Expand description
§nanval
A no_std
, zero-dependency crate for the creation and handling of NaN-tagged 64-bit floating-point values.
Inspired by this article and this crate.
§How does this work?
When a 64-bit floating-point number is set to NaN
/0x7FF8000000000000
, its bits are as follows:
s111 1111 1111 1qxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
^ ^\____________________________________________________________/
| | ^
| Sign Bit | Quiet Bit | Data Bits
As long as the data bits aren’t all set to 0
, indicating the original/sentinel NaN
value, they can be literally anything else! This gives us 50 bits to mess with/use as we please…
§UInts / Unsigned Integers
Look at the module
crate::uint
for this.
TODO: Add explanation.
§Cells / Pointers
Look at the module
crate::cell
for this.
Since it doesn’t matter what the sign-bit s
is set to, we can use it as a flag/marker that indicates that the value is some kind of cell
or ptr
.
Combine this with the fact that basically all x64-platforms only use the lower 48 or 50 bits for addressing (ignoring CHERI shenanigans), we are left with 3 bits (that includes the ‘quiet’ bit) to store some kind of type-tag for the cell; look at the crate::cell::CellTag
.
§References
Re-exports§
pub use raw::IntoRawBits64;
Modules§
- cell
- Handling of values marked as a ‘cell’ (
SIGN_BIT | NAN_BITS
, with 3 ‘tag’ bits). - cons
- Various important constants for NaN-tagging, bit-masking, etc.
- raw
- Trait for functions that can accept any sized+copy 64-bit value.
- uint
- Handling of values marked as a ‘uint’ (
!SIGN_BIT | NAN_BITS
): 52-bit integers.
Functions§
- is_
float - Checks if the given value is a valid
f64
. - is_
nanval - Checks if the given value is a NaN-tagged value.
- unwrap_
float - Returns the value as
f64
, if it is a valid 64-bit floating point number. - unwrap_
float_ unchecked - Returns the value as
f64
; does not check if the value is actually a float.