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)
and x != 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.
isnan()
is clean and self-documenting, whilex != x
, no matter how well-defined it may be per IEEE-754, looks like a kludge that might happen to work today but not tomorrow. – Sombrerox != x
has to be implemented for floating point numbers - the memory can't be compared directly because that would ignoreNaN
values, so there has to be an additional check done on the values beforehand... – DevlandNaN
?" That check isisnan()
.isnan()
functionality is a prerequisite for definingx != x
ifx
isNaN
. – Devland!=
? – Wanyenx == 0
also cannot be implemented as a simple bitwise operation (or it would fail to recognize that −0 equals zero), but we do not have aniszero
macro. There is a floating-point comparison instruction that produces the desired result. None of which is relevant to==
versusisnan
, as either may be implemented with one instruction or many as required by the hardware. – Marcelloiszero
macro Well, we actually do. It just has a different name. Because we havefpclassify( value ) == FP_ZERO
– Devland