在 Java 中,NaN 是什么意思?

我有一个程序,试图缩小一个 double到一个理想的数字。我得到的输出是 NaN

NaN在 Java 中是什么意思?

304466 次浏览

不是一个 Java 的家伙,但在 JS 和其他语言中我使用它的“不是一个数字”,这意味着一些操作导致它成为一个无效的数字。

NaN = 非数字。

字面上的意思是“不是一个数字”。我怀疑你的转换过程出了问题。

看看 这个参考上的非数字部分

Not a valid floating-point value (e.g. the result of division by zero)

Http://en.wikipedia.org/wiki/nan

NaN的意思是“非数字”,是对浮点数进行未定义操作的结果,例如零除以零。(注意,虽然非零数除以零在数学中通常也是未定义的,但它不会导致 NaN,而是导致正无穷大或负无穷大)。

NaN的意思是“不是数字”它是一个特殊的浮点值,表示一个操作的结果没有被定义或者不能表示为一个实数。

有关此值的更多说明,请参见 here

摘自 这一页:

“ NaN”代表“不是数字”“ NaN” 如果一个浮点数 操作有一些输入参数 导致操作产生 一些未定义的结果。例如, 0.0除以0.0是算术上未定义的 负数也是未定义的。

NaN 代表不是一个数字。它用于表示任何数学上未定义的值。就像0.0除以0.0。 You can look here for more information: https://web.archive.org/web/20120819091816/http://www.concentric.net/~ttwang/tech/javafloat.htm

如果您需要更多的帮助,请在这里发布您的程序。

NaN means “不是一个数字” and is basically a representation of a special floating point value in the IEE754浮点数 standard. generally means that the value is something that cannot be expressed with a valid floating point number.

如果要转换的值是其他值,例如转换不表示数字的字符串,则转换将导致此值。

意思是不是数字。 It is a common representation for an impossible numeric value in many programming languages.

最小可运行示例

您必须知道的第一件事是 NaN 的概念是直接在 CPU 硬件上实现的。

All major modern CPUs seem to follow IEEE 754 which specifies floating point formats, and NaNs, which are just special float values, are part of that standard.

Therefore, the concept will be the very similar across any language, including Java which just emits floating point code directly to the CPU.

在继续之前,你可能想先读一下我写的以下答案:

现在来做一些 Java 动作。不在核心语言中的大多数感兴趣的函数都存在于 java.lang.Float中。

Nan.java

import java.lang.Float;
import java.lang.Math;


