#nan #pointers #tagged-pointers #nanbox #tagged-enum #unsigned-integer

no-std litl-nanval

A 64-bit value, that is either a floating-point number (f64), or an arbitrary 52-bit integer

1 unstable release

0.2.0 Nov 15, 2022

#10 in #tagged-pointers

Download history 29/week @ 2024-06-23 7/week @ 2024-06-30 8/week @ 2024-07-07 32/week @ 2024-07-14 35/week @ 2024-07-21 27/week @ 2024-07-28 21/week @ 2024-08-04 22/week @ 2024-08-11 13/week @ 2024-08-18 41/week @ 2024-08-25 36/week @ 2024-09-01 16/week @ 2024-09-08 23/week @ 2024-09-15 42/week @ 2024-09-22 26/week @ 2024-09-29 4/week @ 2024-10-06

99 downloads per month
Used in 11 crates (via litl-val)

MIT/Apache

26KB
430 lines

nanval

Crates.io Docs.rs GitHub LOC

A no_std, zero-dependency crate for the creation and handling of NaN-tagged 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

No runtime deps

Features