Double.NaN - how does this counterintuitive function work?

I came across a definition of .NET double.NaN in code:

 public const double NaN = (double)0.0 / (double)0.0; 

This is done similarly in PositiveInfinity and NegativeInfinity .

double.IsNaN (with the removal of several #pragmas and comments) is defined as:

 [Pure] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] public static bool IsNaN(double d) { if (d != d) { return true; } else { return false; } } 

This is very controversial for me.

Why is NaN defined as division by zero? How is 0.0 / 0.0 presented behind the scenes? How can division by 0 be possible in double , and why NaN != NaN ?

+4
source share
3 answers

Pretty simple answer here .. The Net Framework implemented the floating point standard specified by IEEE ( System.Double complies with IEC 60559: 1989 (IEEE 754) for binary floating point arithmetic.) . This is because floating point arithmetic should actually work on many systems, not just the x86 / 64 architecture, so following the conventions will ensure that there will be less compatibility issues (for example, porting code from DSP to x86 processor )

As for d! = D, this is performance optimization. Basically, this instruction is based on a hardware instruction, which can very quickly determine if two double floating-point numbers are equal. According to the NAN standard! = NAN and, therefore, the fastest way to test. Trying to find a link for you.

+6
source

Why is NaN defined as division by zero? How can one divide by 0 possibly in double, and why NaN! = NaN?

All of them are provided by the IEEE 754 standard, which is implemented in almost all modern CPUs.

How are 0.0 / 0.0 presented behind the scenes?

Having an exponent with all the bits set to 1, and a mantissa with at least one bit set to 1. Note that this means that there are a large number of different bit patterns that all represent NaN, but as mentioned above, even if the bit patterns are identical, they should be considered not equal (i.e. == should return false).

+2
source

In C # Spec:

14.9.2 Floating point comparison operators Predefined floating point comparison operators:

bool operator == (float x, float y); bool operator == (double x, double y);
bool operator! = (float x, float y); bool operator! = (double x, double y);
bool operator <(float x, float y); bool operator <(double x, double y);
bool operator> (float x, float y); bool operator> (double x, double y);
bool operator <= (float x, float y); bool operator <= (double x, double y),
bool operator> = (float x, float y); bool operator> = (double x, double y);

Operators compare operands in accordance with the rules of IEC 60559: If any of the operands is NaN, the result will be false for all operators except! = for which the result is true. For any two operands, x! = Y always gives the same result as! (x = = y). However, when one or both operands are NaN, the operators <,>, <= and> = do not give the same results as the logical negation of the opposite operator. [Example: if any of x and y is NaN, then x <y is wrong, but! (x> = y) is true. end of example]

Regarding the presentation of NaN behind the scenes, the IEEE Wikipedia article has a few examples.

0
source

Source: https://habr.com/ru/post/1333360/


All Articles