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