Java中的INFINITY常量是什么?

36

我最近刚了解原始类型包装类中的常量,例如Double.POSITIVE_INFINITYDouble.NEGATIVE_INFINITY。在API中,第一个的定义如下:

保持double类型正无穷大的常量。它等于Double.longBitsToDouble(0x7ff0000000000000L)返回的值。

其他常量的定义也是这样。

我遇到的问题是理解这些常量实际上是什么。它们不能实际上是或代表正/负无穷大,因为系统本质上是有限的。这只是Java创建者决定用来定义无限概念的一些任意位设置吗?还是这些常量实际上具有某种特殊的价值?如果它只是被解释为double的任意一串位,那么是否存在一些普通数字,当它被解释为double时,将返回POSITIVE_INFINITY而不是实际预期的任何值?

如果对于Double.longBitsToDouble(0x7ff0000000000000L)部分的API来说答案很明显,请原谅我。说实话,对我来说,那个说明相当神秘,我不会假装理解十六进制值实际上意味着什么或代表什么。

3个回答

22

Java 的浮点数基于 IEEE 754 二进制浮点标准《浮点数运算标准》。该标准的第一个版本发布于约 1985 年,因此比 Java 更为古老。由于时至 Java 定义时 IEEE 754 已经被广泛硬件实现,因此 Java 创造者别无选择。

每个 IEEE 754 浮点数有三个组成部分:一个符号位、一个指数和一个尾数。大体上来说,一个正常数的大小可以表示为:

 mantissa * (2 ** exponent)

其中 "**" 表示乘方。

最高位是符号位,在双精度浮点数中,接下来的 11 位是指数位。

所有指数位都为 1 的二进制模式被保留用于表示无穷大和 NaN(非数字)。所有正常数字在指数位上都至少有一个零位。两个无穷大由所有指数位和所有尾数位均为零来表示,而最前面的符号位区分了正无穷和负无穷。

选择将所有指数位都设为 1 的特殊情况并非任意。将极端值之一截断比处理数字范围中间的差距要容易得多,特别是对于硬件实现而言。如果将所有指数位都关掉,则无法使用所有指数位均为零的模式编码零,并且会赋予绝对值最大的数——无穷大——最小的指数,从而使硬件更加复杂。将所有指数位都设为 1 明显是表示无穷大最佳选择。

这两个无穷大都被用于表示两种东西,即实际上无限大的结果和在正常数字系统中无法表示的绝对值过大的结果,即大于 Double.MAX_VALUE 或小于 -Double.MAX_VALUE 的数字。1.0/0.0 是无穷大。2*Double.MAX_VALUE 也是。

有些算法可以通过允许中间结果为无穷来简化,并减少特殊情况的数量,以任意一种方式无限。这样做还允许例如与 y 轴平行的线具有可存储的梯度,可用于计算。


6
IEEE 754浮点数标准规定:
+ ∞ 和 -∞ 的值用指数全为1、小数部分全为0表示。符号位区分负无穷大和正无穷大。将无穷大表示为一个特定的值很有用,因为它允许操作在溢出情况下继续进行。使用无穷大值进行运算在IEEE浮点数中是良好定义的。
此外: "IEEE规定了特殊数字的操作。在最简单的情况下,任何NaN值的操作都会产生NaN结果。其他操作如下:"
      Operation         Result
        n ÷ ±Infinity   0
±Infinity × ±Infinity   ±Infinity
±nonzero  ÷ 0           ±Infinity
Infinity  + Infinity    Infinity
       ±0 ÷ ±0          NaN
 Infinity - Infinity    NaN
±Infinity ÷ ±Infinity   NaN
±Infinity × 0           NaN

2
n + ±Infinity = ±Infinity也成立吗? - caub
2
@caub 是的(除非n是与另一个加数相反类型的无穷大,否则结果将为NaN)。 - blubberdiblub

6

它们确实代表正无穷和负无穷,这些是在IEEE浮点数标准中明确定义的概念。例如,将正浮点数除以零会得到正无穷大。至于比特模式本身,它只是一个被选择来表示无限大的模式。


那个页面没有解释这些数字是否只是随意选择的一些随机数。 - tckmn
2
@PicklishDoorknob:我想,由于有很多位模式通常根据“主要”规则解释为0,他们认为可以将其中一些用于其他目的。我认为这个位模式没有任何其他意义,但我没有任何参考资料来证明这一点。 - Aasmund Eldhuset
你能解释一下你所说的“许多不同的比特模式会被解释为零”的意思吗?我认为唯一这样的比特模式是一串完全未设置的比特。 - asteri
在程序中,确实存在正零和负零,就双精度浮点数而言它们是不同的。 - Louis Wasserman
@Jeff:抱歉,我想错了。实际上,根据解释位的“主”规则(符号(1 +分数) 2 ^(指数-偏差)),_每个_位模式都表示一个非零数字。他们必须以某种方式表示零、无穷大和NaN,并选择通过“牺牲”最极端的指数值(由所有零和所有一组成的位模式)来决定例如所有零的指数和所有零的分数代表+/-0(取决于符号位)。 - Aasmund Eldhuset
@Jeff:(续)从某种意义上说,这是一个任意的选择(因为无论他们选择哪个位模式,都不会是“自然”的零的表示,因为零在上述公式中是无法表示的),但这是一个方便的(而且可能经过深思熟虑的)选择,因为被牺牲的位模式正好位于可表示数字集合的极端两端。 - Aasmund Eldhuset

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