Skip to content
CryoCryo home
Stdlibfmt

float

import std::fmt::float; · source

Float formatting lives here rather than in core::primitives because it needs libm, and keeping libc out of core matters more. The API is extension methods on the primitives.

Types

f64

implement f64 {
    is_negative_zero(&this) -> boolean;
    to_buf(&this, buffer: u8*) -> u64;
    to_buf_with(&this, buffer: u8*, decimals: u64) -> u64;
    to_buf_roundtrip(&this, buffer: u8*) -> u64;
}

to_buf writes fixed-point text with six fractional digits into a buffer of at least F64_MAX_DIGITS (32) bytes, to_buf_with takes the precision, and to_buf_roundtrip — f64 only — writes the shortest decimal string that re-parses to the identical bit value.

Values beyond |v| >= 1e16 or below 0 < |v| < 1e-4 switch to scientific notation, so no precision disappears into a giant zero prefix or a run of trailing zeros. NaN, both infinities, and both zeros are handled explicitly — negative zero prints as -0 so the sign is not lost.

to_buf is a first-cut formatter: correct for human-readable output but not round-trippable, since the fixed six decimals silently truncate (3.141592653589793 becomes 3.141593). Anything that must preserve the value — JSON serialization, notably — should use to_buf_roundtrip, which tries 15, then 16, then 17 significant digits and returns the first that re-parses exactly. Typical values stay compact: 0.1, not 0.10000000000000001.

Methods

is_negative_zero(&this) -> boolean;

IEEE 754: -0.0 has bit pattern 0x8000_0000_0000_0000. The cheap check is 1.0 / v == -Infinity, but we'd rather not divide; the direct comparison relies on value == 0.0 being true for both +/-0 while the sign bit still drives the output branch.

to_buf(&this, buffer: u8*) -> u64;

Write this into buffer. Returns bytes written. buffer must hold at least F64_MAX_DIGITS bytes.

to_buf_with(&this, buffer: u8*, decimals: u64) -> u64;

Variant with caller-chosen precision. decimals applies to the fixed-point form and to the mantissa of the scientific form.

to_buf_roundtrip(&this, buffer: u8*) -> u64;

Write this as the SHORTEST decimal string that re-parses (via strtod) to the identical f64 bit value - i.e. a round-trippable representation. Tries 15, then 16, then 17 significant digits (every finite double round-trips at 17) and returns the first that reparses exactly, so typical values stay compact (0.1, not the noisy 0.10000000000000001). Returns bytes written (excluding the NUL).

f32

implement f32 {
    to_buf(&this, buffer: u8*) -> u64;
    to_buf_with(&this, buffer: u8*, decimals: u64) -> u64;
    is_negative_zero(&this) -> boolean;
}

The same fixed-point writers at single precision. There is no to_buf_roundtrip for f32; widen to f64 for a round-trippable rendering.

Methods

to_buf(&this, buffer: u8*) -> u64;
to_buf_with(&this, buffer: u8*, decimals: u64) -> u64;
is_negative_zero(&this) -> boolean;

Free Functions

function parse_f64(s: string) -> Option<f64>;

Parse a leading f64 from s using C strtod semantics: skip leading whitespace, read the longest valid float prefix (decimal or scientific; no hex floats). Returns None when s has no numeric prefix. The single funnel every float-from-text caller routes through, replacing scattered sscanf("%lf"). Caller-supplied strings must already be cleaned of digit separators (_), which strtod - like sscanf - would stop at.

Integer formatting is on the primitives themselves in core::primitives, and integer parsing goes through TryFrom<Str> in collections::str.

Constants

const DEFAULT_DECIMALS: u64 = 6;
const LARGE_THRESHOLD:  f64 = 1.0e16;
const SMALL_THRESHOLD:  f64 = 1.0e-4;
const F64_MAX_DIGITS:   u64 = 32;