wasm_num (wasm v0.1.0)
View SourceConversion between IEEE 754 bit patterns and the runtime float representation.
Read this when a float coming out of a module is not the shape you expected.
Erlang cannot hold NaN or Infinity in a float. Arithmetic that would produce
one raises badarith, and <<F:64/float>> does not even match the bit
patterns 7FF0... or 7FF8.... WebAssembly requires both, including NaN
payload propagation, so floats use a hybrid representation:
- finite values are Erlang floats, which is the fast and common case;
infinityandneg_infinityare atoms;- NaN is
{nan, Sign, Payload}, keeping the payload bits that the specification's NaN propagation rules make observable. Signed zero needs no special case: since OTP 27-0.0 =/= 0.0and<<(-0.0):64/float>>produces the correct sign bit, so Erlang models it natively.
Arithmetic over this representation lives in wasm_num_f32 and wasm_num_f64.
This module is only the boundary with bit patterns: constants in the binary
format, reinterpret instructions, and linear memory loads and stores.
Summary
Functions
The NaN the specification requires an operation to produce when it makes one.
A 32-bit IEEE 754 bit pattern as a runtime float.
The inverse of f32_from_bits/1. NaN payload and sign survive the round trip.
As f32_canonical_nan/0, at 64 bits.
As f32_from_bits/1, at 64 bits.
As f32_to_bits/1, at 64 bits.
Whether this is an ordinary value, which is exactly when it is an Erlang float.
Whether this is either infinity.
Whether this is a NaN. Never true of an Erlang float, which cannot be one.
Reinterpret a signed value as unsigned, for the _u operations.
Reinterpret a signed value as unsigned, at 64 bits.
Reduce to the signed 32-bit range, wrapping like two's complement.
Reduce to the signed 64-bit range, wrapping like two's complement.
Reduce to the unsigned 32-bit range.
Reduce to the unsigned 64-bit range.
Types
Functions
-spec f32_canonical_nan() -> f32().
The NaN the specification requires an operation to produce when it makes one.
-spec f32_from_bits(non_neg_integer()) -> f32().
A 32-bit IEEE 754 bit pattern as a runtime float.
Total: every one of the 2^32 patterns has an answer. An exponent of all ones
becomes infinity, neg_infinity or {nan, Sign, Payload}, because an Erlang
float cannot hold those. Everything else is an Erlang float.
-spec f32_to_bits(f32()) -> non_neg_integer().
The inverse of f32_from_bits/1. NaN payload and sign survive the round trip.
-spec f64_canonical_nan() -> f64().
As f32_canonical_nan/0, at 64 bits.
-spec f64_from_bits(non_neg_integer()) -> f64().
As f32_from_bits/1, at 64 bits.
-spec f64_to_bits(f64()) -> non_neg_integer().
As f32_to_bits/1, at 64 bits.
Whether this is an ordinary value, which is exactly when it is an Erlang float.
Whether this is either infinity.
Whether this is a NaN. Never true of an Erlang float, which cannot be one.
-spec to_u32(integer()) -> non_neg_integer().
Reinterpret a signed value as unsigned, for the _u operations.
-spec to_u64(integer()) -> non_neg_integer().
Reinterpret a signed value as unsigned, at 64 bits.
Reduce to the signed 32-bit range, wrapping like two's complement.
Reduce to the signed 64-bit range, wrapping like two's complement.
-spec wrap_u32(integer()) -> non_neg_integer().
Reduce to the unsigned 32-bit range.
-spec wrap_u64(integer()) -> non_neg_integer().
Reduce to the unsigned 64-bit range.