Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does double.IsNegative(double.NaN) return true?

Why does double.IsNegative(double.NaN) unexpectedly return true whereas double.NaN < 0 returns false as expected?

like image 479
tiger-empire Avatar asked May 20 '21 18:05

tiger-empire


People also ask

How to check if a double is not a NaN java?

Java Double isNaN() Method The isNaN() method of Java Double class returns true: If the value of this Object is Not-a-Number (NaN). If the argument passed is Not-a-Number (NaN). Otherwise, the method returns false.

What does double NaN do?

Use the IsNaN method to determine whether a value is not a number. The Equality operator considers two NaN values to be unequal to one another. In general, Double operators cannot be used to compare Double. NaN with other Double values, although comparison methods (such as Equals and CompareTo) can.

What is the value of double NaN?

NaN values are tested for equality by using the == operator, the result is false. So, no matter what value of type double is compared with double. NaN, the result is always false.

How to find the value of a double Nan?

What you can do is use compare / compareTo: Double.NaN is considered by this method to be equal to itself and greater than all other double values (including Double.POSITIVE_INFINITY ). If this and argument both represent Double.NaN, then the equals method returns true, even though Double.NaN==Double.NaN has the value false.

What does Isnan return when double is negative?

IsNaN returns false if a Double value is either PositiveInfinity or NegativeInfinity. To test for these values, use the IsInfinity, IsPositiveInfinity, and IsNegativeInfinity methods. Converts the string representation of a number to its double-precision floating-point number equivalent.

Why do floating-point operations return Nan?

Floating-point operations return NaN to signal that result of the operation is undefined. For example, dividing 0.0 by 0.0 results in NaN. IsNaN returns false if a Double value is either PositiveInfinity or NegativeInfinity. To test for these values, use the IsInfinity, IsPositiveInfinity, and IsNegativeInfinity methods.

How do you use Nan in numeric comparison?

All numeric operations with NaN as an operand produce NaN as a result. As has already been described, NaN is unordered, so a numeric comparison operation involving one or two NaNs returns false and any != comparison involving NaN returns true, including x!=x when x is NaN. Published at DZone with permission of Peter Lawrey, DZone MVB .


2 Answers

Well, according to refrence source, double.IsNegative just checks the most significant bit:

    [Pure]
    [System.Security.SecuritySafeCritical]  // auto-generated
    internal unsafe static bool IsNegative(double d) {
        return (*(UInt64*)(&d) & 0x8000000000000000) == 0x8000000000000000;
    }

In case of double.NaN the most signifucant bit is set:

    11111111 11111000 00000000 00000000 00000000 00000000 00000000 00000000   
    ||           ||                                                       |
    |<-   Exp   -><-                     Mantissa                        ->
    Sign

That's why double.IsNegative returns true

When we put < or > FPU commands are used which know all ones exponent is a special kind of floating point value which should be treated in a special way.

The very same picture is with Single.NaN.

Note, that we can construct another strange value, negative zero:

    10000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000   
    ||           ||                                                       |
    |<-   Exp   -><-                          Mantissa                   ->
    Sign

Please, look:

  double negativeZero = BitConverter.ToDouble(new byte[] { 
    0, 0, 0, 0, 0, 0, 0, 128
  });

  Console.WriteLine(negativeZero == 0 ? "Zero" : "???");

  Console.WriteLine(double.IsNegative(negativeZero) ? "Negative" : "???");
like image 107
Dmitry Bychenko Avatar answered Oct 11 '22 22:10

Dmitry Bychenko


The IEEE754 defines floating point numbers. The highest bit is used to define the sign with 0 being positive and 1 being negative.

Through a bit of digging, double.NaN seems to be represented as 0xFFF8000000000000 in binary (and 0.0 / 0.0 in code somehow).

double.IsNegative(double d) just checks the highest bit without any actual math being involved. Therefor, NaN is interpreted as a negative value. Meanwhile, double.NaN if used in a binary comparison will always yield false:

double.NaN < 0.0  //false
double.NaN > 0.0  //false
double.NaN <= 0.0 //false
double.NaN >= 0.0 //false
double.NaN == 0.0 //false
like image 23
Jack T. Spades Avatar answered Oct 12 '22 00:10

Jack T. Spades