Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it a good idea to use IEEE754 floating point NaN for values which are not set?

Is it a good idea to use IEEE754 floating point NaN (not-a-number) for values which are undefined for non-mathematical reasons?

In our case they are not yet set because the values have not been received from some other device. The context is an embedded system using IEC1131 REAL32 values. Edit: The programming language is C, so we would most likely use NAN and isnanf(x), which are from C99. Though we may need some extra contortions to get these into our OS compatibility layer.

The default in programming languages seems to be to initialize floating point variables with positive zero, whose internal representation is all zeros. That is not usable for us, because 0 is in the range of valid values.

It seems like a clean solution to use NaN, but maybe it is more hassle than it is worth and we should pick some other value?

like image 331
starblue Avatar asked Jun 24 '09 06:06

starblue


People also ask

How many NaN can be represented with floating-point?

It seems that the IEEE 754 standard defines 16,777,214 32-bit floating point values as NaNs, or 0.4% of all possible values.

What is NaN in ieee754?

NaN stands for Not a Number , and is used to represent a numerically undefined value. This is done by setting all exponent bits to 1 (as with infinity), and having at least one bit in the significand set to 1. IEEE 754 specifies that 0.0/0.0 should return NaN .

How does NaN represent floating-point?

A signaling NaN is represented by any bit pattern between X'7F80 0001' and X'7FBF FFFF' or between X'FF80 0001' and X'FFBF FFFF'. A quiet NaN is represented by any bit pattern between X'7FC0 0000' and X'7FFF FFFF' or between X'FFC0 0000' and X'FFFF FFFF'.

How NaN values behave while comparing with itself?

Why do comparisons of NaN values behave differently from all other values? That is, all comparisons with the operators ==, <=, >=, <, > where one or both values is NaN returns false, contrary to the behaviour of all other values.


2 Answers

Just noticed this question.

This is one of the uses of NaNs that the IEEE 754 committee has in mind (I was a committee member). The propagation rules for NaNs in arithmetic make this very attractive, because if you have a result from a long sequence of calculations that involve some initialized data, you will not mistake the result for a valid result. It can also make tracing back through your calculations to find where you are using the initialized data much more straightforward.

That said, there are a few pitfalls that are outside of the 754 committee's control: as others have noted, not all hardware supports NaN values at speed, which can result in performance hazards. Fortunately, one does not often do a lot of operations on initialized data in a performance-critical setting.

like image 107
Stephen Canon Avatar answered Sep 30 '22 00:09

Stephen Canon


NaNs are a reasonable choice for a 'no value' sentential (the D programming language uses them for uninitialized values, for instance), but because any comparisons involving them will be false, you can get a few surprises:

  • if (result == DEFAULT_VALUE), won't work as expected if DEFAULT_VALUE is NaN, as Jon mentioned.

  • They can also cause problems with range checking if you're not careful. Consider the function:

bool isOutsideRange(double x, double minValue, double maxValue)
{
    return x < minValue || x > maxValue;
}

If x is NaN, this function would incorrectly report that x is between minValue and maxValue.

If you just want a magic value for users to test against, I'd recommend positive or negative infinity instead of NaN, as it doesn't come with the same traps. Use NaN when you want it for its property that any operations on a NaN result in a NaN: it's handy when you don't want to rely on callers checking the value, for example.

[Edit: I initially managed to type "any comparisons involving them will be true" above, which is not what I meant, and is wrong, they're all false, apart from NaN != NaN, which is true]

like image 45
jskinner Avatar answered Sep 29 '22 23:09

jskinner