It is well known that for any variable of floating-point type x != x
iff (if and only if) x
is NaN
(not-a-number). Or inverse version: x == x
iff x
is not NaN
. Then why did WG14 decide to define isnan(x)
(math.h
) if the same result can be obtained using the natural capabilities of the language? What was the motivation? Better code readability?
Extra question: Are there any functional differences between isnan(x)
and x != x
?
"Why does NaN exist at all, rather than resulting in an exception or error?" Because it is neither an exception nor an error. It is a perfectly valid result for a calculation. You have several use cases in mathematics where you are receiving the equivalent to "NaN", i.e., something that cannot be measured.
NaN cannot be compared with any floating type value. This means that we'll get false for all comparison operations involving NaN (except “!= ” for which we get true). Hence, we cannot check for NaN by comparing with NaN using “==” or “!=
NaN is neither less than nor greater than any number.
In computing, NaN (/næn/), standing for Not a Number, is a member of a numeric data type that can be interpreted as a value that is undefined or unrepresentable, especially in floating-point arithmetic.
if the same result can be obtained using natural capabilities of the language?
C does not specify x == x
iff x is not NaN
. Many implementations do that though. C does not require adherence to IEEE_754. isnan(x)
is well defined.
Use isnan(x)
for portable code.
C in Representations of types (since C99) has
Two values (other than NaNs) with the same object representation compare equal, but values that compare equal may have different object representations.
... but that does not specify the behavior of comparing 2 NANs.
When __STDC_IEC_559__
(akin to adherence to IEEE-754) is defined as 1 (something not required by C), then
"The expression x != x is true if x is a NaN."
"The expression x == x is false if x is a NaN."
When __STDC_IEC_559__
is not defined as 1, exercise caution about assuming behavior in the edges of floating point math such as NAN
equality.
[Edit to address some comments]
C, on the corners of FP math, lack the specifics of IEEE-754. C89 allowed NANs as evidenced by references to IEEE-754, yet lacked isnan(x)
. There was no "Two values (other than NaNs) with the same object representation compare equal, ..." to guide either. At that time, x==x
for NAN was not specified. With C99, rather than break or invalidate prior code, isnan(x)
is defined as a clear NAN test. As I see it, x==x
remains unspecified for NANs, yet it is commonly results in false. isnan(x)
also provides code clarity. Much about C and NAN is fuzzy: round tripping payload sequences, signaling encoding/discernment, NAN availability, ...
Are there any functional differences between
isnan(x)
andx != x
?
In addition to the well defined functionality of isnan(x)
versus x != x
discussed above, some obscure ones:
isnan(x)
evaluates x
once versus twice for x != x
. Makes a difference if x
was some expression like y++
.
isnan(x)
operates on the sematic type. This makes a difference when "the implementation supports NaNs in the evaluation type but not in the semantic type.". x != x
operates on the evaluation type. Research FLT_EVAL_METHOD
for more detail.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With