Java 中的 INFINITY 常量到底是啥?

Posted

技术标签:

【中文标题】Java 中的 INFINITY 常量到底是啥?【英文标题】:What are the INFINITY constants in Java, really?Java 中的 INFINITY 常量到底是什么? 【发布时间】:2012-10-30 07:59:54 【问题描述】:

我最近刚刚遇到了基本类型包装类中的常量,例如Double.POSITIVE_INFINITYDouble.NEGATIVE_INFINITY。在 API 中,它将第一个定义为:

一个保持双精度正无穷大的常数。它等于 Double.longBitsToDouble(0x7ff0000000000000L) 返回的值。

其他人也有类似的定义。

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

鉴于 API 的 Double.longBitsToDouble(0x7ff0000000000000L) 部分,如果这个问题的答案很明显,请原谅我。老实说,这种描述对我来说非常神秘,我不会假装理解十六进制值的实际含义或代表什么。

【问题讨论】:

【参考方案1】:

它们确实代表正无穷和负无穷,这是IEEE floating point standard 中明确定义的概念。例如,将正浮点数除以零会产生正无穷大。至于位模式本身,它只是一种被选择来代表无穷大的模式。

【讨论】:

该页面没有解释它们是否只是一些随机任意选择的数字...... @PicklishDoorknob:我想,由于根据解释位的“主要”规则,有很多位模式通常会被解释为 0,他们认为他们可以使用其中的一些用于其他目的。我认为位模式没有任何其他意义,但我对此没有任何参考。 您能解释一下您所说的“许多不同的位模式将被解释为零”是什么意思吗?我认为唯一这样的位模式是一串完全未设置的位? 嗯,肯定有正零和负零,就双打而言,它们是不同的。 @Jeff:对不起;我的想法不好。实际上,根据解释位的“主要”规则(符号 *(1 + 分数)* 2^(指数 - 偏差)),每个 位模式将表示一个非零数。他们必须以某种方式表示零、无穷大和 NaN,并选择通过“牺牲”最极端的指数值(由全零和全一组成的位模式)来做到这一点,并决定例如全零的指数和全零的一小部分表示 +/- 0(取决于符号位)。【参考方案2】:

IEEE Standard 754 Floating Point Numbers 声明:

“值 +infinity 和 -infinity 用全 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

【讨论】:

还有n + ±Infinity = ±Infinity? @caub 是(除非 n 是与另一个加数相反的 Infinity,在这种情况下结果将为 NaN)。【参考方案3】:

Java 浮点基于 IEEE 754 二进制浮点标准Floating Point Standard,其第一个版本大约在 1985 年发布,因此它比 Java 古老得多。鉴于在定义 Java 时 IEEE 754 的硬件实现广泛,Java 创建者别无选择。

每个 IEEE 754 浮点数都包含三个组成部分,一个符号位、一个指数和一个尾数。大大简化,正态数的大小为:

 mantissa * (2 ** exponent)

其中“**”代表权力。

前导位是符号位。在双精度中,接下来的 11 位是指数。

所有指数位都打开的位模式保留用于无穷大和 NaN。所有正常数在指数中至少有一个零位。这两个无穷大由所有指数位打开,所有尾数位为零来表示。前导符号位区分正无穷和负无穷。

对于特殊情况,所有指数位的选择不是任意的。砍掉一个极端比处理一系列数字中间的差距更容易,尤其是对于硬件实现。在特殊情况下取消所有位的指数会阻止使用所有位关闭模式编码零,并且会给出最大的绝对幅度值、无穷大、最小的指数,这也会使硬件更加复杂。指数上的所有位绝对是无穷大的最佳选择。

这两个无穷大都用来表示两个东西,实际上是无穷大的结果和绝对量级太大而无法在正常数系中表示的结果,大于 Double.MAX_VALUE 或小于 -Double.MAX_VALUE 的数字。 1.0/0.0 是无限的。 2*Double.MAX_VALUE 也是如此。

有一些算法可以简化,减少特殊情况,允许中间结果在任何一种意义上都是无限的。这样做还允许例如甚至一条平行于 y 轴的线,以具有可用于计算的可存储梯度。

【讨论】:

以上是关于Java 中的 INFINITY 常量到底是啥?的主要内容,如果未能解决你的问题,请参考以下文章

Java I/O 中的“Stream”和“Buffer”到底是啥意思?

数组的存储方式是啥?

Java 中的实例到底是啥?

Java中的Double到底是啥意思?

Java中的上下文到底是啥? [复制]

Java中的上下文到底是啥? [复制]