Search code examples
floating-pointintegernan

Why are NaN floats?


Division by zero can lead to the apparition of objects, which, while being typed as numbers, are not valid numbers. This led to the creation of NaNs values for numeric data types, mostly used in floating point arithmetic (and hence in most programming float types).

Since division by zero could also occur when manipulating integers, why doesn't a 'NaN integer' exist?

I am looking for a documented answer on programmatic constraints explaining this pattern.


Solution

  • Because all integers are consistent, have a value.

    A 8 bit unsigned integers goes from 00000000 to 11111111, and all those values have a clear, defined, value, that is from 0 to 255.

    Which one of those value would you sacrifice to code a 8 bit unsigned integer NaN? 255 maybe. But then, you sacrifice lot of possible applications. You can't use 8 bits unsigned integer to handle bytes (since they are in [0,256)). Nor use them to manipulate images (white (255,255,255) pixels would be (NaN, NaN, NaN)). Etc.

    Not even mentionning all the optimization that becomes impossible if 11111111 unsigned 8bits int means NaN, but 11111111 signed bits int means -1 (which it has to do)

    Sure, you could use 16 bits integer instead. But that would be to need twice as much memory for all those applications (and those happen to be the kind of applicative usage that makes sometimes even 64Gb memory insufficient. I am currently working on a such an application, where my buffer images use all of my 64 Gb. It would be to much cost to half my buffer capacity, just because of a remote possibility that I might need to encode an integer NaN).

    Because, that is another reason why it is not so: why would someone need that? I mean, NaN means "Not a number". That is it means that the bits stored in a memory place where a number should be, do not, in reality, represent a number.

    It is different for floats. Because classical IEEE encoding of floats makes some combination of bits meaningless (or special). Not much. It is not like it was 1 unused bit, or anything remotely similar. Just a few impossible values among billions of possible ones. But still, some combination of bits are not valid. Or, more precisely, we gave them some special meaning, including NaN.

    For int, it is up to you to decide that, for your application, you can sacrifice a value. For example, if you are storing dice outputs, you have more than enough choice to decide that one value (-1, 0, 7, 99, ... anything but 1,2,3,4,5 or 6) will have a special meaning for you (such as "the dice was not rolled"). The system can't take the responsibility to sacrifice some combination of bits, that is some possible values, to make same special, even for those who don't need any such special value.

    For float, well, since there are already a few impossible/redundant combination of bits it cost nothing to give them special names.