User Oleksandr Miadelets
Oleksandr Miadelets
Head of Developers Team at CodeGym

NaN in Java

Published in the Random group
In Java, “NaN” stands for “Not a Number”. It is not a type of exception, rather surprisingly, the datatype of NaN is also a number. But often when novice programmers get it unintentionally, they further use it in their calculations. Hence, incompatible data types in Java when used together can cause a throwable error. It is also commonly seen that java.lang.ArithmeticException: / by zero is considered the same as NaN. However, Java treats them both differently. Puzzling enough? For your comprehensive understanding we’ll dissect how these are different from one another. By the end of this article you’ll learn about the possible operations producing not a number (nan), and some easy ways to handle it.

What is NaN?

So, what is NaN? “NaN” as many of you have guessed, is used to represent “Not a Number” in Java. It is a special floating point value to denote overflows and errors. It is generated when a floating point number is divided by zero or if the square root of a negative number is computed. NaN in Java - 1For example, have a look at the following snippet.

public class NaN
{
    public static void main(String[]args)
    {
        System.out.println(0.0 / 0.0);	  //zero divided by zero
        System.out.println(Math.sqrt(-1)); //take sqrt of negative number
        System.out.println(10.0 % 0);      //taking mod by zero	
    }
}
Output

NaN                                                                                                                                           
NaN                                                                                                                                           
NaN
In the snippet above, you can observe that NaN is produced as a result of 3 simple operations:
  • Dividing a float / double zero with zero.
  • Taking under-root of a negative number (Math.sqrt(-x)). In mathematics, taking the square root of a negative number results in an imaginary number. This case is dealt with by returning NaN in Java.
  • Taking mod of a number with zero, will return the remainder after dividing a value by zero. Hence, NaN is returned.

How NaN is Different from Positive and Negative Infinity?

According to IEEE 754 specification, there are three special floating-point & double values to handle the boundary cases:
  • Positive infinity
  • Negative infinity
  • NaN
The result of dividing a positive number by 0 is positive infinity. Similarly, negative infinity yields as a result of dividing a negative number with zero. Please note that all floating point values are applicable to data type double as well. The limited precision of floats is at times not sufficient. However, we’ll see how NaN works for both float and double in a later section.

What isNaN() Method?

isNaN() is one of the basic methods in Java to check if it is a NaN value or not. As we discussed three cases above, it’s time to test how isNaN() method differentiates between +infinity, -infinity and NaN values.

public class isNaN
{ public static void main(String[]args)
  { 
    Double posInfinity = +2.0 / 0.0;
    Double negInfinity = -3.5 / 0.0;
    Double nanVal = 50 % 0.0;


    System.out.println ("+" + posInfinity + ".IsNaN() = " + posInfinity.isNaN());
    System.out.println ( negInfinity + ".IsNaN() = " + negInfinity.isNaN());
    System.out.println ( nanVal +  ".IsNaN() = " + nanVal.isNaN());
  }
}
Output

+Infinity.IsNaN() = false                                                                                                                       
-Infinity.IsNaN() = false                                                                                                                       
NaN.IsNaN() = true

How to Compare NaN Values?

Every NaN value is considered distinct. This means, not a single NaN is equal to any other NaN. By this principle, If you compare one value to another the result is always negative. Since, NaN is unordered, so a numeric comparison involving even a single NaN returns false. Java provides Float.NaN and Double.NaN for constant fields in both classes to perform comparisons. We can differentiate these in two separate scenarios:
  • True: Only in case of In-equality (!=)
  • False: For all comparison operands (==, <=, >=, <, >)
Here’s a working example for you guys:

public class ComparingNaN
{ public static void main(String[] args)                                                                                                     
  {
    // Comparing NaN values for Float constants
    System.out.println (Float.NaN != Float.NaN); // true
    System.out.println (Float.NaN == Float.NaN); // false
    System.out.println (Float.NaN < Float.NaN);  // false
    System.out.println (Float.NaN > Float.NaN);  // false
    System.out.println (Float.NaN <= Float.NaN); // false
    System.out.println (Float.NaN >= Float.NaN); // false

    // Comparing NaN values for Float constants
    System.out.println (Double.NaN != Double.NaN); // true
    System.out.println (Double.NaN == Double.NaN); // false
    System.out.println (Double.NaN < Double.NaN);  // false
    System.out.println (Double.NaN > Double.NaN);  // false
    System.out.println (Double.NaN <= Double.NaN); // false
    System.out.println (Double.NaN >= Double.NaN); // false
  }
}

How to Generate NaN Values?

Before wrapping up, let’s look at some common examples of getting a Not a Number (nan).

public class GenerateNaNValues {  
  static final float ZERO = 0;
  public static void main (String[]args)
  {
    System.out.println("ZERO / ZERO = " + (ZERO / ZERO));
    System.out.println("+INFINITY - INFINITY = " + 
    (Float.POSITIVE_INFINITY + Float.NEGATIVE_INFINITY));
    System.out.println("-INFINITY * ZERO = " + (Float.NEGATIVE_INFINITY * ZERO));
    System.out.println("+INFINITY * ZERO = " + (Float.POSITIVE_INFINITY * ZERO));
    System.out.println("log10(-10) = " +  Math.log(-10));
    System.out.println("√-10 = " + Math.sqrt(-10));
    System.out.println("NaN + 10 = " + (Float.NaN + 10));
    System.out.println("NaN - 10 = " + (Float.NaN - 10));
    System.out.println("NaN * 10 = " + (Float.NaN * 10));
    System.out.println("NaN / 10 = " + (Float.NaN / 10));
    System.out.println("NaN + NaN = " + (Float.NaN + Float.NaN));
    System.out.println("NaN - NaN = " + (Float.NaN - Float.NaN));
    System.out.println("NaN * NaN = " + (Float.NaN * Float.NaN));
    System.out.println("NaN / NaN = " + (Float.NaN / Float.NaN));
  }
}
Output:

ZERO / ZERO = NaN                                                                                                                               
+INFINITY - INFINITY = NaN                                                                                                                      
-INFINITY * ZERO = NaN                                                                                                                          
+INFINITY * ZERO = NaN                                                                                                                          
log10(-10) = NaN                                                                                                                                
√-10 = NaN                                                                                                                                      
NaN + 10 = NaN                                                                                                                                    
NaN - 10 = NaN                                                                                                                                  
NaN * 10 = NaN                                                                                                                                  
NaN / 10 = NaN                                                                                                                                  
NaN + NaN = NaN                                                                                                                                 
NaN - NaN = NaN                                                                                                                                 
NaN * NaN = NaN                                                                                                                                 
NaN / NaN = NaN
NaN in Java - 2

Conclusion

After looking at the numerous operations producing NaN, you must be familiar with it now. It might puzzle you initially, but there is nothing complicated dealing with this. By developing a little habit of checking if a value is not NaN in double/floating point calculations can save you from a lot of hassle. Even if you forget this initially, it’s totally fine. You can always consult this article for minor troubleshooting. Creating compilable, error-free code in one go comes after years of experience. So let’s get our hands dirty in code, and build something great!
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION