在 Java 中,“NaN”代表“不是数字”。这不是一种异常类型,令人惊讶的是,NaN 的数据类型也是一个数字。但往往当新手程序员无意中得到它时,他们会在计算中进一步使用它。因此,Java 中不兼容的数据类型一起使用时会导致可抛出的错误。通常也可以看到它
例如,看看下面的片段。
java.lang.ArithmeticException: / by zero
被认为与 NaN 相同。然而,Java 以不同的方式对待它们。够令人费解吗?为了您的全面理解,我们将剖析它们之间的区别。到本文结束时,您将了解可能产生非数字 (nan) 的操作,以及一些处理它的简单方法。
什么是南?
那么,NaN 是什么?许多人已经猜到“NaN”在 Java 中用来表示“非数字”。它是一个特殊的浮点值,用于表示溢出和错误。当浮点数除以零或计算负数的平方根时生成。
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
}
}
输出
NaN
NaN
NaN
在上面的代码片段中,您可以观察到 NaN 是 3 个简单操作的结果:
- 零除以
float / double
零。 - 取负数的根 (Math.sqrt(-x))。在数学中,对负数求平方根会得到一个虚数。这种情况通过在 Java 中返回 NaN 来处理。
- 用零取模,将返回一个值除以零后的余数。因此,返回 NaN。
NaN 与正无穷大和负无穷大有何不同?
根据 IEEE 754 规范,有三种特殊的浮点和双精度值来处理边界情况:- 正无穷大
- 负无穷大
- 钠盐
什么是 NaN() 方法?
isNaN()
是 Java 中检查它是否为 NaN 值的基本方法之一。正如我们上面讨论的三种情况,是时候测试 isNaN() 方法如何区分+infinity、-infinity和 NaN 值了。
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());
}
}
输出
+Infinity.IsNaN() = false
-Infinity.IsNaN() = false
NaN.IsNaN() = true
如何比较 NaN 值?
每个 NaN 值都被认为是不同的。这意味着,没有一个 NaN 等于任何其他 NaN。根据这一原则,如果将一个值与另一个值进行比较,结果总是负数。由于 NaN 是无序的,因此即使涉及单个 NaN 的数字比较也会返回 false。Java 为这两个类中的常量字段都提供了 Float.NaN 和 Double.NaN 来进行比较。我们可以在两个不同的场景中区分它们:- True:仅在不相等的情况下 (!=)
- False:对于所有比较操作数(==、<=、>=、<、>)
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
}
}
如何生成 NaN 值?
在结束之前,让我们看一下获取非数字 (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));
}
}
输出:
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
GO TO FULL VERSION