/*---------------------------------------------------------------------------
  Copyright 2017-2020 Microsoft Research, Daan Leijen.

  This is free software; you can redistribute it and/or modify it under the
  terms of the Apache License, Version 2.0. A copy of the License can be
  found in the LICENSE file at the root of this distribution.
---------------------------------------------------------------------------*/

/* 64-bit IEEE floating point numbers.

Also described as _double_ precision or _binary64_ numbers in the standards.
See also <https://en.wikipedia.org/wiki/Double-precision_floating-point_format>.

*/
module std/num/float64std/num/float64

import std/text/parsestd/text/parse
import std/num/int32std/num/int32
import std/num/int64std/num/int64

extern import
  c  file "float64-inline"
  js file "float64-inline.js"


//-----------------------------------------
// Constants
//-----------------------------------------

// &pi;
pub val pistd/num/float64/pi: float64          = 0x1.9_21FB_5444_2D18p+1literal: float64
hex64= 0x1.921fb54442d18p1
//3.141592653589793238462643383279502884 // &pi; pub val flt-pistd/num/float64/flt-pi: float64 = pistd/num/float64/pi: float64 // 2&pi; pub val flt-twopistd/num/float64/flt-twopi: float64 = 0x1.9_21FB_5444_2D18p+2literal: float64
hex64= 0x1.921fb54442d18p2
// &pi;/2 pub val flt-pi2std/num/float64/flt-pi2: float64 = 0x1.9_21FB_5444_2D18p+0literal: float64
hex64= 0x1.921fb54442d18p0
// &pi;/4 pub val flt-pi4std/num/float64/flt-pi4: float64 = 0x1.9_21FB_5444_2D18p-1literal: float64
hex64= 0x1.921fb54442d18p-1
// 3&pi;/4 pub val flt-pi34std/num/float64/flt-pi34: float64 =0x1.2_D97C_7F33_21D2p+1literal: float64
hex64= 0x1.2d97c7f3321d2p1
// The [_e_](https://en.wikipedia.org/wiki/E_(mathematical_constant)) constant. pub val flt-estd/num/float64/flt-e: float64 = 0x1.5_BF0A_8B14_5769p+1literal: float64
hex64= 0x1.5bf0a8b145769p1
// 2.718281828459045235360287471352662498 // The natural logarithm of 2 pub val flt-ln2std/num/float64/flt-ln2: float64 = 0x1.6_2E42_FEFA_39EFp-1literal: float64
hex64= 0x1.62e42fefa39efp-1
// 0.693147180559945309417232121458176568 // The natural logarithm of 10 pub val flt-ln10std/num/float64/flt-ln10: float64 = 0x1.2_6BB1_BBB5_5516p+1literal: float64
hex64= 0x1.26bb1bbb55516p1
// 2.302585092994045684017991454684364208 // The base-2 logarithm of _e_. pub val flt-log2estd/num/float64/flt-log2e: float64 = 0x1.7_1547_652B_82FEp+0literal: float64
hex64= 0x1.71547652b82fep0
// 1.442695040888963407359924681001892137 // The base-10 logarithm of _e_. pub val flt-log10estd/num/float64/flt-log10e: float64 = 0x1.B_CB7B_1526_E50Ep-2literal: float64
hex64= 0x1.bcb7b1526e50ep-2
// 0.434294481903251827651128918916605082 // The square-root of 2 pub val flt-sqrt2std/num/float64/flt-sqrt2: float64 = 0x1.6_A09E_667F_3BCDp+0literal: float64
hex64= 0x1.6a09e667f3bcdp0
// 1.414213562373095048801688724209698079 // `1.0 / sqrt(2.0)` (= `sqrt(0.5)`) pub val flt-sqrt12std/num/float64/flt-sqrt12: float64 = 0x1.6_A09E_667F_3BCDp-1literal: float64
hex64= 0x1.6a09e667f3bcdp-1
// 0.707106781186547524400844362104849039 // [Euler's constant](https://en.wikipedia.org/wiki/Euler%E2%80%93Mascheroni_constant) pub val flt-eulerstd/num/float64/flt-euler: float64 = 0x1.2_788C_FC6F_B619p-1literal: float64
hex64= 0x1.2788cfc6fb619p-1
// 0.577215664901532860606512090082402431 // Maximum float64 value pub val flt-maxstd/num/float64/flt-max: float64 = 0x1.F_FFFF_FFFF_FFFFp+1023literal: float64
hex64= 0x1.fffffffffffffp1023
// 1.79769313486231570815e+308 // Smallest positive normalized float64 value pub val flt-minstd/num/float64/flt-min: float64 = 0x1.0p-1022literal: float64
hex64= 0x1p-1022
// 2.22507385850720138309e-308 // Smallest positive subnormal value (i.e. [``DBL_TRUE_MIN``](https://en.cppreference.com/w/cpp/types/climits)) pub val flt-true-minstd/num/float64/flt-true-min: float64= 0x1.0p-1074literal: float64
hex64= 0x1p-1074
// 4.9406564584124654418e-324 // Machine epsilon: the difference between 1.0 and the next representable `:float64` value. pub val flt-epsilonstd/num/float64/flt-epsilon: float64 = 0x1.0p-52literal: float64
hex64= 0x1p-52
// 2.2204460492503130808e-16 // maximal precision in decimal digits of a `:float64`. pub val flt-max-precstd/num/float64/flt-max-prec: int= 15literal: int
dec = 15
hex8 = 0x0F
bit8 = 0b00001111
// Represents a value that is _not a number_ (NaN) pub val nanstd/num/float64/nan: float64 : float64std/core/types/float64: V = make-nanstd/num/float64/make-nan: () -> float64() // Positive infinity pub val posinfstd/num/float64/posinf: float64 : float64std/core/types/float64: V = make-posinfstd/num/float64/make-posinf: () -> float64() // Negative infinity pub val neginfstd/num/float64/neginf: float64 : float64std/core/types/float64: V = make-neginfstd/num/float64/make-neginf: () -> float64() // --------------------------------------- // Basic operations // ---------------------------------------- // Are two floating point number equal? pub inline fip extern (==)std/num/float64/(==): (x : float64, y : float64) -> bool(x : float64std/core/types/float64: V, y : float64std/core/types/float64: V) : boolstd/core/types/bool: V inline "(#1 == #2)" js inline "(#1 === #2)" // Are two floating point number not equal? pub inline fip extern (!=)std/num/float64/(!=): (x : float64, y : float64) -> bool(x : float64std/core/types/float64: V, y : float64std/core/types/float64: V) : boolstd/core/types/bool: V inline "(#1 != #2)" js inline "(#1 !== #2)" // Is the first floating point number smaller or equal to the second? pub inline fip extern (<=)std/num/float64/(<=): (x : float64, y : float64) -> bool( x : float64std/core/types/float64: V, y : float64std/core/types/float64: V) : boolstd/core/types/bool: V inline "(#1 <= #2)" // Is the first floating point number greater or equal to the second? pub inline fip extern (>=)std/num/float64/(>=): (x : float64, y : float64) -> bool( x : float64std/core/types/float64: V, y : float64std/core/types/float64: V) : boolstd/core/types/bool: V inline "(#1 >= #2)" // Is the first floating point number smaller than the second? pub inline fip extern (<)std/num/float64/(<): (x : float64, y : float64) -> bool( x : float64std/core/types/float64: V, y : float64std/core/types/float64: V) : boolstd/core/types/bool: V inline "(#1 < #2)" // Is the first floating point number greater than the second? pub inline fip extern (>)std/num/float64/(>): (x : float64, y : float64) -> bool( x : float64std/core/types/float64: V, y : float64std/core/types/float64: V) : boolstd/core/types/bool: V inline "(#1 > #2)" // Add two floating point numbers. pub inline fip extern (+)std/num/float64/(+): (x : float64, y : float64) -> float64( x : float64std/core/types/float64: V, y : float64std/core/types/float64: V) : float64std/core/types/float64: V inline "(#1 + #2)" // Subtract two floating point numbers. pub inline fip extern (-)std/num/float64/(-): (x : float64, y : float64) -> float64( x : float64std/core/types/float64: V, y : float64std/core/types/float64: V) : float64std/core/types/float64: V inline "(#1 - #2)" // Multiply two floating point numbers. pub inline fip extern (*)std/num/float64/(*): (x : float64, y : float64) -> float64( x : float64std/core/types/float64: V, y : float64std/core/types/float64: V) : float64std/core/types/float64: V inline "(#1 * #2)" // Divide two floating point numbers. pub inline fip extern (/)std/num/float64/(/): (x : float64, y : float64) -> float64( x : float64std/core/types/float64: V, y : float64std/core/types/float64: V) : float64std/core/types/float64: V inline "(#1 / #2)" // Modulus of two floating point numbers. pub inline fip extern (%)std/num/float64/(%): (x : float64, y : float64) -> float64( x : float64std/core/types/float64: V, y : float64std/core/types/float64: V) : float64std/core/types/float64: V c inline "fmod(#1,#2)" inline "(#1 % #2)" // Is the value negative? pub fip fun is-negstd/num/float64/is-neg: (d : float64) -> bool( dd: float64 : float64std/core/types/float64: V )result: -> total bool : boolstd/core/types/bool: V dd: float64 <std/num/float64/(<): (x : float64, y : float64) -> bool 0.0literal: float64
hex64= 0x0p+0
// Is the value positive? pub fip fun is-posstd/num/float64/is-pos: (d : float64) -> bool( dd: float64 : float64std/core/types/float64: V )result: -> total bool : boolstd/core/types/bool: V dd: float64 >std/num/float64/(>): (x : float64, y : float64) -> bool 0.0literal: float64
hex64= 0x0p+0
// Is the value zero? pub fip fun is-zerostd/num/float64/is-zero: (d : float64) -> bool( dd: float64 : float64std/core/types/float64: V )result: -> total bool : boolstd/core/types/bool: V dd: float64 ==std/num/float64/(==): (x : float64, y : float64) -> bool 0.0literal: float64
hex64= 0x0p+0
// Compare the argument to zero. pub fip fun signstd/num/float64/sign: (d : float64) -> order( dd: float64 : float64std/core/types/float64: V )result: -> total order : orderstd/core/types/order: V if dd: float64 <std/num/float64/(<): (x : float64, y : float64) -> bool 0.0literal: float64
hex64= 0x0p+0
then Ltstd/core/types/Lt: order elif dd: float64 >std/num/float64/(>): (x : float64, y : float64) -> bool 0.0literal: float64
hex64= 0x0p+0
then Gtstd/core/types/Gt: order else Eqstd/core/types/Eq: order
// Negate a `:float64`. pub inline fip extern (~)std/num/float64/(~): (f : float64) -> float64( f : float64std/core/types/float64: V ) : float64std/core/types/float64: V inline "(-#1)" // inline so `~0.0` becomes negative zero // convert a `:float64` to an `:int` using `round` to round to its nearest integer. // (rounding to an even number on a tie) // Returns `0` if the argument is not `finite?`. pub inline extern intstd/num/float64/int: (f : float64) -> int( f : float64std/core/types/float64: V ) : intstd/core/types/int: V c "kk_integer_from_double" cs "Primitive.IntDouble" js "$std_core_types._int_double" // Returns the value `f` raised to the power `p` . pub inline fip extern (^)std/num/float64/(^): (f : float64, p : float64) -> float64( f : float64std/core/types/float64: V, p : float64std/core/types/float64: V) : float64std/core/types/float64: V c inline "pow(#1,#2)" cs "Math.Pow" js "Math.pow" // Return the absolute value of a `:float64` `f` pub inline fip extern absstd/num/float64/abs: (f : float64) -> float64( f : float64std/core/types/float64: V ) : float64std/core/types/float64: V c inline "kk_double_abs(#1)" cs "Math.Abs" js "Math.abs" // Convert an integer to a `:float64`. May return `nan` if the integer is too large to represent as a `:float64`. pub inline fip extern float64std/num/float64/float64: (i : int) -> float64( i : intstd/core/types/int: V) : float64std/core/types/float64: V c "kk_integer_as_double" cs "Primitive.IntToDouble" js "$std_core_types._int_to_double" // Convert an integer to a `:float32`. May return `nan` if the integer is too large to represent as a `:float32`. pub inline fip extern float32std/num/float64/float32: (i : int) -> float32( i : intstd/core/types/int: V) : float32std/core/types/float32: V c "kk_integer_as_float" cs "Primitive.IntToFloat" js "$std_core_types._int_to_float" // Convert an 64-bit integer to a `:float64`. pub fip fun int64/float64std/num/float64/int64/float64: (i : int64) -> float64( ii: int64 : int64std/core/types/int64: V )result: -> total float64 : float64std/core/types/float64: V ii: int64.intstd/num/int64/int: (i : int64) -> int.float64std/num/float64/float64: (i : int) -> float64 // Returns the smallest of two floats pub fip fun minstd/num/float64/min: (x : float64, y : float64) -> float64( xx: float64 : float64std/core/types/float64: V, yy: float64 : float64std/core/types/float64: V )result: -> total float64 : float64std/core/types/float64: V if xx: float64 <=std/num/float64/(<=): (x : float64, y : float64) -> bool yy: float64 then xx: float64 else yy: float64 // Returns the largest of two floats pub fip fun maxstd/num/float64/max: (x : float64, y : float64) -> float64( xx: float64 : float64std/core/types/float64: V, yy: float64 : float64std/core/types/float64: V )result: -> total float64 : float64std/core/types/float64: V if xx: float64 >=std/num/float64/(>=): (x : float64, y : float64) -> bool yy: float64 then xx: float64 else yy: float64 // Show a `:float64` as a string. // If `d >= 1.0e-5` and `d < 1.0e+21`, `show-fixed` is used and otherwise `show-exp`. // Default `precision` is `-17`. pub fun showstd/num/float64/show: (d : float64, precision : ? int) -> string( dd: float64 : float64std/core/types/float64: V, precisionprecision: ? int : intstd/core/types/int: V = -17literal: int
dec = -17
hex8 = 0xEF
bit8 = 0b11101111
)result: -> total string : stringstd/core/types/string: V val dabsdabs: float64 = dd: float64.absstd/num/float64/abs: (f : float64) -> float64 if dabsdabs: float64 >=std/num/float64/(>=): (x : float64, y : float64) -> bool 1.0e-5literal: float64
hex64= 0x1.4f8b588e368f1p-17
&&std/core/types/(&&): (x : bool, y : bool) -> bool dabsdabs: float64 <std/num/float64/(<): (x : float64, y : float64) -> bool 1.0e+21literal: float64
hex64= 0x1.b1ae4d6e2ef5p69
then show-fixedstd/num/float64/show-fixed: (d : float64, precision : ? int) -> string(dd: float64,precisionprecision: int) else show-expstd/num/float64/show-exp: (d : float64, precision : ? int) -> string(dd: float64,precisionprecision: int
) // Show a `:float64` fixed-point notation. // The optional `precision` (= `-2`) specifies the maximum precision. // If `>=0` it specifies the number of digits behind the dot (up to `20` max). // If negative, then at most the absolute value of `precision` digits behind the dot are used. // This may still show a number in exponential notation if the it is too small or large, // in particular, for a `d` where `d > 1.0e21` or `d < 1.0e-15`, or if // `precision.abs > 17`, the `show-exp` routine is used. pub fun show-fixedstd/num/float64/show-fixed: (d : float64, precision : ? int) -> string( dd: float64 : float64std/core/types/float64: V, precisionprecision: ? int : intstd/core/types/int: V = -2literal: int
dec = -2
hex8 = 0xFE
bit8 = 0b11111110
)result: -> total string : stringstd/core/types/string: V val dabsdabs: float64 = dd: float64.absstd/num/float64/abs: (f : float64) -> float64 if dabsdabs: float64 <std/num/float64/(<): (x : float64, y : float64) -> bool 1.0e-15literal: float64
hex64= 0x1.203af9ee75616p-50
||std/core/types/(||): (x : bool, y : bool) -> bool dabsdabs: float64 >std/num/float64/(>): (x : float64, y : float64) -> bool 1.0e+21literal: float64
hex64= 0x1.b1ae4d6e2ef5p69
then show-expstd/num/float64/show-exp: (d : float64, precision : ? int) -> string(dd: float64,precisionprecision: int) else show-fixedxstd/num/float64/show-fixedx: (d : float64, prec : int32) -> string(dd: float64, precisionprecision: int.int32std/num/int32/int32: (i : int) -> int32
) extern show-fixedxstd/num/float64/show-fixedx: (d : float64, prec : int32) -> string( dd: float64 : float64std/core/types/float64: V, precprec: int32 : int32std/core/types/int32: V ) : stringstd/core/types/string: V c "kk_double_show_fixed" cs "Primitive.DoubleShowFixed" js "_double_show_fixed" // Show a `:float64` in exponential (scientific) notation. // The optional `precision` (= `-17`) specifies the precision. // If `>=0` it specifies the number of digits behind the dot (up to `17` max). // If negative, then at most the absolute value of `precision` digits behind the dot are used. pub fun show-expstd/num/float64/show-exp: (d : float64, precision : ? int) -> string( dd: float64 : float64std/core/types/float64: V, precisionprecision: ? int : intstd/core/types/int: V = -17literal: int
dec = -17
hex8 = 0xEF
bit8 = 0b11101111
)result: -> total string show-expxstd/num/float64/show-expx: (d : float64, prec : int32) -> string(dd: float64,precisionprecision: int.int32std/num/int32/int32: (i : int) -> int32
) extern show-expxstd/num/float64/show-expx: (d : float64, prec : int32) -> string( dd: float64 : float64std/core/types/float64: V, precprec: int32 : int32std/core/types/int32: V ) : stringstd/core/types/string: V c "kk_double_show_exp" cs "Primitive.DoubleShowExp" js "_double_show_exp" // Returns the smallest element of a list of floats (or `0` for the empty list) pub fun minimumstd/num/float64/minimum: (xs : list<float64>) -> float64( xsxs: list<float64> : liststd/core/types/list: V -> V<float64std/core/types/float64: V> )result: -> total float64 : float64std/core/types/float64: V match xsxs: list<float64> Nilstd/core/types/Nil: forall<a> list<a> -> 0.0literal: float64
hex64= 0x0p+0
Consstd/core/types/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: float64,xxxx: list<float64>) -> xxxx: list<float64>.foldlstd/core/list/foldl: (xs : list<float64>, z : float64, f : (float64, float64) -> float64) -> float64( xx: float64, minstd/num/float64/min: (x : float64, y : float64) -> float64
) // Returns the largest element of a list of floats (or `0` for the empty list) pub fun maximumstd/num/float64/maximum: (xs : list<float64>) -> float64( xsxs: list<float64> : liststd/core/types/list: V -> V<float64std/core/types/float64: V> )result: -> total float64 : float64std/core/types/float64: V match xsxs: list<float64> Nilstd/core/types/Nil: forall<a> list<a> -> 0.0literal: float64
hex64= 0x0p+0
Consstd/core/types/Cons: forall<a> (head : a, tail : list<a>) -> list<a>(xx: float64,xxxx: list<float64>) -> xxxx: list<float64>.foldlstd/core/list/foldl: (xs : list<float64>, z : float64, f : (float64, float64) -> float64) -> float64( xx: float64, maxstd/num/float64/max: (x : float64, y : float64) -> float64
) //----------------------------------------- // NaN, Infinity //----------------------------------------- extern make-nanstd/num/float64/make-nan: () -> float64() : float64std/core/types/float64: V c inline "(double)NAN" cs inline "double.NaN" js inline "NaN" extern make-posinfstd/num/float64/make-posinf: () -> float64() : float64std/core/types/float64: V c inline "HUGE_VAL" cs inline "double.PositiveInfinity" js inline "Infinity" extern make-neginfstd/num/float64/make-neginf: () -> float64() : float64std/core/types/float64: V c inline "-HUGE_VAL" cs inline "double.NegativeInfinity" js inline "-Infinity" // Is this value equal to NaN ? pub inline extern is-nanstd/num/float64/is-nan: (d : float64) -> bool( d : float64std/core/types/float64: V ) : boolstd/core/types/bool: V c inline "isnan(#1)" cs "double.IsNaN" js "isNaN" // Is this value equal to negative or positive infinity ? pub extern is-infstd/num/float64/is-inf: (d : float64) -> bool( dd: float64 : float64std/core/types/float64: V ) : boolstd/core/types/bool: V c inline "isinf(#1)" cs "double.IsInfinity" js inline "((#1) === Infinity || (#1) === -Infinity)" // Is this value equal to positive infinity ? pub inline extern is-posinfstd/num/float64/is-posinf: (d : float64) -> bool( d : float64std/core/types/float64: V ) : boolstd/core/types/bool: V c inline "(isinf(#1) && !signbit(#1))" cs "double.IsPositiveInfinity" js inline "((#1) === Infinity)" // Is this value equal to negative infinity ? pub inline extern is-neginfstd/num/float64/is-neginf: (d : float64) -> bool( d : float64std/core/types/float64: V ) : boolstd/core/types/bool: V c inline "(isinf(#1) && signbit(#1))" cs "double.IsNegativeInfinity" js inline "((#1) === -Infinity)" // Is this a finite number (i.e. not `nan` or infinity) pub inline extern is-finitestd/num/float64/is-finite: (d : float64) -> bool( d : float64std/core/types/float64: V ) : boolstd/core/types/bool: V c inline "isfinite(#1)" cs inline "(!double.IsNaN(#1) && !double.IsInfinity(#1))" js "isFinite" // Is this a negative zero value? pub fun is-negzerostd/num/float64/is-negzero: (d : float64) -> bool( dd: float64 : float64std/core/types/float64: V )result: -> total bool : boolstd/core/types/bool: V (dd: float64==std/num/float64/(==): (x : float64, y : float64) -> bool0.0literal: float64
hex64= 0x0p+0
&&std/core/types/(&&): (x : bool, y : bool) -> bool is-neginfstd/num/float64/is-neginf: (d : float64) -> bool(1.0literal: float64
hex64= 0x1p0
/std/num/float64/(/): (x : float64, y : float64) -> float64 dd: float64)
) // Is this a [subnormal](https://en.wikipedia.org/wiki/Denormal_number) value? // (i.e. `0 < d.abs < flt-min`) pub fun is-subnormalstd/num/float64/is-subnormal: (d : float64) -> bool( dd: float64 :float64std/core/types/float64: V )result: -> total bool : boolstd/core/types/bool: V (dd: float64 !=std/num/float64/(!=): (x : float64, y : float64) -> bool 0.0literal: float64
hex64= 0x0p+0
&&std/core/types/(&&): (x : bool, y : bool) -> bool dd: float64.absstd/num/float64/abs: (f : float64) -> float64 <std/num/float64/(<): (x : float64, y : float64) -> bool flt-minstd/num/float64/flt-min: float64
) //----------------------------------------- // Rounding //----------------------------------------- // Round a float64 to its nearest integral value. // If the value is halfway between two integers, the value is rounded towards the even one. pub inline extern roundstd/num/float64/round: (d : float64) -> float64( d : float64std/core/types/float64: V ) : float64std/core/types/float64: V c "kk_double_round_even" cs inline "Math.Round(#1,MidpointRounding.ToEven)" js "$std_core_types._double_round_even" // Return the largest integer equal or less than `d` pub inline extern floorstd/num/float64/floor: (d : float64) -> float64( d : float64std/core/types/float64: V ) : float64std/core/types/float64: V c "floor" cs "Math.Floor" js "Math.floor" // Return the smallest integer equal or larger than `d` pub inline extern ceilingstd/num/float64/ceiling: (d : float64) -> float64( d : float64std/core/types/float64: V ) : float64std/core/types/float64: V c "ceil" cs "Math.Ceiling" js "Math.ceil" // fused multiply-add. Computes `(x*y)+z` as if to infinite precision // with only the final result rounded back to a `:float64`. pub extern fmaddstd/num/float64/fmadd: (x : float64, y : float64, z : float64) -> float64( xx: float64 : float64std/core/types/float64: V, yy: float64 : float64std/core/types/float64: V, zz: float64 : float64std/core/types/float64: V ) : float64std/core/types/float64: V c "fma" js "_fmadd" cs "Math.FusedMultiplyAdd" // Return the integral part of a `:float64` `d` . // If `d >= 0.0` , return the largest integer equal or less to `d` , // If `d < 0.0` , return the smallest integer equal or larger to `d` . pub fun truncatestd/num/float64/truncate: (d : float64) -> float64(dd: float64 : float64std/core/types/float64: V)result: -> total float64 : float64std/core/types/float64: V if dd: float64 >=std/num/float64/(>=): (x : float64, y : float64) -> bool 0.0literal: float64
hex64= 0x0p+0
then floorstd/num/float64/floor: (d : float64) -> float64(dd: float64) else ceilingstd/num/float64/ceiling: (d : float64) -> float64(dd: float64
) // Return the fractional part of a `:float64` `d`.\ // `d.truncate + d.fraction === d`\ // `(-2.4).fraction === -0.4` pub fun fractionstd/num/float64/fraction: (d : float64) -> float64(dd: float64 : float64std/core/types/float64: V)result: -> total float64 : float64std/core/types/float64: V dd: float64 -std/num/float64/(-): (x : float64, y : float64) -> float64 dd: float64.truncatestd/num/float64/truncate: (d : float64) -> float64 // Return the 'floored' fraction of `d`, always greater or equal to zero.\ // `d.floor + d.ffraction === d`\ // `(-2.4).ffraction === 0.6` pub fun ffractionstd/num/float64/ffraction: (d : float64) -> float64(dd: float64 : float64std/core/types/float64: V)result: -> total float64 : float64std/core/types/float64: V dd: float64 -std/num/float64/(-): (x : float64, y : float64) -> float64 dd: float64.floorstd/num/float64/floor: (d : float64) -> float64 // Round a float64 to a specified precision. Rounds to the even number in case of a tie.\ // `123.456.round-to-prec(2) == 123.46`\ // `123.456.round-to-prec(-1) == 120.0`\ pub fun round-to-precstd/num/float64/round-to-prec: (d : float64, prec : int) -> float64( dd: float64 : float64std/core/types/float64: V, precprec: int : intstd/core/types/int: V )result: -> total float64 : float64std/core/types/float64: V if precprec: int <=std/core/int/(<=): (x : int, y : int) -> bool 0literal: int
dec = 0
hex8 = 0x00
bit8 = 0b00000000
then dd: float64.roundstd/num/float64/round: (d : float64) -> float64 else val pp: float64 = exp10std/num/float64/exp10: (p : float64) -> float64(precprec: int.float64std/num/float64/float64: (i : int) -> float64) (dd: float64 *std/num/float64/(*): (x : float64, y : float64) -> float64 pp: float64).roundstd/num/float64/round: (d : float64) -> float64 /std/num/float64/(/): (x : float64, y : float64) -> float64
pp: float64 // Round a `:float64` to a `:float32` pub extern float64/float32std/num/float64/float64/float32: (f : float64) -> float32( ff: float64 : float64std/core/types/float64: V ) : float32std/core/types/float32: V c inline "(float)(#1)" js "$std_core_types._double_to_float" // Extend a `:float32` to a `:float64` pub extern float32/float64std/num/float64/float32/float64: (f : float32) -> float64( ff: float32 : float32std/core/types/float32: V ) : float64std/core/types/float64: V c inline "(double)(#1)" js inline "(#1)" // Short version of `float32` for convenience, e.g. `1.337.f32`. For example: // ``` // > 1.337.show-hex ++ " != " ++ 1.337.f32.float64.show-hex // "0x1.5645A1CAC0831p+0 != 0x1.5645A2p+0" // ``` // . pub fun f32std/num/float64/f32: (f : float64) -> float32( ff: float64 : float64std/core/types/float64: V )result: -> total float32 : float32std/core/types/float32: V ff: float64.float32std/num/float64/float64/float32: (f : float64) -> float32 //----------------------------------------- // Powers //----------------------------------------- // Return the square root of a value `d` // Returns `nan` if `d == nan` or if `d` is negative. // Returns `inf` if `d == inf` . pub inline extern sqrtstd/num/float64/sqrt: (d : float64) -> float64( d : float64std/core/types/float64: V ) : float64std/core/types/float64: V c "sqrt" cs "Math.Sqrt" js "Math.sqrt" // Return the cubic root of a value `d` // Returns `nan` if `d == nan` or if `d` is negative. // Returns `inf` if `d == inf` . pub inline extern cbrtstd/num/float64/cbrt: (d : float64) -> float64( d : float64std/core/types/float64: V ) : float64std/core/types/float64: V c "cbrt" cs "Math.Cbrt" js "Math.cbrt" // Return the `d` raised to the power of `p`. pub inline extern powstd/num/float64/pow: (d : float64, p : float64) -> float64( d : float64std/core/types/float64: V, p : float64std/core/types/float64: V) : float64std/core/types/float64: V c "pow" cs "Math.Pow" js "Math.pow" // Return the natural logarithm (in base _e_) of a `:float64` `f` pub inline extern lnstd/num/float64/ln: (f : float64) -> float64( f : float64std/core/types/float64: V ) : float64std/core/types/float64: V c "log" cs "Math.Log" js "Math.log" // Return the logarithm in base 10 of a `:float64` `f`. pub inline extern log10std/num/float64/log10: (f : float64) -> float64( f : float64std/core/types/float64: V ) : float64std/core/types/float64: V c "log10" cs "Math.Log10" js "Math.log10" // Return the logarithm in base 2 of a `:float64` `f`. pub inline extern log2std/num/float64/log2: (f : float64) -> float64( f : float64std/core/types/float64: V ) : float64std/core/types/float64: V c "log2" cs "Math.Log2" js "Math.log2" // Return the logarithm in base `base` of a `:float64` `f` pub fun logstd/num/float64/log: (f : float64, base : float64) -> float64( ff: float64 : float64std/core/types/float64: V, basebase: float64 : float64std/core/types/float64: V )result: -> total float64 : float64std/core/types/float64: V lnstd/num/float64/ln: (f : float64) -> float64(ff: float64) /std/num/float64/(/): (x : float64, y : float64) -> float64 lnstd/num/float64/ln: (f : float64) -> float64(basebase: float64) // Return _e_ to the power of `p`. pub inline extern expstd/num/float64/exp: (p : float64) -> float64( p : float64std/core/types/float64: V ) : float64std/core/types/float64: V c "exp" cs "Math.Exp" js "Math.exp" // Return the 10 to the power of `p`. pub inline extern exp10std/num/float64/exp10: (p : float64) -> float64( p : float64std/core/types/float64: V ) : float64std/core/types/float64: V c inline "pow(10.0,#1)" cs inline "Math.Pow(10.0,#1)" js inline "Math.pow(10.0,#1)" // Return the 2 to the power of `p`. pub inline extern exp2std/num/float64/exp2: (p : float64) -> float64( p : float64std/core/types/float64: V ) : float64std/core/types/float64: V c "exp2" cs inline "Math.Pow(2.0,#1)" js inline "Math.pow(2.0,#1)" fun log2p1std/num/float64/log2p1: (x : float64) -> float64( xx: float64 : float64std/core/types/float64: V )result: -> total float64 : float64std/core/types/float64: V flt-log2estd/num/float64/flt-log2e: float64 *std/num/float64/(*): (x : float64, y : float64) -> float64 ln1pstd/num/float64/ln1p: (d : float64) -> float64(xx: float64) fun exp2m1std/num/float64/exp2m1: (x : float64) -> float64( xx: float64 : float64std/core/types/float64: V )result: -> total float64 : float64std/core/types/float64: V expm1std/num/float64/expm1: (d : float64) -> float64(flt-ln2std/num/float64/flt-ln2: float64 *std/num/float64/(*): (x : float64, y : float64) -> float64 xx: float64) // Returns `ln(exp(x) + exp(y))`. // Avoids overlow/underflow errors. pub fun lnaddexpstd/num/float64/lnaddexp: (x : float64, y : float64) -> float64( xx: float64 : float64std/core/types/float64: V, yy: float64 : float64std/core/types/float64: V )result: -> total float64 : float64std/core/types/float64: V if xx: float64==std/num/float64/(==): (x : float64, y : float64) -> boolyy: float64 then xx: float64 +std/num/float64/(+): (x : float64, y : float64) -> float64 flt-ln2std/num/float64/flt-ln2: float64 else val zz: float64 = xx: float64 -std/num/float64/(-): (x : float64, y : float64) -> float64 yy: float64 if zz: float64 >std/num/float64/(>): (x : float64, y : float64) -> bool 0.0literal: float64
hex64= 0x0p+0
then xx: float64 +std/num/float64/(+): (x : float64, y : float64) -> float64 ln1pstd/num/float64/ln1p: (d : float64) -> float64(expstd/num/float64/exp: (p : float64) -> float64(~std/num/float64/(~): (f : float64) -> float64zz: float64)) else yy: float64 +std/num/float64/(+): (x : float64, y : float64) -> float64 ln1pstd/num/float64/ln1p: (d : float64) -> float64(expstd/num/float64/exp: (p : float64) -> float64(zz: float64)
) // Returns `log2( exp2(x) + exp2(y) )`. // Avoids overlow/underflow errors. pub fun logaddexp2std/num/float64/logaddexp2: (x : float64, y : float64) -> float64( xx: float64 : float64std/core/types/float64: V, yy: float64 : float64std/core/types/float64: V )result: -> total float64 : float64std/core/types/float64: V if xx: float64==std/num/float64/(==): (x : float64, y : float64) -> boolyy: float64 then xx: float64 +std/num/float64/(+): (x : float64, y : float64) -> float64 1.0literal: float64
hex64= 0x1p0
else val zz: float64 = xx: float64 -std/num/float64/(-): (x : float64, y : float64) -> float64 yy: float64 if zz: float64 >std/num/float64/(>): (x : float64, y : float64) -> bool 0.0literal: float64
hex64= 0x0p+0
then xx: float64 +std/num/float64/(+): (x : float64, y : float64) -> float64 log2p1std/num/float64/log2p1: (x : float64) -> float64(exp2std/num/float64/exp2: (p : float64) -> float64(~std/num/float64/(~): (f : float64) -> float64zz: float64)) else yy: float64 +std/num/float64/(+): (x : float64, y : float64) -> float64 log2p1std/num/float64/log2p1: (x : float64) -> float64(exp2std/num/float64/exp2: (p : float64) -> float64(zz: float64)
) // Return if two floats are nearly equal with respect to some `epsilon` (=`8*flt-epsilon`). // The epsilon is the nearest difference for numbers around 1.0. The routine automatically // scales the epsilon for larger and smaller numbers, and for subnormal numbers. pub fun nearly-eqstd/num/float64/nearly-eq: (x : float64, y : float64, epsilon : ? float64) -> bool( xx: float64 : float64std/core/types/float64: V, yy: float64 : float64std/core/types/float64: V, epsilonepsilon: ? float64 : float64std/core/types/float64: V = 8.0literal: float64
hex64= 0x1p3
*std/num/float64/(*): (x : float64, y : float64) -> float64flt-epsilonstd/num/float64/flt-epsilon: float64 )result: -> total bool : boolstd/core/types/bool: V if xx: float64 ==std/num/float64/(==): (x : float64, y : float64) -> bool yy: float64 returnreturn: bool Truestd/core/types/True: bool val diffdiff: float64 = (xx: float64 -std/num/float64/(-): (x : float64, y : float64) -> float64 yy: float64).absstd/num/float64/abs: (f : float64) -> float64 if xx: float64==std/num/float64/(==): (x : float64, y : float64) -> bool0.0literal: float64
hex64= 0x0p+0
||std/core/types/(||): (x : bool, y : bool) -> bool yy: float64==std/num/float64/(==): (x : float64, y : float64) -> bool0.0literal: float64
hex64= 0x0p+0
||std/core/types/(||): (x : bool, y : bool) -> bool diffdiff: float64 <std/num/float64/(<): (x : float64, y : float64) -> bool flt-minstd/num/float64/flt-min: float64 then // very close to zero, scale the epsilon for denormalized numbers (2.0literal: float64
hex64= 0x1p1
*std/num/float64/(*): (x : float64, y : float64) -> float64diffdiff: float64 <std/num/float64/(<): (x : float64, y : float64) -> bool (epsilonepsilon: float64 *std/num/float64/(*): (x : float64, y : float64) -> float64 flt-minstd/num/float64/flt-min: float64)) else val sumsum: float64 = xx: float64.absstd/num/float64/abs: (f : float64) -> float64 +std/num/float64/(+): (x : float64, y : float64) -> float64 yy: float64.absstd/num/float64/abs: (f : float64) -> float64 ((2.0literal: float64
hex64= 0x1p1
*std/num/float64/(*): (x : float64, y : float64) -> float64diffdiff: float64 /std/num/float64/(/): (x : float64, y : float64) -> float64 (if sumsum: float64 >std/num/float64/(>): (x : float64, y : float64) -> bool flt-maxstd/num/float64/flt-max: float64 then flt-maxstd/num/float64/flt-max: float64 else sumsum: float64)) <std/num/float64/(<): (x : float64, y : float64) -> bool epsilonepsilon: float64
) // Return if two floats are nearly equal with respect to an `epsilon` of `8*flt-epsilon`. // See also `nearly-eq` which takes an explicit `epsilon`. pub fun (~=)std/num/float64/(~=): (x : float64, y : float64) -> bool(xx: float64 : float64std/core/types/float64: V, yy: float64 : float64std/core/types/float64: V )result: -> total bool : boolstd/core/types/bool: V nearly-eqstd/num/float64/nearly-eq: (x : float64, y : float64, epsilon : ? float64) -> bool(xx: float64,yy: float64) //----------------------------------------- // Ldexp/Frexp //----------------------------------------- // Low-level: return the bits of a 64-bit `:float64` as in `:int64` pub extern float64-to-bitsstd/num/float64/float64-to-bits: (d : float64) -> int64( dd: float64 : float64std/core/types/float64: V ) : int64std/core/types/int64: V c "kk_double_to_bits" cs "Primitive.DoubleToBits" js "_double_to_bits" // Low-level: create a `:float64` from the given 64-bit integer. pub extern float64-from-bitsstd/num/float64/float64-from-bits: (i : int64) -> float64( ii: int64 : int64std/core/types/int64: V ) : float64std/core/types/float64: V c "kk_double_from_bits" cs "Primitive.DoubleFromBits" js "_double_from_bits" // Calculate 2&middot;^`e`^ for an integer `e`. // Uses efficient bit conversion for exponents between -1022 and 1023 and // otherwise falls back to the regular `exp2` function converting `e` to a float64. pub fun exp2istd/num/float64/exp2i: (e : int) -> float64( ee: int : intstd/core/types/int: V )result: -> total float64 : float64std/core/types/float64: V if ee: int >=std/core/int/(>=): (x : int, y : int) -> bool -1022literal: int
dec = -1022
hex16= 0xFC02
bit16= 0b1111110000000010
&&std/core/types/(&&): (x : bool, y : bool) -> bool ee: int <=std/core/int/(<=): (x : int, y : int) -> bool 1023literal: int
dec = 1023
hex16= 0x03FF
bit16= 0b0000001111111111
then float64-from-bitsstd/num/float64/float64-from-bits: (i : int64) -> float64( (1023literal: int
dec = 1023
hex16= 0x03FF
bit16= 0b0000001111111111
+std/core/int/(+): (x : int, y : int) -> int ee: int).int64std/num/int64/int64: (i : int) -> int64.shlstd/num/int64/shl: (i : int64, shift : int) -> int64(52literal: int
dec = 52
hex8 = 0x34
bit8 = 0b00110100
) ) else exp2std/num/float64/exp2: (p : float64) -> float64( ee: int.float64std/num/float64/float64: (i : int) -> float64
) // Create a float64 `d` given a mantissa `man` and exponent `exp` // such that `man`&middot;2^`exp`^ = `d` exactly (if it is representable // by a `:float64`). See also `ldexp`. pub fun encodestd/num/float64/encode: (man : int, exp : int) -> float64( manman: int : intstd/core/types/int: V, expexp: int : intstd/core/types/int: V )result: -> total float64 : float64std/core/types/float64: V ldexpstd/num/float64/ldexp: (x : float64, e : int) -> float64(manman: int.float64std/num/float64/float64: (i : int) -> float64,expexp: int) val one-p1023std/num/float64/one-p1023: float64 = 0x1.0p1023literal: float64
hex64= 0x1p1023
val one-m1022std/num/float64/one-m1022: float64 = 0x1.0p-1022literal: float64
hex64= 0x1p-1022
// = flt-min fun mul-exp2std/num/float64/mul-exp2: (x : float64, e : int) -> float64( xx: float64 : float64std/core/types/float64: V, ee: int : intstd/core/types/int: V )result: -> total float64 : float64std/core/types/float64: V xx: float64 *std/num/float64/(*): (x : float64, y : float64) -> float64 exp2istd/num/float64/exp2i: (e : int) -> float64(ee: int) // 'Load exponent': returns `x`&middot;2^`e`^ for a `is-finite` `x` and // otherwise `x` itself. See also `encode` which loads an integer mantissa. pub fun ldexpstd/num/float64/ldexp: (x : float64, e : int) -> float64( xx: float64 : float64std/core/types/float64: V, ee: int : intstd/core/types/int: V )result: -> total float64 : float64std/core/types/float64: V if !std/core/types/bool/(!): (b : bool) -> boolis-finitestd/num/float64/is-finite: (d : float64) -> bool(xx: float64) then xx: float64 elif ee: int >=std/core/int/(>=): (x : int, y : int) -> bool -1022literal: int
dec = -1022
hex16= 0xFC02
bit16= 0b1111110000000010
then if ee: int <=std/core/int/(<=): (x : int, y : int) -> bool 1023literal: int
dec = 1023
hex16= 0x03FF
bit16= 0b0000001111111111
then mul-exp2std/num/float64/mul-exp2: (x : float64, e : int) -> float64(xx: float64,ee: int) // usually this branch elif ee: int <=std/core/int/(<=): (x : int, y : int) -> bool 2046literal: int
dec = 2046
hex16= 0x07FE
bit16= 0b0000011111111110
then mul-exp2std/num/float64/mul-exp2: (x : float64, e : int) -> float64( xx: float64*std/num/float64/(*): (x : float64, y : float64) -> float64one-p1023std/num/float64/one-p1023: float64, ee: int -std/core/int/(-): (x : int, y : int) -> int 1023literal: int
dec = 1023
hex16= 0x03FF
bit16= 0b0000001111111111
) elif ee: int <=std/core/int/(<=): (x : int, y : int) -> bool 3069literal: int
dec = 3069
hex16= 0x0BFD
bit16= 0b0000101111111101
then mul-exp2std/num/float64/mul-exp2: (x : float64, e : int) -> float64( xx: float64*std/num/float64/(*): (x : float64, y : float64) -> float64one-p1023std/num/float64/one-p1023: float64*std/num/float64/(*): (x : float64, y : float64) -> float64one-p1023std/num/float64/one-p1023: float64, ee: int -std/core/int/(-): (x : int, y : int) -> int 2046literal: int
dec = 2046
hex16= 0x07FE
bit16= 0b0000011111111110
) elif xx: float64 <std/num/float64/(<): (x : float64, y : float64) -> bool 0.0literal: float64
hex64= 0x0p+0
then neginfstd/num/float64/neginf: float64 else posinfstd/num/float64/posinf: float64 else if ee: int >=std/core/int/(>=): (x : int, y : int) -> bool -2044literal: int
dec = -2044
hex16= 0xF804
bit16= 0b1111100000000100
then mul-exp2std/num/float64/mul-exp2: (x : float64, e : int) -> float64(xx: float64*std/num/float64/(*): (x : float64, y : float64) -> float64one-m1022std/num/float64/one-m1022: float64, ee: int +std/core/int/(+): (x : int, y : int) -> int 1022literal: int
dec = 1022
hex16= 0x03FE
bit16= 0b0000001111111110
) elif ee: int >=std/core/int/(>=): (x : int, y : int) -> bool -3066literal: int
dec = -3066
hex16= 0xF406
bit16= 0b1111010000000110
then mul-exp2std/num/float64/mul-exp2: (x : float64, e : int) -> float64(xx: float64*std/num/float64/(*): (x : float64, y : float64) -> float64one-m1022std/num/float64/one-m1022: float64*std/num/float64/(*): (x : float64, y : float64) -> float64one-m1022std/num/float64/one-m1022: float64, ee: int +std/core/int/(+): (x : int, y : int) -> int 2044literal: int
dec = 2044
hex16= 0x07FC
bit16= 0b0000011111111100
) elif xx: float64 <std/num/float64/(<): (x : float64, y : float64) -> bool 0.0literal: float64
hex64= 0x0p+0
then -0.0literal: float64
hex64= -0x0p+0
else 0.0literal: float64
hex64= 0x0p+0
// Decode a float64 `d` into a tuple `(m,e)` of a mantissa `m` and exponent `e` // such that `m`&middot;2^`e`^ = `d` exactly. The mantissa `m` is // always either 0 or in the range [2^52^, 2^53^). See also `frexp`. pub fun decodestd/num/float64/decode: (d : float64) -> (int, int)( dd: float64 : float64std/core/types/float64: V )result: -> total (int, int) : (std/core/types/tuple2: (V, V) -> Vintstd/core/types/int: V,intstd/core/types/int: V) if dd: float64==std/num/float64/(==): (x : float64, y : float64) -> bool0.0literal: float64
hex64= 0x0p+0
then (std/core/types/Tuple2: forall<a,b> (fst : a, snd : b) -> (a, b)0literal: int
dec = 0
hex8 = 0x00
bit8 = 0b00000000
,0literal: int
dec = 0
hex8 = 0x00
bit8 = 0b00000000
)std/core/types/Tuple2: forall<a,b> (fst : a, snd : b) -> (a, b) elif dd: float64.is-subnormalstd/num/float64/is-subnormal: (d : float64) -> bool then decode-normalizedstd/num/float64/decode-normalized: (d : float64, e-adjust : ? int) -> (int, int)(dd: float64 *std/num/float64/(*): (x : float64, y : float64) -> float64 0x1.0p54literal: float64
hex64= 0x1p54
, -54literal: int
dec = -54
hex8 = 0xCA
bit8 = 0b11001010
) else decode-normalizedstd/num/float64/decode-normalized: (d : float64, e-adjust : ? int) -> (int, int)(dd: float64,0literal: int
dec = 0
hex8 = 0x00
bit8 = 0b00000000
) // decode a normalized float64 (i.e. not subnormal) fun decode-normalizedstd/num/float64/decode-normalized: (d : float64, e-adjust : ? int) -> (int, int)( dd: float64 : float64std/core/types/float64: V, e-adjuste-adjust: ? int : intstd/core/types/int: V = 0literal: int
dec = 0
hex8 = 0x00
bit8 = 0b00000000
)result: -> total (int, int) : (std/core/types/tuple2: (V, V) -> Vintstd/core/types/int: V,intstd/core/types/int: V) val ii: int64 = float64-to-bitsstd/num/float64/float64-to-bits: (d : float64) -> int64(dd: float64) val expexp: int64 = andstd/num/int64/and: (int64, int64) -> int64(ii: int64.shrstd/num/int64/shr: (i : int64, shift : int) -> int64(52literal: int
dec = 52
hex8 = 0x34
bit8 = 0b00110100
),0x7FFliteral: int
dec = 2047
hex16= 0x07FF
bit16= 0b0000011111111111
.int64std/num/int64/int64: (i : int) -> int64) -std/num/int64/(-): (x : int64, y : int64) -> int64 1043literal: int
dec = 1043
hex16= 0x0413
bit16= 0b0000010000010011
.int64std/num/int64/int64: (i : int) -> int64 val manman: int64 = andstd/num/int64/and: (int64, int64) -> int64(ii: int64,0x000F_FFFF_FFFF_FFFFliteral: int
dec = 4503599627370495
hex64= 0x000FFFFFFFFFFFFF
bit64= 0b0000000000001111111111111111111111111111111111111111111111111111
.int64std/num/int64/int64: (i : int) -> int64) +std/num/int64/(+): (x : int64, y : int64) -> int64 0x0010_0000_0000_0000literal: int
dec = 4503599627370496
hex64= 0x0010000000000000
bit64= 0b0000000000010000000000000000000000000000000000000000000000000000
.int64std/num/int64/int64: (i : int) -> int64 (std/core/types/Tuple2: forall<a,b> (fst : a, snd : b) -> (a, b) (if ii: int64.is-negstd/num/int64/is-neg: (i : int64) -> bool then ~std/num/int64/(~): (i : int64) -> int64manman: int64 else manman: int64).intstd/num/int64/int: (i : int64) -> int, expexp: int64.intstd/num/int64/int: (i : int64) -> int -std/core/int/(-): (x : int, y : int) -> int 32literal: int
dec = 32
hex8 = 0x20
bit8 = 0b00100000
+std/core/int/(+): (x : int, y : int) -> int e-adjuste-adjust: int
)std/core/types/Tuple2: forall<a,b> (fst : a, snd : b) -> (a, b) // 'Fraction/exponent': return the normalized fraction `f` and exponent `exp` // for a number `x` such that `x == f`&middot;2^`exp`^. // The absolute value of the fraction `f` is always in the range [0.5, 1.0), or // one of `0.0`, `-0.0`, `neginf`, `posinf`, or `nan`. // See also `decode` which decodes to an integer mantissa. pub fun frexpstd/num/float64/frexp: (x : float64) -> (float64, int)( xx: float64 : float64std/core/types/float64: V )result: -> total (float64, int) : (std/core/types/tuple2: (V, V) -> Vfloat64std/core/types/float64: V, intstd/core/types/int: V) if !std/core/types/bool/(!): (b : bool) -> boolxx: float64.is-finitestd/num/float64/is-finite: (d : float64) -> bool ||std/core/types/(||): (x : bool, y : bool) -> bool xx: float64.is-negzerostd/num/float64/is-negzero: (d : float64) -> bool returnreturn: (float64, int) (std/core/types/Tuple2: forall<a,b> (fst : a, snd : b) -> (a, b)xx: float64,0literal: int
dec = 0
hex8 = 0x00
bit8 = 0b00000000
)std/core/types/Tuple2: forall<a,b> (fst : a, snd : b) -> (a, b) val (std/core/types/Tuple2: forall<a,b> (fst : a, snd : b) -> (a, b)mm: int,ee: int)std/core/types/Tuple2: forall<a,b> (fst : a, snd : b) -> (a, b) = xx: float64.decodestd/num/float64/decode: (d : float64) -> (int, int) (std/core/types/Tuple2: forall<a,b> (fst : a, snd : b) -> (a, b)mm: int.float64std/num/float64/float64: (i : int) -> float64 *std/num/float64/(*): (x : float64, y : float64) -> float64 0x1.0p-53literal: float64
hex64= 0x1p-53
, ee: int +std/core/int/(+): (x : int, y : int) -> int 53literal: int
dec = 53
hex8 = 0x35
bit8 = 0b00110101
)std/core/types/Tuple2: forall<a,b> (fst : a, snd : b) -> (a, b) // Returns the greatest `:float64` less than `x`. // This behaves exactly as `nextDown` in the IEEE 754-2008 standard. // The identity `x.next-down == ~next-down(~x)` holds for all `x`. // When `x` is finite `x == x.next-down.next-up` also holds. pub fun next-downstd/num/float64/next-down: (x : float64) -> float64( xx: float64 : float64std/core/types/float64: V )result: -> total float64 : float64std/core/types/float64: V if xx: float64.is-nanstd/num/float64/is-nan: (d : float64) -> bool ||std/core/types/(||): (x : bool, y : bool) -> bool xx: float64.is-neginfstd/num/float64/is-neginf: (d : float64) -> bool then xx: float64 elif xx: float64.is-zerostd/num/float64/is-zero: (d : float64) -> bool then ~std/num/float64/(~): (f : float64) -> float64flt-true-minstd/num/float64/flt-true-min: float64 else val ii: int64 = float64-to-bitsstd/num/float64/float64-to-bits: (d : float64) -> int64(xx: float64) val nextnext: int64 = if ii: int64.is-negstd/num/int64/is-neg: (i : int64) -> bool then ii: int64.incstd/num/int64/inc: (i : int64) -> int64 else ii: int64.decstd/num/int64/dec: (i : int64) -> int64 float64-from-bitsstd/num/float64/float64-from-bits: (i : int64) -> float64(nextnext: int64) // Returns the least `:float64` greater than `x`. // This behaves exactly as `nextUp` in the IEEE 754-2008 standard. // The identity `x.next-up == ~next-down(~x)` holds for all `x`. // When `x` is finite `x == x.next-up.next-down` also holds. pub fun next-upstd/num/float64/next-up: (x : float64) -> float64( xx: float64 : float64std/core/types/float64: V )result: -> total float64 : float64std/core/types/float64: V if xx: float64.is-nanstd/num/float64/is-nan: (d : float64) -> bool ||std/core/types/(||): (x : bool, y : bool) -> bool xx: float64.is-posinfstd/num/float64/is-posinf: (d : float64) -> bool then xx: float64 elif xx: float64.is-zerostd/num/float64/is-zero: (d : float64) -> bool then flt-true-minstd/num/float64/flt-true-min: float64 else val ii: int64 = float64-to-bitsstd/num/float64/float64-to-bits: (d : float64) -> int64(xx: float64) val nextnext: int64 = if ii: int64.is-negstd/num/int64/is-neg: (i : int64) -> bool then ii: int64.decstd/num/int64/dec: (i : int64) -> int64 else ii: int64.incstd/num/int64/inc: (i : int64) -> int64 float64-from-bitsstd/num/float64/float64-from-bits: (i : int64) -> float64(nextnext: int64) // Compare floats using a total ordering on the `:float64`. // The ordering follows the `totalOrder` predicate as defined in IEEE 754-2008 exactly. // The values are ordered in following order: // negative quiet nan, // negative signaling nan, // `neginf`, // -finite, // -0.0, // +0.0, // finite, // `posinf`, // signaling nan, // and quiet nan. pub fun cmpstd/num/float64/cmp: (x : float64, y : float64) -> order( xx: float64 : float64std/core/types/float64: V, yy: float64 : float64std/core/types/float64: V )result: -> total order : orderstd/core/types/order: V val bxbx: int64 = float64-to-bitsstd/num/float64/float64-to-bits: (d : float64) -> int64(xx: float64) val byby: int64 = float64-to-bitsstd/num/float64/float64-to-bits: (d : float64) -> int64(yy: float64) // flip exp+mantissa bits if negative to get a two's complement number val ixix: int64 = bxbx: int64.sarstd/num/int64/sar: (i : int64, shift : int) -> int64(63literal: int
dec = 63
hex8 = 0x3F
bit8 = 0b00111111
).shrstd/num/int64/shr: (i : int64, shift : int) -> int64(1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
).xorstd/num/int64/xor: (int64, int64) -> int64(bxbx: int64) val iyiy: int64 = byby: int64.sarstd/num/int64/sar: (i : int64, shift : int) -> int64(63literal: int
dec = 63
hex8 = 0x3F
bit8 = 0b00111111
).shrstd/num/int64/shr: (i : int64, shift : int) -> int64(1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
).xorstd/num/int64/xor: (int64, int64) -> int64(byby: int64) cmpstd/num/int64/cmp: (x : int64, y : int64) -> order(ixix: int64,iyiy: int64
) // The midpoint is the average of `x` and `y`. // Avoids overflow on large numbers. pub fun midpointstd/num/float64/midpoint: (x : float64, y : float64) -> float64( xx: float64 : float64std/core/types/float64: V, yy: float64 : float64std/core/types/float64: V )result: -> total float64 : float64std/core/types/float64: V if is-subnormalstd/num/float64/is-subnormal: (d : float64) -> bool(xx: float64) ||std/core/types/(||): (x : bool, y : bool) -> bool is-subnormalstd/num/float64/is-subnormal: (d : float64) -> bool(yy: float64) then (xx: float64 +std/num/float64/(+): (x : float64, y : float64) -> float64 yy: float64) /std/num/float64/(/): (x : float64, y : float64) -> float64 2.0literal: float64
hex64= 0x1p1
else (xx: float64 /std/num/float64/(/): (x : float64, y : float64) -> float64 2.0literal: float64
hex64= 0x1p1
) +std/num/float64/(+): (x : float64, y : float64) -> float64 (yy: float64 /std/num/float64/(/): (x : float64, y : float64) -> float64 2.0literal: float64
hex64= 0x1p1
) // Linear interpolation, calculating `x + t*(y - x)` but avoids troublesome edge cases. // Follows the C++20 [specification](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0811r3.html). // In particular, if `x.is-finite && y.is-finite`, then: // - exact: `lerp(x,y,0.0) == x` and `lerp(x,y,1.0) == y` // - monotonic: if `x <= y` and `t1 <= t2`, then `cmp( lerp(x,y,t1), lerp(x,y,t2) ) <= Eq` (and other cases) // - deterministic: only `lerp(x,x,flt-inf)` results in `nan` // - bounded: `t<0.0 || t>1.0 || is-finite(lerp(x,y,t))` // - consistent: `lerp(x,x,t) == x` pub fun lerpstd/num/float64/lerp: (x : float64, y : float64, t : float64) -> float64( xx: float64 : float64std/core/types/float64: V, yy: float64 : float64std/core/types/float64: V, tt: float64 : float64std/core/types/float64: V )result: -> total float64 : float64std/core/types/float64: V if (xx: float64 <=std/num/float64/(<=): (x : float64, y : float64) -> bool 0.0literal: float64
hex64= 0x0p+0
&&std/core/types/(&&): (x : bool, y : bool) -> bool yy: float64 >=std/num/float64/(>=): (x : float64, y : float64) -> bool 0.0literal: float64
hex64= 0x0p+0
) ||std/core/types/(||): (x : bool, y : bool) -> bool (xx: float64 >=std/num/float64/(>=): (x : float64, y : float64) -> bool 0.0literal: float64
hex64= 0x0p+0
&&std/core/types/(&&): (x : bool, y : bool) -> bool yy: float64 <=std/num/float64/(<=): (x : float64, y : float64) -> bool 0.0literal: float64
hex64= 0x0p+0
) then tt: float64*std/num/float64/(*): (x : float64, y : float64) -> float64yy: float64 +std/num/float64/(+): (x : float64, y : float64) -> float64 (1.0literal: float64
hex64= 0x1p0
-std/num/float64/(-): (x : float64, y : float64) -> float64 tt: float64)*std/num/float64/(*): (x : float64, y : float64) -> float64xx: float64 elif tt: float64 ==std/num/float64/(==): (x : float64, y : float64) -> bool 1.0literal: float64
hex64= 0x1p0
then yy: float64 else val zz: float64 = xx: float64 +std/num/float64/(+): (x : float64, y : float64) -> float64 tt: float64*std/num/float64/(*): (x : float64, y : float64) -> float64(yy: float64 -std/num/float64/(-): (x : float64, y : float64) -> float64 xx: float64) if ((tt: float64 >std/num/float64/(>): (x : float64, y : float64) -> bool 1.0literal: float64
hex64= 0x1p0
) ==std/core/bool/(==): (x : bool, y : bool) -> bool (yy: float64 >std/num/float64/(>): (x : float64, y : float64) -> bool xx: float64)) then maxstd/num/float64/max: (x : float64, y : float64) -> float64(yy: float64,zz: float64) else minstd/num/float64/min: (x : float64, y : float64) -> float64(yy: float64,zz: float64
) //----------------------------------------- // Show in hexadecimal //----------------------------------------- /* Show a float64 in [hexadecimal notation](https://books.google.com/books?id=FgMsCwAAQBAJ&pg=PA41). An advantage of this format is that it precisely represents the `:float64` and can reliably (and efficiently) be parsed back, i.e. `d.show-hex.parse-float64 == Just(d)`. The significant is the _hexadecimal_ fraction while the exponent after the `p` is the _decimal_ power of 2. For example, ``0xA.Fp-10`` = (10 + 15/16)&middot;2^-10^ (not 2^-16^!) = 0.01068115234375. Equivalently, ``0xA.Fp-10 == 0x5.78p-9 == 0x2.BCp-8 == 0x1.5Ep-7``. ``` > flt-min.show-hex "0x1.0p-1022" > 0.1.show-hex "0x1.999999999999Ap-4" > flt-max.show-hex "0x1.FFFFFFFFFFFFFp+1023" > -0.0.show-hex "-0x0.0p+0" > nan.show-hex "NaN" > 0.01068115234375.show-hex "0x1.5Ep-7" ``` . */ pub fun show-hexstd/num/float64/show-hex: (d : float64, width : ? int, use-capitals : ? bool, pre : ? string) -> string( dd: float64 : float64std/core/types/float64: V, widthwidth: ? int : intstd/core/types/int: V = 1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
, use-capitalsuse-capitals: ? bool : boolstd/core/types/bool: V = Truestd/core/types/True: bool, prepre: ? string : stringstd/core/types/string: V = "0x"literal: string
count= 2
)result: -> total string : stringstd/core/types/string: V if !std/core/types/bool/(!): (b : bool) -> booldd: float64.is-finitestd/num/float64/is-finite: (d : float64) -> bool then dd: float64.showstd/num/float64/show: (d : float64, precision : ? int) -> string else val (std/core/types/Tuple2: forall<a,b> (fst : a, snd : b) -> (a, b)mm: int,ee: int)std/core/types/Tuple2: forall<a,b> (fst : a, snd : b) -> (a, b) = dd: float64.decodestd/num/float64/decode: (d : float64) -> (int, int) val manman: string = mm: int.absstd/core/int/abs: (i : int) -> int.show-hexstd/core/show/show-hex: (i : int, width : ? int, use-capitals : ? bool, pre : ? string) -> string(1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
,use-capitalsuse-capitals: bool,""literal: string
count= 0
) val exp0exp0: int = ee: int +std/core/int/(+): (x : int, y : int) -> int 4literal: int
dec = 4
hex8 = 0x04
bit8 = 0b00000100
*std/core/int/(*): (int, int) -> int(manman: string.countstd/core/string/count: (s : string) -> int -std/core/int/(-): (x : int, y : int) -> int 1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
) val expexp: string = (if exp0exp0: int >=std/core/int/(>=): (x : int, y : int) -> bool 0literal: int
dec = 0
hex8 = 0x00
bit8 = 0b00000000
then "+"literal: string
count= 1
else ""literal: string
count= 0
) ++std/core/types/(++): (x : string, y : string) -> string exp0exp0: int.showstd/core/int/show: (i : int) -> string val fracfrac: string = manman: string.tailstd/core/sslice/tail: (s : string) -> string.trim-rightstd/core/sslice/trim-right: (s : string, sub : string) -> string("0"literal: string
count= 1
).pad-rightstd/core/string/pad-right: (s : string, width : int, fill : ? char) -> string(maxstd/core/int/max: (i : int, j : int) -> int(1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
,widthwidth: int),'0'literal: char
unicode= u0030
) val signsign: string = if dd: float64.is-negstd/num/float64/is-neg: (d : float64) -> bool ||std/core/types/(||): (x : bool, y : bool) -> bool dd: float64.is-negzerostd/num/float64/is-negzero: (d : float64) -> bool then "-"literal: string
count= 1
else ""literal: string
count= 0
signsign: string ++std/core/types/(++): (x : string, y : string) -> string prepre: string ++std/core/types/(++): (x : string, y : string) -> string manman: string.headstd/core/sslice/head: (s : string) -> string ++std/core/types/(++): (x : string, y : string) -> string "."literal: string
count= 1
++std/core/types/(++): (x : string, y : string) -> string fracfrac: string ++std/core/types/(++): (x : string, y : string) -> string "p"literal: string
count= 1
++std/core/types/(++): (x : string, y : string) -> string expexp: string
//----------------------------------------- // Parse a float64 //----------------------------------------- // Parse a float64 number. Can be "NaN", "Inf(inity)" (case-insensitive), // a fix-point number (`1.2`) or in scientific notation (`-2.3e-5`). // Also allows floats in [hexadecimal notation](https://books.google.com/books?id=FgMsCwAAQBAJ&pg=PA41) (`0xA.Fp-10`) that can // be represented precisely (and are the preferred _round trip_ format). pub fun parse-float64std/num/float64/parse-float64: (s : string) -> maybe<float64>( ss: string : stringstd/core/types/string: V )result: -> total maybe<float64> : maybestd/core/types/maybe: V -> V<float64std/core/types/float64: V> ss: string.trimstd/core/string/trim: (s : string) -> string.to-lowerstd/core/string/to-lower: (s : string) -> string.slicestd/core/sslice/slice: (s : string) -> sslice.parse-eofstd/text/parse/parse-eof: (input : sslice, p : () -> parse float64) -> parse-error<float64>(pdoublestd/num/float64/pdouble: () -> parse float64).maybestd/text/parse/maybe: (perr : parse-error<float64>) -> maybe<float64> pub fun pdoublestd/num/float64/pdouble: () -> parse float64()result: -> parse float64 : parsestd/text/parse/parse: (E, V) -> V float64std/core/types/float64: V val negneg: bool = signstd/text/parse/sign: () -> parse bool() val dd: float64 = [std/core/types/Cons: forall<a> (head : a, tail : list<a>) -> list<a>{ phexdoublestd/num/float64/phexdouble: () -> parse float64() }, { pdecdoublestd/num/float64/pdecdouble: () -> parse float64() }, { pspecialstd/num/float64/pspecial: () -> parse float64() }, { 0.0literal: float64
hex64= 0x0p+0
}]std/core/types/Nil: forall<a> list<a>.choosestd/text/parse/choose: (ps : list<parser<total,float64>>) -> parse float64 if negneg: bool then ~std/num/float64/(~): (f : float64) -> parse float64dd: float64 else
dd: float64 fun phexdoublestd/num/float64/phexdouble: () -> parse float64()result: -> parse float64 : parsestd/text/parse/parse: (E, V) -> V float64std/core/types/float64: V charstd/text/parse/char: (c : char) -> parse char('0'literal: char
unicode= u0030
) one-ofstd/text/parse/one-of: (chars : string) -> parse char("xX"literal: string
count= 2
) val manman: string = hex-digitsstd/text/parse/hex-digits: () -> parse string() val fracfrac: string = optionalstd/text/parse/optional: (default : string, p : parser<total,string>) -> parse string( ""literal: string
count= 0
, { charstd/text/parse/char: (c : char) -> parse char('.'literal: char
unicode= u002E
); hex-digitsstd/text/parse/hex-digits: () -> parse string() }).trim-rightstd/core/sslice/trim-right: (s : string, sub : string) -> parse string("0"literal: string
count= 1
) val expexp: int : intstd/core/types/int: V = optionalstd/text/parse/optional: (default : int, p : parser<total,int>) -> parse int( 0literal: int
dec = 0
hex8 = 0x00
bit8 = 0b00000000
, { one-ofstd/text/parse/one-of: (chars : string) -> parse char("pP"literal: string
count= 2
); pintstd/text/parse/pint: () -> parse int() }) val mm: int : intstd/core/types/int: V = (manman: string ++std/core/types/(++): (x : string, y : string) -> parse string fracfrac: string).parse-intstd/core/int/parse-int: (s : string, hex : ? bool) -> parse maybe<int>(hex=Truestd/core/types/True: bool).defaultstd/core/maybe/default: (m : maybe<int>, nothing : int) -> parse int(0literal: int
dec = 0
hex8 = 0x00
bit8 = 0b00000000
) val ee: int : intstd/core/types/int: V = expexp: int -std/core/int/(-): (x : int, y : int) -> parse int 4literal: int
dec = 4
hex8 = 0x04
bit8 = 0b00000100
*std/core/int/(*): (int, int) -> parse intfracfrac: string.countstd/core/string/count: (s : string) -> parse int encodestd/num/float64/encode: (man : int, exp : int) -> parse float64(mm: int,ee: int
) fun pdecdoublestd/num/float64/pdecdouble: () -> parse float64()result: -> parse float64 : parsestd/text/parse/parse: (E, V) -> V float64std/core/types/float64: V val curcur: sslice = current-inputstd/text/parse/current-input: () -> parse sslice() val manman: string = digitsstd/text/parse/digits: () -> parse string() val fracfrac: string = optionalstd/text/parse/optional: (default : string, p : parser<total,string>) -> parse string(""literal: string
count= 0
, { charstd/text/parse/char: (c : char) -> parse char('.'literal: char
unicode= u002E
); digits0std/text/parse/digits0: () -> parse string() }).trim-rightstd/core/sslice/trim-right: (s : string, sub : string) -> parse string("0"literal: string
count= 1
) val expexp: int : intstd/core/types/int: V = optionalstd/text/parse/optional: (default : int, p : parser<total,int>) -> parse int( 0literal: int
dec = 0
hex8 = 0x00
bit8 = 0b00000000
, { one-ofstd/text/parse/one-of: (chars : string) -> parse char("eE"literal: string
count= 2
); pintstd/text/parse/pint: () -> parse int() }) //val m : int = (man ++ frac).parse-int.default(0) //val e : int = exp - frac.count //m.float64 * exp10(e.float64) curcur: sslice.stringstd/core/sslice/string: (slice : sslice) -> parse string.prim-parse-float64std/num/float64/prim-parse-float64: (s : string) -> parse float64
// more precision than simple multiply fun pspecialstd/num/float64/pspecial: () -> parse float64()result: -> parse float64 : parsestd/text/parse/parse: (E, V) -> V float64std/core/types/float64: V [std/core/types/Cons: forall<a> (head : a, tail : list<a>) -> list<a>{ pstringstd/text/parse/pstring: (s : string) -> parse string("nan"literal: string
count= 3
); nanstd/num/float64/nan: float64 }, { pstringstd/text/parse/pstring: (s : string) -> parse string("infinity"literal: string
count= 8
); posinfstd/num/float64/posinf: float64 }, { pstringstd/text/parse/pstring: (s : string) -> parse string("inf"literal: string
count= 3
); posinfstd/num/float64/posinf: float64 } ]std/core/types/Nil: forall<a> list<a>.choosestd/text/parse/choose: (ps : list<parser<total,float64>>) -> parse float64
// Return `nan` on failure extern prim-parse-float64std/num/float64/prim-parse-float64: (s : string) -> float64( ss: string : stringstd/core/types/string: V ) : float64std/core/types/float64: V c "kk_prim_parse_double" cs "Primitive.DoubleParse" js "parseFloat" //----------------------------------------- // Various //----------------------------------------- // Return the sum of a list of floats. // Uses [Kahan-Babu&scaron;kan-Neumaier summation](https://en.wikipedia.org/wiki/Kahan_summation_algorithm#Further_enhancements) // to minimize rounding errors. This // is more precise as Kahan summation and about as fast.\ // `[1.0e3,1.0e97,1.0e3,-1.0e97].sum == 2000.0`\ // while\ // `[1.0e3,1.0e97,1.0e3,-1.0e97].foldl(0.0,(+)) == 0.0` (!)\ // A. Neumaier, _Rundungsfehleranalyse einiger Verfahren zur Summation endlicher Summen_. // Math. Mechanik, 54:39--51, 1974. pub fun sumstd/num/float64/sum: (xs : list<float64>) -> float64( xsxs: list<float64> : liststd/core/types/list: V -> V<float64std/core/types/float64: V> )result: -> total float64 : float64std/core/types/float64: V var totaltotal: local-var<$2994,float64> := 0.0literal: float64
hex64= 0x0p+0
var compcomp: local-var<$2994,float64> := 0.0literal: float64
hex64= 0x0p+0
xsxs: list<float64>.foreachstd/core/list/foreach: (xs : list<float64>, action : (float64) -> (local<$2994>) ()) -> (local<$2994>) () fnfn: (x : float64) -> (local<$2994>) ()(xx: float64) val tt: float64 = totaltotal: float64 +std/num/float64/(+): (x : float64, y : float64) -> (local<$2994>) float64 xx: float64 val cc: float64 = if totaltotal: float64.absstd/num/float64/abs: (f : float64) -> (local<$2994>) float64 >=std/num/float64/(>=): (x : float64, y : float64) -> (local<$2994>) bool xx: float64.absstd/num/float64/abs: (f : float64) -> (local<$2994>) float64 then (totaltotal: float64 -std/num/float64/(-): (x : float64, y : float64) -> (local<$2994>) float64 tt: float64) +std/num/float64/(+): (x : float64, y : float64) -> (local<$2994>) float64 xx: float64 else (xx: float64 -std/num/float64/(-): (x : float64, y : float64) -> (local<$2994>) float64 tt: float64) +std/num/float64/(+): (x : float64, y : float64) -> (local<$2994>) float64 totaltotal: float64 compcomp: local-var<$2994,float64> :=std/core/types/local-set: (v : local-var<$2994,float64>, assigned : float64) -> (local<$2994>) () compcomp: float64 +std/num/float64/(+): (x : float64, y : float64) -> (local<$2994>) float64 cc: float64 totaltotal: local-var<$2994,float64> :=std/core/types/local-set: (v : local-var<$2994,float64>, assigned : float64) -> (local<$2994>) () tt: float64 totaltotal: float64 +std/num/float64/(+): (x : float64, y : float64) -> (local<$2994>) float64 compcomp: float64
; // The hypotenuse of `x` and `y`: `sqrt(x*x + y*y)`. // Prevents overflow for large numbers. pub fun hypotstd/num/float64/hypot: (x : float64, y : float64) -> float64( xx: float64 : float64std/core/types/float64: V, yy: float64 : float64std/core/types/float64: V )result: -> total float64 : float64std/core/types/float64: V val xxxx: float64 = absstd/num/float64/abs: (f : float64) -> float64(xx: float64) val yyyy: float64 = absstd/num/float64/abs: (f : float64) -> float64(yy: float64) val lolo: float64 = minstd/num/float64/min: (x : float64, y : float64) -> float64(xxxx: float64,yyyy: float64) val hihi: float64 = maxstd/num/float64/max: (x : float64, y : float64) -> float64(xxxx: float64,yyyy: float64) if hihi: float64==std/num/float64/(==): (x : float64, y : float64) -> bool0.0literal: float64
hex64= 0x0p+0
then 0.0literal: float64
hex64= 0x0p+0
else val zz: float64 = lolo: float64 /std/num/float64/(/): (x : float64, y : float64) -> float64 hihi: float64 hihi: float64 *std/num/float64/(*): (x : float64, y : float64) -> float64 sqrtstd/num/float64/sqrt: (d : float64) -> float64( 1.0literal: float64
hex64= 0x1p0
+std/num/float64/(+): (x : float64, y : float64) -> float64 zz: float64*std/num/float64/(*): (x : float64, y : float64) -> float64zz: float64
) // The square root of the sum of the squares of three floats. // Prevents overflow for large numbers. pub fun xyz/hypotstd/num/float64/xyz/hypot: (x : float64, y : float64, z : float64) -> float64( xx: float64 : float64std/core/types/float64: V, yy: float64 : float64std/core/types/float64: V, zz: float64 : float64std/core/types/float64: V )result: -> total float64 : float64std/core/types/float64: V val xxxx: float64 = absstd/num/float64/abs: (f : float64) -> float64(xx: float64) val yyyy: float64 = absstd/num/float64/abs: (f : float64) -> float64(yy: float64) val zzzz: float64 = absstd/num/float64/abs: (f : float64) -> float64(zz: float64) val hihi: float64 = maxstd/num/float64/max: (x : float64, y : float64) -> float64(maxstd/num/float64/max: (x : float64, y : float64) -> float64(xxxx: float64,yyyy: float64),zzzz: float64) if hihi: float64==std/num/float64/(==): (x : float64, y : float64) -> bool0.0literal: float64
hex64= 0x0p+0
then 0.0literal: float64
hex64= 0x0p+0
else hihi: float64 *std/num/float64/(*): (x : float64, y : float64) -> float64 sqrtstd/num/float64/sqrt: (d : float64) -> float64( sqrstd/num/float64/sqr: (x : float64) -> float64(xxxx: float64 /std/num/float64/(/): (x : float64, y : float64) -> float64 hihi: float64) +std/num/float64/(+): (x : float64, y : float64) -> float64 sqrstd/num/float64/sqr: (x : float64) -> float64(yyyy: float64 /std/num/float64/(/): (x : float64, y : float64) -> float64 hihi: float64) +std/num/float64/(+): (x : float64, y : float64) -> float64 sqrstd/num/float64/sqr: (x : float64) -> float64(zzzz: float64 /std/num/float64/(/): (x : float64, y : float64) -> float64 hihi: float64)
) // The square root of the sum of squares of a list of floats. // Prevents overflow for large numbers and uses Kahan-Babu&scaron;kan-Neumaier summation // for precision. pub fun list/hypotstd/num/float64/list/hypot: (xs : list<float64>) -> float64( xsxs: list<float64> : liststd/core/types/list: V -> V<float64std/core/types/float64: V> )result: -> total float64 : float64std/core/types/float64: V val hihi: float64 = xsxs: list<float64>.abs-maxstd/num/float64/list/abs-max: (xs : list<float64>) -> float64 if hihi: float64==std/num/float64/(==): (x : float64, y : float64) -> bool0.0literal: float64
hex64= 0x0p+0
then 0.0literal: float64
hex64= 0x0p+0
else hihi: float64 *std/num/float64/(*): (x : float64, y : float64) -> float64 xsxs: list<float64>.mapstd/core/list/map: (xs : list<float64>, f : (float64) -> float64) -> list<float64>( fnfn: (x : float64) -> float64(xx: float64) sqrstd/num/float64/sqr: (x : float64) -> float64(xx: float64 /std/num/float64/(/): (x : float64, y : float64) -> float64 hihi: float64) ).sumstd/num/float64/sum: (xs : list<float64>) -> float64.sqrtstd/num/float64/sqrt: (d : float64) -> float64
// The square of a float64 pub fun sqrstd/num/float64/sqr: (x : float64) -> float64(xx: float64 : float64std/core/types/float64: V )result: -> total float64: float64std/core/types/float64: V xx: float64*std/num/float64/(*): (x : float64, y : float64) -> float64xx: float64 // The maximum of the absolute values. pub fun abs-maxstd/num/float64/abs-max: (x : float64, y : float64) -> float64( xx: float64 : float64std/core/types/float64: V, yy: float64 : float64std/core/types/float64: V )result: -> total float64 : float64std/core/types/float64: V maxstd/num/float64/max: (x : float64, y : float64) -> float64(absstd/num/float64/abs: (f : float64) -> float64(xx: float64),absstd/num/float64/abs: (f : float64) -> float64(yy: float64)) // The maximum of a list of absolute values. pub fun list/abs-maxstd/num/float64/list/abs-max: (xs : list<float64>) -> float64( xsxs: list<float64> : liststd/core/types/list: V -> V<float64std/core/types/float64: V> )result: -> total float64 : float64std/core/types/float64: V xsxs: list<float64>.foldlstd/core/list/foldl: (xs : list<float64>, z : float64, f : (float64, float64) -> float64) -> float64(0.0literal: float64
hex64= 0x0p+0
, fnfn: (m : float64, x : float64) -> float64(mm: float64,xx: float64) maxstd/num/float64/max: (x : float64, y : float64) -> float64(absstd/num/float64/abs: (f : float64) -> float64(xx: float64),mm: float64)
) //----------------------------------------- // Trigonometry //----------------------------------------- val rad2degstd/num/float64/rad2deg: float64 : float64std/core/types/float64: V = 180.0literal: float64
hex64= 0x1.68p7
/std/num/float64/(/): (x : float64, y : float64) -> float64pistd/num/float64/pi: float64
val deg2radstd/num/float64/deg2rad: float64 : float64std/core/types/float64: V = pistd/num/float64/pi: float64/std/num/float64/(/): (x : float64, y : float64) -> float64180.0literal: float64
hex64= 0x1.68p7
// Convert radians to degrees. pub fun degstd/num/float64/deg: (rad : float64) -> float64( radrad: float64 : float64std/core/types/float64: V )result: -> total float64 : float64std/core/types/float64: V radrad: float64 *std/num/float64/(*): (x : float64, y : float64) -> float64 rad2degstd/num/float64/rad2deg: float64 // Convert degrees to radians. pub fun radstd/num/float64/rad: (deg : float64) -> float64( degdeg: float64 : float64std/core/types/float64: V )result: -> total float64 : float64std/core/types/float64: V degdeg: float64 *std/num/float64/(*): (x : float64, y : float64) -> float64 deg2radstd/num/float64/deg2rad: float64 // Return `x` with the sign of `y`. pub fun with-sign-ofstd/num/float64/with-sign-of: (x : float64, y : float64) -> float64( xx: float64 : float64std/core/types/float64: V, yy: float64 : float64std/core/types/float64: V )result: -> total float64 : float64std/core/types/float64: V if yy: float64 <std/num/float64/(<): (x : float64, y : float64) -> bool 0.0literal: float64
hex64= 0x0p+0
then ~std/num/float64/(~): (f : float64) -> float64(xx: float64.absstd/num/float64/abs: (f : float64) -> float64) else xx: float64.absstd/num/float64/abs: (f : float64) -> float64
// Return the sine of an angle in radians `d`. pub inline extern sinstd/num/float64/sin: (d : float64) -> float64( d : float64std/core/types/float64: V ) : float64std/core/types/float64: V c "sin" cs "Math.Sin" js "Math.sin" // Return the cosine of an angle in radians `d`. pub inline extern cosstd/num/float64/cos: (d : float64) -> float64( d : float64std/core/types/float64: V ) : float64std/core/types/float64: V c "cos" cs "Math.Cos" js "Math.cos" // Return the tangent of an angle in radians `d`. pub inline extern tanstd/num/float64/tan: (d : float64) -> float64( d : float64std/core/types/float64: V ) : float64std/core/types/float64: V c "tan" cs "Math.Tan" js "Math.tan" // Return the arc-tangent of `d` pub inline extern atanstd/num/float64/atan: (d : float64) -> float64( d : float64std/core/types/float64: V ) : float64std/core/types/float64: V c "atan" cs "Math.Atan" js "Math.atan" // Return the arc-tangent of a point (`x`,`y`). pub inline extern atan2std/num/float64/atan2: (x : float64, y : float64) -> float64( x : float64std/core/types/float64: V, y : float64std/core/types/float64: V ) : float64std/core/types/float64: V c "atan2" cs "Math.Atan2" js "Math.atan2" // Return the arc-cosine of `d` pub inline extern acosstd/num/float64/acos: (d : float64) -> float64( d : float64std/core/types/float64: V ) : float64std/core/types/float64: V c "acos" cs "Math.Acos" js "Math.acos" // Return the arc-sine of `d` pub inline extern asinstd/num/float64/asin: (d : float64) -> float64( d : float64std/core/types/float64: V ) : float64std/core/types/float64: V c "asin" cs "Math.Asin" js "Math.asin" // The hyperbolic tangent of `d` pub inline extern tanhstd/num/float64/tanh: (d : float64) -> float64( d : float64std/core/types/float64: V ) : float64std/core/types/float64: V c "tanh" cs "Math.Tanh" js "Math.tanh" // The hyperbolic cosine of `d` pub inline extern coshstd/num/float64/cosh: (d : float64) -> float64( d : float64std/core/types/float64: V ) : float64std/core/types/float64: V c "cosh" cs "Math.Cosh" js "Math.cosh" // The hyperbolic sine of `d` pub inline extern sinhstd/num/float64/sinh: (d : float64) -> float64( d : float64std/core/types/float64: V ) : float64std/core/types/float64: V c "sinh" cs "Math.Sinh" js "Math.sinh" // Return `ln(1.0 + x)`. // Avoids potential imprecision for small `x` where adding `1.0` explicitly // may lead to rounding errors. pub inline extern ln1pstd/num/float64/ln1p: (d : float64) -> float64( d : float64std/core/types/float64: V ) : float64std/core/types/float64: V c "log1p" js "Math.log1p" // Return `exp(x - 1.0)`. // Avoids rounding errors for values of `x` very close to `1.0`. pub inline extern expm1std/num/float64/expm1: (d : float64) -> float64( d : float64std/core/types/float64: V ) : float64std/core/types/float64: V c "expm1" js "Math.expm1" // The area hyperbolic tangent of `d` pub extern atanhstd/num/float64/atanh: (d : float64) -> float64( dd: float64 : float64std/core/types/float64: V ) : float64std/core/types/float64: V c "atanh" js "Math.atanh" // The area hyperbolic cosine of `d` pub extern acoshstd/num/float64/acosh: (d : float64) -> float64( dd: float64 : float64std/core/types/float64: V ) : float64std/core/types/float64: V c "acosh" js "Math.acosh" // The area hyperbolic sine of `d` pub extern asinhstd/num/float64/asinh: (d : float64) -> float64( dd: float64 : float64std/core/types/float64: V ) : float64std/core/types/float64: V c "asinh" js "Math.asinh" // ------------------------ // explicit implementations // ------------------------ /* // Return `log(1.0 + x)`. // Avoids potential imprecision for small `x` where adding `1.0` explicitly // may lead to rounding errors. pub fun log1p( x : float64 ) : float64 if x.is-posinf then x else val y = 1.0 + x val z = y - 1.0 if z==0.0 then x else log(y) * (x / z) // Return `exp(x - 1.0)`. // Avoids rounding errors for values of `x` very close to `1.0`. pub fun expm1( x : float64 ) : float64 if x.is-posinf then x else val y = exp(x) if y==1.0 then x elif y - 1.0 == -1.0 then -1.0 else (y - 1.0) * (x / log(y)) // The area hyperbolic tangent of `x` pub fun atanh( x : float64 ) : float64 0.5*log( (1.0 + x) / (1.0 - x)) /* // 0.5*log( (1.0 + x) / (1.0 - x)) = 0.5*log1p( (2.0*x) / (1-x) ) if x.abs >= 0.5 then 0.5*log1p(2.0*(x/(1.0 - x))) else val x2 = x + x 0.5*log1p(x2 + (x2*x)/(1.0 - x)) */ // The area hyperbolic cosine of `x` pub fun acosh( x : float64 ) : float64 // log(x + sqrt((x - 1.0)*(x + 1.0))); if x > 0x1.0p28 then flt-ln2 + log(x) elif x > 2.0 then log(2.0*x - 1.0/(x + sqrt(x.sqr - 1.0))) elif x <= 1.0 then (if x < 1.0 then nan else 0.0) else val xm1 = x - 1.0 log1p( xm1 + sqrt(2.0*xm1 + xm1*xm1) ) // The area hyperbolic sine of `x` pub fun asinh( x : float64 ) : float64 //log( x + sqrt(x.sqr + 1.0)) val xa = x.abs if xa > 0x1.0p28 then (log(xa) + flt-ln2).with-sign-of(x) elif xa >= 2.0 then (log(2.0*xa + 1.0/(xa + sqrt(xa.sqr + 1.0)))).with-sign-of(x) elif xa == 0.0 then 0.0 else val xa2 = xa.sqr log1p( xa + xa2/(1.0 + sqrt( xa2 + 1.0 ))).with-sign-of(x) */