Skip to content

Instantly share code, notes, and snippets.

@eaglgenes101
Created October 13, 2018 18:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eaglgenes101/eee00bc212b989b21500473cabcfb111 to your computer and use it in GitHub Desktop.
Save eaglgenes101/eee00bc212b989b21500473cabcfb111 to your computer and use it in GitHub Desktop.
Double-precision floating point numbers have 9007199254740990 different valid NaN payloads, and single-precision floating points have 16777214, both way more than the vast majority of programs will ever need for floating-point purposes. Let's pack our own data into that.
In a double-precision floating-point number, there are 52 mantissa bits, and one sign bit. When the exponent has all bits set, the value as a whole is interpreted as an overflow value if all zeroes, and a NaN otherwise, giving (2^52 - 1)*2 different valid NaN values. Similarly, single-precision floating-point has 21 mantissa bits, for (2^21-1)*2 different valid NaN values. For the room allotted for them, NaN payloads are insignificant in the scheme of things: the IEEE standard mandates NaN behavior that makes their payloads essentially opaque to type-safe code, most programming languages and libraries only give one or two different NaN payloads, most encodings which accept floating point NaNs disregard the payload, and there is not standard for NaN payloads outside of individual applications.
In a similar vein to null-pointer optimization, this RFC suggests the following changes:
- The specific NaN values reserved for the optimization are platform-dependent, and are chosen so that the minimum number of bits need to be read to distinguish between NaNs originating from floating-point computations and ones which are used for this optimization.
- The language is changed so that the specific payload of the stdlib-provided NaN is unspecified, and that setting it to any other payload is undefined in Rust-layout types. C-layout types do not perform the optimization, and setting their payload to any value is well-defined, so as to accomodate any C programs that performed similar optimizations manually. Crater runs are performed to ferret out any regressions caused by this minor breaking change.
- In the compiler, layout attempts to use the sign bit and high mantissa bits for the discriminant, and use the low mantissa bits to store fields.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment