35

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

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

其他人也有同样的定义。

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

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

4

3 回答 3

21

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轴的线具有可用于计算的可存储梯度。

于 2012-11-10T00:40:39.560 回答
6

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

于 2012-11-09T23:36:21.320 回答
5

IEEE 标准 754 浮点数规定:

“值 +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
于 2012-11-09T23:37:46.090 回答