public class Nan {
public static void main(String[] args) {
// Generate some NaNs.
float nan            = Float.NaN;
float zero_div_zero  = 0.0f / 0.0f;
float sqrt_negative  = (float)Math.sqrt(-1.0);
float log_negative   = (float)Math.log(-1.0);
float inf_minus_inf  = Float.POSITIVE_INFINITY - Float.POSITIVE_INFINITY;
float inf_times_zero = Float.POSITIVE_INFINITY * 0.0f;
float quiet_nan1     = Float.intBitsToFloat(0x7fc00001);
float quiet_nan2     = Float.intBitsToFloat(0x7fc00002);
float signaling_nan1 = Float.intBitsToFloat(0x7fa00001);
float signaling_nan2 = Float.intBitsToFloat(0x7fa00002);
float nan_minus      = -nan;


// Generate some infinities.
float positive_inf   = Float.POSITIVE_INFINITY;
float negative_inf   = Float.NEGATIVE_INFINITY;
float one_div_zero   = 1.0f / 0.0f;
float log_zero       = (float)Math.log(0.0);


// Double check that they are actually NaNs.
assert  Float.isNaN(nan);
assert  Float.isNaN(zero_div_zero);
assert  Float.isNaN(sqrt_negative);
assert  Float.isNaN(inf_minus_inf);
assert  Float.isNaN(inf_times_zero);
assert  Float.isNaN(quiet_nan1);
assert  Float.isNaN(quiet_nan2);
assert  Float.isNaN(signaling_nan1);
assert  Float.isNaN(signaling_nan2);
assert  Float.isNaN(nan_minus);
assert  Float.isNaN(log_negative);


// Double check that they are infinities.
assert  Float.isInfinite(positive_inf);
assert  Float.isInfinite(negative_inf);
assert !Float.isNaN(positive_inf);
assert !Float.isNaN(negative_inf);
assert one_div_zero == positive_inf;
assert log_zero == negative_inf;
// Double check infinities.


// See what they look like.
System.out.printf("nan            0x%08x %f\n", Float.floatToRawIntBits(nan           ), nan           );
System.out.printf("zero_div_zero  0x%08x %f\n", Float.floatToRawIntBits(zero_div_zero ), zero_div_zero );
System.out.printf("sqrt_negative  0x%08x %f\n", Float.floatToRawIntBits(sqrt_negative ), sqrt_negative );
System.out.printf("log_negative   0x%08x %f\n", Float.floatToRawIntBits(log_negative  ), log_negative  );
System.out.printf("inf_minus_inf  0x%08x %f\n", Float.floatToRawIntBits(inf_minus_inf ), inf_minus_inf );
System.out.printf("inf_times_zero 0x%08x %f\n", Float.floatToRawIntBits(inf_times_zero), inf_times_zero);
System.out.printf("quiet_nan1     0x%08x %f\n", Float.floatToRawIntBits(quiet_nan1    ), quiet_nan1    );
System.out.printf("quiet_nan2     0x%08x %f\n", Float.floatToRawIntBits(quiet_nan2    ), quiet_nan2    );
System.out.printf("signaling_nan1 0x%08x %f\n", Float.floatToRawIntBits(signaling_nan1), signaling_nan1);
System.out.printf("signaling_nan2 0x%08x %f\n", Float.floatToRawIntBits(signaling_nan2), signaling_nan2);
System.out.printf("nan_minus      0x%08x %f\n", Float.floatToRawIntBits(nan_minus     ), nan_minus     );
System.out.printf("positive_inf   0x%08x %f\n", Float.floatToRawIntBits(positive_inf  ), positive_inf  );
System.out.printf("negative_inf   0x%08x %f\n", Float.floatToRawIntBits(negative_inf  ), negative_inf  );
System.out.printf("one_div_zero   0x%08x %f\n", Float.floatToRawIntBits(one_div_zero  ), one_div_zero  );
System.out.printf("log_zero       0x%08x %f\n", Float.floatToRawIntBits(log_zero      ), log_zero      );


// NaN comparisons always fail.
// Therefore, all tests that we will do afterwards will be just isNaN.
assert !(1.0f < nan);
assert !(1.0f == nan);
assert !(1.0f > nan);
assert !(nan == nan);


// NaN propagate through most operations.
assert Float.isNaN(nan + 1.0f);
assert Float.isNaN(1.0f + nan);
assert Float.isNaN(nan + nan);
assert Float.isNaN(nan / 1.0f);
assert Float.isNaN(1.0f / nan);
assert Float.isNaN((float)Math.sqrt((double)nan));
}
}

GitHub 上游。

运行与:

javac Nan.java && java -ea Nan

产出:

nan            0x7fc00000 NaN
zero_div_zero  0x7fc00000 NaN
sqrt_negative  0xffc00000 NaN
log_negative   0xffc00000 NaN
inf_minus_inf  0x7fc00000 NaN
inf_times_zero 0x7fc00000 NaN
quiet_nan1     0x7fc00001 NaN
quiet_nan2     0x7fc00002 NaN
signaling_nan1 0x7fa00001 NaN
signaling_nan2 0x7fa00002 NaN
nan_minus      0xffc00000 NaN
positive_inf   0x7f800000 Infinity
negative_inf   0xff800000 -Infinity
one_div_zero   0x7f800000 Infinity
log_zero       0xff800000 -Infinity

从中我们学到了一些东西:

在 Ubuntu 18.10 amd64,OpenJDK 1.8.0 _ 191中测试。