这三个特殊的浮点数值是什么意思:正无穷大、负无穷大和NaN?

13

我们如何在代码中使用它们,以及什么会导致NaN(不是数字)的出现?

6个回答

16
  • 正无穷表示朝着正方向趋于无穷大 - 越来越接近于正方向中绝对值更大的值。
  • 负无穷表示朝着负方向趋于无穷大 - 越来越接近于负方向中绝对值更大的值。
  • 非数字 (NaN) 表示未定义,例如 0/0 的结果。

以下是 Float 类规范中的常量:

更多信息可以在 维基百科的 IEEE-754 页面 中找到。

这里有一个小程序来说明这三个常量:

System.out.println(0f / 0f);
System.out.println(1f / 0f);
System.out.println(-1f / 0f);

输出:

NaN
Infinity
-Infinity

但我认为1/0会导致正无穷大 :-? - Johanna
是的,你说得对--那是我的错误,并已经修复。 - coobird

13

这里是一个很好的参考,如果你想了解Java中浮点数的更多知识。

正无穷大是一个太大以至于无法正常表示的正数。负无穷大是一个太小以至于无法正常表示的负数。NaN表示“不是数字”,并且由于数学运算无法产生数字,例如将0除以0所得到。

在Java中,Double和Float类都有用于表示这三种情况的常量。它们是POSITIVE_INFINITY、NEGATIVE_INFINITY和NaN。

另外,请考虑以下内容:

double a = Math.pow(10, 600) - Math.pow(10, 600); //==NaN

从数学上讲,每个人都可以看出它是0。但对于机器来说,它是一个“无穷大减去无穷大”(同等级),这实际上是NaN。


我试图修复这个损坏的链接,但它被拒绝了。这里是一个非常好的资源,还包括一个QA部分,提供了进一步探索的链接。 - Michael Hogenson
我不同意(在这里和其他地方)将正无穷大表述为“一个不能被正常表示的数字”的描述。它可以是一个无法用正常浮点数表示的如此巨大的数字,但实际上通常源于类似于5f / 0f之类的东西,它并不是一个大的(实数)数字;它是无知版本的无穷大。(技术上,+inf,-inf和NaN是对实数的扩展,提供对任何算术操作的闭包,但代价是违反基本的场公理。这对计算机科学家来说并不重要,但对数学家来说很重要)。 - Peter Webb
@PeterWebb:NaN的定义不幸地不仅是未排序的,而且还不等于自身,这意味着floatdouble不仅违反了字段公理 - 它们甚至不是等价类。这不仅仅是数学家感兴趣的问题,因为它强制使用丑陋的修补程序使集合工作。 - supercat
@PeterWebb 实际上,即使没有±inf/NaN,“float”、“double”等也违反了场公理,即结合律。无论如何,它们都不应该是想要使用真实实数进行计算的数学家的基本构建块——对于这些人来说,有可以使用精确数字的计算机代数系统。 - Ruslan

3
  • 1/0的结果为正无穷。
  • 0/0的结果为NaN。您可以像处理其他数字一样处理NaN,例如:NaN + NaN = NaN,NaN + 2.0 = NaN。
  • -1/0的结果为负无穷。

Infinity(在Java中)意味着操作的结果将是一个极其大的正数或负数,无法正常表示。


2

这个概念是用来表示可以从“普通”数字运算自然产生的特殊数字。您可以将无穷大(正负)视为浮点表示的“溢出”,其想法是在至少某些条件下,函数返回此类值仍然会给出有意义的结果。它们仍具有某些排序属性,例如(因此它们不会破坏排序操作,例如)。

Nan非常特殊:如果x是Nan,则x == x为false(这实际上是一种测试nan的方法,至少在C中)。如果您不习惯浮点奇特性,这可能会相当困惑。除非进行科学计算,否则我会说通过操作返回Nan是一个错误,至少在我能想到的大多数情况下。Nan可能来自各种操作:0/0,inf-inf,inf/inf,0 * inf。 Nan也没有任何排序属性。


0

您可以像使用其他数字一样使用它们:

e.g:

float min = Float.NEGATIVE_INFINITY;
float max = Float.POSITIVE_INFINITY;
float nan = Float.NaN;

0
正无穷大是一个正数,它太大了以至于不能被正常表示。负无穷大是一个负数,它太小了以至于不能被正常表示。NaN意味着“不是一个数字”,并且是由于数学运算无法产生数字而导致的,比如将0除以0。这只是部分答案(或者没有解释清楚)- 请考虑这一点:
double a = Math.pow(10,600) - Math.pow(10,600); //==NaN

从数学上讲,每个人都可以看到它是0。但对于机器来说,它是一个“无穷大” - “无穷大”(同阶)的结果,实际上是NaN...


1
如果引用答案,最好将其留作评论或建议进行编辑。答案应该能够独立存在。 - chrisbajorin
好的,我不知道我可以编辑别人的帖子...就像 Git :) - Alex

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接