This is usually called NaN-boxing and is often used to implement dynamic languages.<p><a href="https://piotrduperas.com/posts/nan-boxing" rel="nofollow">https://piotrduperas.com/posts/nan-boxing</a>
This doesn't work on Firefox, as it normalizes NaNs as they're extracted from ArrayBuffers. Presumably because SpiderMonkey uses NaN-boxing itself, and thus just doesn't have any way to represent actual non-canonical NaN floats.
Note that there are a lot of exciting new float-related functions in C23, many related to NaN handling, signed zeros, or precision in edge cases. Some have been in glibc for years; others not yet.<p>The API for `getpayload`/`setpayload`/`setpayloadsig` looks a little funny but it's easy enough to wrap (just consider the edge cases; in particular remember that whether 0 is valid for quiet or signaling NaNs is platform-dependent).<p>Finally we have a reliable `roundeven`, and the convenience of directly calling `nextup`/`nextdown` (but note that you'll still only visit one of the zeros).<p>The new `fmaximum` family is confusing, but I think I have it clear:<p><pre><code> without 'imum' (legacy): prefer non-NaN
with 'imum': zeros distinguished (-0 < +0)
with '_num': prefer a non-NaN, also signal if applicable
with '_mag': compare as if fabs first
</code></pre>
`totalorder` has been often-desired; the other new comparisons not so much.<p>`rootn` and `compoundn` are surprisingly tricky to implement yourself. I still have one testcase I'm not sure why I have to hand-patch, and I'm not sure which implementation choice keeps the best precision (to say nothing of correct rounding mode).
I made a garlic nan: <a href="https://www.godbolt.org/z/enjv1c7Tf" rel="nofollow">https://www.godbolt.org/z/enjv1c7Tf</a>
Since the first time I had Indian food sometime in 1987 I have always called naan “not a number bread” and no one has ever laughed. I feel like i may have found my people.
I guess I just don't get it because the before & after cases don't seem to be showing remotely comparable use cases.<p>In the "before" use-cases, the programmer has accidentally written a bug and gets back a single NaN from a logical operation they performed as a result.<p>In the "after" cases, the programmer already has some data and explicitly decides to convert it to a NaN encoding. But instead of actually getting back a NaN that is secretly carrying their data, they actually get a whole array of NaN's, which duck type differently, and thus are likely to disappear into another NaN or an undefined if they are propagated through an API.<p>Like.. I get that the whole thing is supposed to be humorously absurd but... It just doesn't land unless there's something technical I'm missing to connect up the pieces.
I learned about this when trying to decode data from Firefox IndexedDB. (I was extracting Tana data.) Their structured clone data format uses nan-boxing for serialization.
Reminds me of using the highest bit(s) of 64-bit ints to stuff auxiliary data into lockfree algorithms. So long as you’re aware of your OS environment you can enable some efficiencies you couldn’t otherwise.
The nan bits were intended to help provide more informative float error diagnostics at the language implementation level for non crashing code. I wonder if I’ll ever get to exploring it myself.