NaN in Java – Java中的NaN

最后修改: 2018年 5月 23日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

Simply put, NaN is a numeric data type value which stands for “not a number”.

简单地说,NaN是一个数字数据类型值,代表 “不是一个数字”。

In this quick tutorial, we’ll explain the NaN value in Java and the various operations that can produce or involve this value.

在这个快速教程中,我们将解释Java中的NaN值,以及可以产生或涉及该值的各种操作。

2. What Is NaN?

2.什么是NaN

NaN usually indicates the result of invalid operations. For example, attempting to divide zero by zero is one such operation.

NaN通常表示无效操作的结果。例如,试图用零除以零就是这样的一个操作。

We also use NaN for unrepresentable values. The square root of -1 is one such case, as we can describe the value (i) only in complex numbers.

我们也用NaN来表示不可表示的值。-1的平方根就是这样一种情况,因为我们只能用复数来描述这个值(i)。

The IEEE Standard for Floating-Point Arithmetic (IEEE 754) defines the NaN value. In Java, the floating-point types float and double implement this standard.

IEEE浮点运算标准(IEEE 754)定义了NaN值。在Java中,浮点类型floatdouble实现了这个标准。

Java defines NaN constants of both float and double types as Float.NaN and Double.NaN:

Java定义了floatdouble类型的NaN常量,即Float.NaNDouble.NaN

A constant holding a Not-a-Number (NaN) value of type double. It is equivalent to the value returned by Double.longBitsToDouble(0x7ff8000000000000L).”

一个持有双倍类型的非数字(NaN)值的常数。它相当于Double.longBitsToDouble(0x7ff8000000000000L)所返回的值。”

and:

和。

“A constant holding a Not-a-Number (NaN) value of type float. It is equivalent to the value returned by Float.intBitsToFloat(0x7fc00000).”

“一个持有浮动类型的非数字(NaN)值的常数。它相当于Float.intBitsToFloat(0x7fc00000)所返回的值。”

We don’t have this type of constants for other numeric data types in Java.

在Java中的其他数字数据类型,我们没有这种类型的常量。

3. Comparisons with NaN

3.与NaN的比较

While writing methods in Java, we should check that the input is valid and within the expected range. NaN value is not a valid input in most cases. Therefore, we should verify that the input value is not a NaN value and handle these input values appropriately.

在Java中编写方法时,我们应该检查输入是否有效,是否在预期范围内。NaN值在大多数情况下不是一个有效的输入。因此,我们应该验证输入值是否为NaN值,并适当地处理这些输入值。

NaN cannot be compared with any floating type value. This means that we’ll get false for all comparison operations involving NaN (except “!=” for which we get true).

NaN不能与任何浮动类型的值进行比较。这意味着在所有涉及NaN的比较操作中,我们将得到false(除了”!=”,我们得到true)。

We get true for “x != x” if and only if x is NaN:

当且仅当xNaN:时,我们得到的”x != x”

System.out.println("NaN == 1 = " + (NAN == 1));
System.out.println("NaN > 1 = " + (NAN > 1));
System.out.println("NaN < 1 = " + (NAN < 1));
System.out.println("NaN != 1 = " + (NAN != 1));
System.out.println("NaN == NaN = " + (NAN == NAN));
System.out.println("NaN > NaN = " + (NAN > NAN));
System.out.println("NaN < NaN = " + (NAN < NAN));
System.out.println("NaN != NaN = " + (NAN != NAN));

Let’s have a look at the result of running the code above:

让我们看一下运行上述代码的结果。

NaN == 1 = false
NaN > 1 = false
NaN < 1 = false
NaN != 1 = true
NaN == NaN = false
NaN > NaN = false
NaN < NaN = false
NaN != NaN = true

Hence, we cannot check for NaN by comparing with NaN using “==” or “!= “. In fact, we should rarely use “==” or “!= ” operators with float or double types.

因此,我们不能通过使用”==”或”!=”与NaN进行比较来检查NaN事实上,我们应该很少对floatdouble类型使用”==”或”!=”运算符。

Instead, we can use the expression “x != x”. This expression returns true only for NAN.

相反,我们可以使用表达式”x != x”这个表达式只对NAN.返回真。

We can also use the methods Float.isNaN and Double.isNaN to check for these values. This is the preferred approach as it’s more readable and understandable:

我们也可以使用Float.isNaNDouble.isNaN方法来检查这些值这是首选的方法,因为它更具可读性和可理解性。

double x = 1;
System.out.println(x + " is NaN = " + (x != x));
System.out.println(x + " is NaN = " + (Double.isNaN(x)));
        
x = Double.NaN;
System.out.println(x + " is NaN = " + (x != x));
System.out.println(x + " is NaN = " + (Double.isNaN(x)));

We’ll get the following result when running this code:

运行这段代码时,我们会得到以下结果。

1.0 is NaN = false
1.0 is NaN = false
NaN is NaN = true
NaN is NaN = true

4. Operations Producing NaN

4.生产NaN的操作

While doing operations involving float and double types, we need to be aware of the NaN values.

在进行涉及floatdouble类型的操作时,我们需要注意NaN值。

Some floating-point methods and operations produce NaN values instead of throwing an Exception. We may need to handle such results explicitly.

一些浮点方法和操作会产生NaN值,而不是抛出Exception。我们可能需要明确地处理这样的结果。

A common case resulting in not-a-number values are mathematically undefined numerical operations:

导致非数字值的一个常见情况是数学上未定义的数字运算

double ZERO = 0;
System.out.println("ZERO / ZERO = " + (ZERO / ZERO));
System.out.println("INFINITY - INFINITY = " + 
  (Double.POSITIVE_INFINITY - Double.POSITIVE_INFINITY));
System.out.println("INFINITY * ZERO = " + (Double.POSITIVE_INFINITY * ZERO));

These examples result in the following output:

这些例子的输出结果如下。

ZERO / ZERO = NaN
INFINITY - INFINITY = NaN
INFINITY * ZERO = NaN

Numerical operations which don’t have results in real numbers also produce NaN:

没有实数结果的数字运算也会产生NaN:

System.out.println("SQUARE ROOT OF -1 = " + Math.sqrt(-1));
System.out.println("LOG OF -1 = " +  Math.log(-1));

These statements will result in:

这些声明将导致。

SQUARE ROOT OF -1 = NaN
LOG OF -1 = NaN

All numeric operations with NaN as an operand produce NaN as a result:

所有以NaN为操作数的数字运算都会产生NaN的结果。

System.out.println("2 + NaN = " +  (2 + Double.NaN));
System.out.println("2 - NaN = " +  (2 - Double.NaN));
System.out.println("2 * NaN = " +  (2 * Double.NaN));
System.out.println("2 / NaN = " +  (2 / Double.NaN));

And the result of the above is:

而上述的结果是。

2 + NaN = NaN
2 - NaN = NaN
2 * NaN = NaN
2 / NaN = NaN

Finally, we cannot assign null to double or float type variables. Instead, we may explicitly assign NaN to such variables to indicate missing or unknown values:

最后,我们不能将null分配给doublefloat型变量。相反,我们可以明确地将NaN分配给这类变量,以表示缺失或未知的值。

double maxValue = Double.NaN;

5. Conclusion

5.总结

In this article, we discussed NaN and the various operations involving it. We also discussed the need to handle NaN while doing floating-point computations in Java explicitly.

在这篇文章中,我们讨论了NaN和涉及它的各种操作。我们还讨论了在Java中进行浮点计算时需要明确处理NaN的问题。

The full source code can be found over on GitHub.

完整的源代码可以在GitHub上找到over