Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does isnan(x) exist if x != x gives the same result?

Tags:

c

nan

ieee-754

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?

like image 949
pmor Avatar asked Jan 29 '21 21:01

pmor


People also ask

Why does NaN exist?

"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.

How does NaN compare?

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 “!=

Is NaN less than zero?

NaN is neither less than nor greater than any number.

What kind of data type is NaN?

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.


1 Answers

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.

like image 171
chux - Reinstate Monica Avatar answered Oct 11 '22 19:10

chux - Reinstate Monica