f64
stdlib/f64.hk: bit-level methods on the f64 fixed-width float.
f64 is an IEEE 754 double (HANKI.md §3). to_bits/from_bits expose its raw bit pattern, the seam any binary float codec needs: there is no other way to reach the eight wire bytes of a float from Hanki. Both are total and lossless, and from_bits is the exact inverse of to_bits. parse is the decimal text seam: a correctly-rounded string to f64.
impl f64
to_bits
def to_bits(self) -> u64
The raw IEEE 754 bit pattern of self, as a u64. Exact inverse of from_bits.
1.0f64.to_bits() => 4607182418800017408u64
0.0f64.to_bits() => 0u64
from_bits
def from_bits(bits: u64) -> f64
The f64 whose IEEE 754 bit pattern is bits. Exact inverse of to_bits.
f64.from_bits(4607182418800017408u64) => 1.0f64
f64.from_bits(0u64) => 0.0f64
_parse
def _parse(s: string) -> Option<f64>
The runtime seam under [FromString]: the raw yes-or-no parse, with no room to say why. parse below is the surface, and turns the None into a reason.
min
def min(self, other: f64) -> f64
The smaller of self and other. Where one is NaN and the other is not, it returns the other (IEEE minNum); -0.0 and 0.0 compare equal, and either may be returned for that pair.
2.0f64.min(3.0f64) => 2.0f64
3.0f64.min(2.0f64) => 2.0f64
max
def max(self, other: f64) -> f64
The larger of self and other. Where one is NaN and the other is not, it returns the other (IEEE maxNum).
2.0f64.max(3.0f64) => 3.0f64
3.0f64.max(2.0f64) => 3.0f64
abs
def abs(self) -> f64
The magnitude of self, the sign bit cleared. (-0.0).abs() is 0.0; NaN.abs() is NaN.
(-2.5f64).abs() => 2.5f64
2.5f64.abs() => 2.5f64
to_int
def to_int(self) -> int
Truncates self toward zero into the unbounded int tier. The fractional part is dropped, like a Rust as cast. int has no range tier has no range limit, the crossing is total, and the IEEE non-finite floats map to int's in-band sentinels - inf -> inf, -inf -> -inf, NaN -> undefined - the exact inverse of int.to_f64.
3.9f64.to_int() => 3
(-3.9f64).to_int() => -3
2.0f64.to_int() => 2
floor
def floor(self) -> f64
--- Rounding to integral f64 values (the result remains f64) --- The largest integral f64 not greater than self (round toward -inf).
2.7f64.floor() => 2.0f64
(-2.3f64).floor() => -3.0f64
ceil
def ceil(self) -> f64
The smallest integral f64 not less than self (round toward +inf).
2.3f64.ceil() => 3.0f64
(-2.7f64).ceil() => -2.0f64
round
def round(self) -> f64
The nearest integral f64, rounding half away from zero (2.5 -> 3, -2.5 -> -3).
2.5f64.round() => 3.0f64
2.4f64.round() => 2.0f64
(-2.5f64).round() => -3.0f64
trunc
def trunc(self) -> f64
self with the fractional part removed (round toward zero).
2.7f64.trunc() => 2.0f64
(-2.7f64).trunc() => -2.0f64
sqrt
def sqrt(self) -> f64
--- Roots and powers --- The square root. NaN for a negative input (no trap).
9.0f64.sqrt() => 3.0f64
2.0f64.sqrt().to_int() => 1
cbrt
def cbrt(self) -> f64
The cube root (defined for negatives: (-8).cbrt() is -2).
27.0f64.cbrt() => 3.0f64
(-8.0f64).cbrt() => -2.0f64
pow
def pow(self, exp: f64) -> f64
self raised to the power exp (both f64).
2.0f64.pow(10.0f64) => 1024.0f64
4.0f64.pow(0.5f64) => 2.0f64
exp
def exp(self) -> f64
--- Exponentials and logarithms --- e raised to the power self.
0.0f64.exp() => 1.0f64
ln
def ln(self) -> f64
The natural logarithm (base e). NaN for a negative input, -inf at zero.
1.0f64.exp().ln().round() => 1.0f64
1.0f64.ln() => 0.0f64
log10
def log10(self) -> f64
The base-10 logarithm.
1000.0f64.log10() => 3.0f64
log2
def log2(self) -> f64
The base-2 logarithm.
8.0f64.log2() => 3.0f64
sin
def sin(self) -> f64
--- Trigonometry (radians) --- The sine of self (radians).
0.0f64.sin() => 0.0f64
cos
def cos(self) -> f64
The cosine of self (radians).
0.0f64.cos() => 1.0f64
tan
def tan(self) -> f64
The tangent of self (radians).
0.0f64.tan() => 0.0f64
atan2
def atan2(self, x: f64) -> f64
The four-quadrant arctangent of self / x (radians), using the signs of both to place the angle in the correct quadrant.
0.0f64.atan2(1.0f64) => 0.0f64
hypot
def hypot(self, other: f64) -> f64
The Euclidean distance sqrt(self^2 + other^2), computed without undue overflow.
3.0f64.hypot(4.0f64) => 5.0f64
to_fixed
def to_fixed(self, places: int) -> string
--- Rendering --- self with places fractional digits, printf's %.Nf, which Display cannot spell: it prints the shortest text that round-trips, so 1.0f64 renders as 1 and never as 1.00.
Ties round half to even, as %.2f does in C, Python, Go and Crystal, and unlike round above (half away from zero). There is no rounding-mode parameter: on this tier the tie is usually not a real one, 2.675f64 being 2.67499…, and a mode would offer a choice about a digit the value does not have. decimal.to_fixed is the exact tier's answer and takes the mode.
Zero-padding matches printf, and a negative places clamps to zero. A places past 1100 clamps there too: the smallest f64 is ~4.9e-324, so everything beyond that is padding, and a computed precision that went wrong would otherwise ask for a string measured in gigabytes. The non-finite values render as their names, a fixed number of digits meaning nothing for them.
places is an int because a digit count is a count, and the module whose scale accessor answers int should ask for one too. A places that is itself non-finite clamps like any other out-of-range count: toward the bound it points at.
1.5f64.to_fixed(3) => "1.500"
1.0f64.to_fixed(2) => "1.00"
2.5f64.to_fixed(0) => "2"
3.5f64.to_fixed(0) => "4"
2.675f64.to_fixed(2) => "2.67"
(-1.25f64).to_fixed(1) => "-1.2"
1.5f64.to_fixed(0 - 1) => "2"
(0.0f64 / 0.0f64).to_fixed(2) => "NaN"
(1.0f64 / 0.0f64).to_fixed(2) => "inf"
(-1.0f64 / 0.0f64).to_fixed(2) => "-inf"
impl FromString<f64>
parse
def parse(s: string) -> Result<f64, ParseError>
Parses a decimal float, correctly rounded. Accepts the forms the platform float parser does (1.5, -0.25, 1e10); a magnitude past f64's range rounds to the IEEE infinity in place of failing, and the only way to fail is for the text not to denote a number at all. Surrounding whitespace is trimmed.
The success doctests compare the unwrapped value and not the Result: f64 has no Eq (IEEE NaN breaks reflexivity), and a Result<f64, ParseError> cannot be ==-compared (HANKI.md §20). The failure line maps the payload to a bool for the same reason. An Err is comparable only when both sides are.
f64.parse("0.5").unwrap_or(0.0f64) => 0.5f64
f64.parse("-2.0").unwrap_or(0.0f64) => -2.0f64
f64.parse("nope").map(|v| v > 0.0f64) => Err(ParseError(input="nope", reason="not a decimal float"))