📜  Java中的 NaN(非数字)

📅  最后修改于: 2022-05-13 01:55:34.948000             🧑  作者: Mango

Java中的 NaN(非数字)

你能猜出以下代码片段的输出吗:

public class Test
{
    public static void main(String[] args)
    {
        System.out.println(2 % 0);
    }
}       

是的,你猜对了:ArithmeticException
输出:

Exception in thread "main" java.lang.ArithmeticException: / by zero
    at traps.Test.main(Test.java:3)

现在猜测 的输出:

public class Test
{
    public static void main(String[] args)
    {
        System.out.println(2.0 % 0);
    }
}       

你猜对了吗?
输出:

NaN


什么是南?

NaN ”代表“不是数字”。如果浮点运算有一些输入参数导致运算产生一些未定义的结果,则会产生“Nan”。例如, 0.0 除以 0.0在算术上是未定义的。找出负数的平方根也是未定义的。

//Java Program to illustrate NaN
public class Test
{
    public static void main(String[] args)
    {
        System.out.println(2.0 % 0);
        System.out.println(0.0 / 0);
        System.out.println(Math.sqrt(-1));
    }
}       

输出:

NaN
NaN
NaN

在 javadoc 中,常量字段 NaN 分别在 Float 和 Double 类中声明如下。

public static final float     NaN = 0f / 0f;
public static final double      NaN = 0d / 0d;

如何比较 NaN 值?

所有以 NaN 作为操作数的数值运算都会产生 NaN 作为结果。这背后的原因是 NaN 是无序的,因此涉及一个或两个 NaN 的数值比较操作返回 false。

  • 如果一个或两个操作数都是 NaN,则数值运算符和 >= 总是返回 false。(§15.20.1)
  • 如果任一操作数为 NaN,则相等运算符== 返回 false。
  • 如果任一操作数为 NaN,则不等式运算符!= 返回 true。 (§15.21.1)
// Java program to test relational operator on NaN
public class ComparingNaN
{
    public static void main(String[] args)
    {
        // comparing NaN constant field defined in
        // Float Class
        System.out.print("Check if equal :");
        System.out.println(Float.NaN == Float.NaN);
          
        System.out.print("Check if UNequal: ");
        System.out.println(Float.NaN != Float.NaN);
  
        // comparing NaN constant field defined in Double Class
        System.out.print("Check if equal: ");
        System.out.println(Double.NaN == Double.NaN);
          
        System.out.print("Check if UNequal: ");
        System.out.println(Double.NaN != Double.NaN);
  
  
        // More Examples
        double NaN = 2.1 % 0;
        System.out.println((2.1%0) == NaN);
        System.out.println(NaN == NaN);
    }
}

输出:

Check if equal :false
Check if UNequal: true
Check if equal: false
Check if UNequal: true
false
false

isNaN() 方法

如果此对象表示的值为 NaN,则此方法返回 true;否则为假。

import java.lang.*;
  
public class isNan
{
  
   public static void main(String[] args)
   {
  
     Double x = new Double(-2.0/0.0);
     Double y = new Double(0.0/0.0);
       
       
     // returns false if this Double value is not a Not-a-Number (NaN) 
     System.out.println(y + " = " + y.isNaN());
    
     // returns true if this Double value is a Not-a-Number (NaN) 
     System.out.println(x + " = " + x.isNaN());
    
   }
} 

输出:

NaN = true
-Infinity = false

使用数学值操作时,浮点类型不会产生异常

IEEE 754 浮点数可以表示正无穷或负无穷,以及 NaN(不是数字)。这三个值来自结果未定义或无法准确表示的计算。
Java遵循已知的数学事实。 1.0 / 0.0 是无穷大,但其他是不确定的形式, Java表示为 NaN(不是数字)。

// Java program to illustrate output of floating
// point number operations
public class Test
{
    public static void main(String[] args)
    {
        System.out.println(2.0 / 0);
        System.out.println(-2.0 / 0);
        System.out.println(9.0E234 / 0.1E-234);
    }
}

输出:

Infinity
-Infinity
Infinity

参考:
https://docs.oracle.com/javase/7/docs/api/java Java
https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html