浮点数或双精度的NaN和无穷大如何存储在内存中?

2022-09-01 01:56:26

据我所知,java将在内存中存储一个浮点数作为32位整数,具有以下属性:

  • 第一位用于确定符号
  • 接下来的 8 位表示指数
  • 最后23位用于存储分数

这为三种特殊情况留下了任何多余的位:

  • 正无穷大
  • 负无穷大

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

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


答案 1

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

这是它的存储方式:

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

现在,我已经用不同的双精度值执行了下面的方法:

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

维基百科解释说,当指数字段为全位-1时,数字为Inf或NaN。Inf 具有尾数的所有位零;NaN 在尾数中至少有一个位设置为 1。符号位对 Inf 保留其正常含义,但对 NaN 没有意义。Java是一个将被解释为NaN的特定值,但还有其他253-3个。Double.NaN


答案 2

从这里

Q.如何使用 IEEE 754 表示零、无穷大和 NaN?

一个。将所有指数位设置为 1。正无穷大 = 0x7ff0000000000000(所有指数位 1,符号位 0 和所有尾数位 0),负无穷大 = 0xfff0000000000000(所有指数位 1,符号位 1 和所有尾数位 0),NaN = 0x7ff8000000000000(所有指数位 1,至少一个尾数位集)。正零 = 所有位 0。负零 = 所有位 0,符号位除外,即 1。

另请参阅有关 NAN、正无穷大和负无穷大的 Javadocs。