float 或 double 的 NaN 和 Infinity 如何存储在内存中?

How are NaN and Infinity of a float or double stored in memory?

据我了解,java 会将浮点数作为具有以下属性的 32 位整数存储在内存中:

这三种特殊情况没有多余的位:

我猜想负 0 可以用来存储其中之一。

这些在内存中实际是如何表示的?

Wikipedia中所述,所有位都设置为 1 的指数用于标识这些数字。设置为 0 的小数字段用于标识无穷大(正或负,由符号标识),非零小数字段标识 NaN 值。

来自here

Q. How are zero, infinity and NaN represented using IEEE 754?

A. By setting all the exponent bits to 1. Positive infinity = 0x7ff0000000000000 (all exponent bits 1, sign bit 0 and all mantissa bits 0), negative infinity = 0xfff0000000000000 (all exponent bits 1, sign bit 1 and all mantissa bits 0), NaN = 0x7ff8000000000000 (all exponent bits 1, at least one mantissa bit set). Positive zero = all bits 0. Negative zero = all bits 0, except sign bit which is 1.

另请参阅有关 NAN, Positive Infinity and Negative Infinity 的 Javadocs。

Java 指定浮点数遵循 IEEE 754 标准。

这是它的存储方式:

  • 第 0 位:符号位
  • 位 1 到 11:指数
  • 位 12 到 63:小数

现在,我已经用不同的 double 值执行了以下方法:

public static void print(double d){
    System.out.println(Long.toBinaryString(Double.doubleToRawLongBits(d)));
}

我使用这些值执行:

print(Double.NaN);
print(Double.NEGATIVE_INFINITY);
print(Double.POSITIVE_INFINITY);
print(-Double.MAX_VALUE);
print(Double.MAX_VALUE);

并针对上述值得到以下输出(为了便于阅读而格式化):

 NaN: 0111111111111000000000000000000000000000000000000000000000000000
-Inf: 1111111111110000000000000000000000000000000000000000000000000000
+Inf: 0111111111110000000000000000000000000000000000000000000000000000
-Max: 1111111111101111111111111111111111111111111111111111111111111111
+Max: 0111111111101111111111111111111111111111111111111111111111111111

Wikipedia explains当指数字段为全位1时,该数要么为Inf,要么为NaN。 Inf 的尾数全部为零; NaN 的尾数中至少有一位设置为 1。符号位保留其对 Inf 的正常含义,但对 NaN 没有意义。 Java 的 Double.NaN 是一个将被解释为 NaN 的特定值,但还有 253−3 个其他值。

Java 使用 IEEE 754 浮点数。

大多数数字以符号-指数-尾数格式表示,尾数隐含前导 1。

指数字段的极值(全零和全一)不用作正常指数值。相反,它们用于表示特殊情况。

指数字段中的所有零用于表示太小而无法以正常格式表示的数字(包括正零和负零)。

指数中全1用于表示特殊值。如果尾数中的所有位都是零,则该值是正负无穷大(符号由符号位指示)。否则值为 NaN。

首先我们要了解数字在内存中是如何表示为float point和double的。

一般数字的形式为:1.M * 2^e.

(其中M称为尾数,e是excess-127中的指数)

浮点数

MSB(Most significant bit)作为符号位,23到31的位数用于指数值,形式为excess-127,0到30的位数用于存储尾数。

双倍

MSB(Most significant bit)作为符号位,52到63的位数用于指数值,形式为excess-127,0到0的位数用于存储尾数.

所以现在我们可以理解 NaN,float 或 double 中的 Infinity 表示。

NaN(不是数字)

在NaN的表示中,所有的指数位都是1,尾数位可以是任何东西,它是浮点数还是十进制都没有关系。

无限

在Infinity的表示中,所有指数位都是1,尾数位都是0,它是浮点数还是十进制都没有关系。 positive Infinity 的表示方式与上面相同,但符号位为 0,negative infinity 的表示方式与上述相同,但符号位为 0在这里 1.