#1,096 – Floating Point NaN Values

We’ve seen that floating point numbers can represent approximations of real number values, positive and negative zero values, and positive and negative infinity.

A floating point variable or memory location can also represent a value that is “Not a Number”, normally denoted by the keyword NaN.  A NaN value is a floating point value that is a result of a calculation that leads to a value that is not a real number or a positive or negative infinity value.

NaN values are used when it’s useful to capture the fact that a calculation led to a value that is not a valid numerical result.

Below are some examples of calculations that can lead to NaN values.  Note that we can use float.IsNaN to check for this value.

            float zeroOverZero = 0.0f / 0.0f;
            float zeroTimesInfinity = 0.0f * float.PositiveInfinity;
            float InfinityCalc = float.PositiveInfinity + float.NegativeInfinity;

            double rootNegOne = Math.Sqrt(-1.0);

1096-001

Advertisements

#79 – Equality Checks for NaN

You should use the float and double static methods for checking for NaN values (E.g. float.isNaN), rather than using the equality operator.  The equality operator will not work to compare a value against double.NaN and float.NaN.

 // Easiest way--use static method
 bool b1 = double.IsNaN(0.0 / 0.0);     // true

 // == operator doesn't work
 bool b2 = (0.0 / 0.0) == double.NaN;   // false !

 // object.Equals does work
 bool b3 = object.Equals(0.0 / 0.0, double.NaN);

#78 – Checking for Special Floating Point Values

You can check a float or double in C# to see if it has one of the following special values: Infinity, Negative Infinity, or Not-a-Number (NaN).

 float f1 = 0.0f / 0.0f;        // NaN
 float f2 = 1.0f / 0.0f;        // Infinity
 float f3 = -1.0f / 0.0f;       // -Infinity

 Console.WriteLine(float.IsNaN(f1));     // True
 Console.WriteLine(float.IsInfinity(f2));  // True
 Console.WriteLine(float.IsPositiveInfinity(f2));    // True
 Console.WriteLine(float.IsNegativeInfinity(f3));    // True

The float and double classes also have static fields that let you set special values directly.

 // Setting special values
 float f1 = float.NaN;
 float f2 = float.PositiveInfinity;
 float f3 = float.NegativeInfinity;

#77 – Special Floating Point Values

In C#, the float and double types can represent regular floating point values as well as a handful of special values:

  • Positive and negative zero
  • Positive and negative infinity
  • Not-a-Number value (NaN)

Floating point types can represent both positive and negative zero values.  In most cases, the two different zero values are indistinguishable.  When converting to string, both will result in “0”.  Internally, in memory, however, a negative zero will have its sign bit set.

 float f1 = 1.0f * 0.0f;    // Positive zero - 0x00000000
 float f2 = -1.0f * 0.0f;   // Negative zero - 0x00000080  (sign bit set)

Negative and positive values for infinity are also part of the IEEE spec for floating-point arithmetic.

 float f1 = 1.0f / 0.0f;    // Infinity  - 0x0000807F
 float f2 = -1.0f / 0.0f;   // -Infinity - 0x000080FF

The Not-a-Number (NaN) value indicates an unrepresentable number.

 float f1 = 0.0f / 0.0f;        // NaN - 0x0000C0FF
 double d1 = Math.Sqrt(-1.0);   // NaN - 0x000000000000F8FF