float 或 double 的 NaN 和 Infinity 如何存储在内存中?
How are NaN and Infinity of a float or double stored in memory?
据我了解,java 会将浮点数作为具有以下属性的 32 位整数存储在内存中:
- 第一位用于判断符号
- 接下来的8位代表指数
- 后23位用来存放小数
这三种特殊情况没有多余的位:
- 南
- 正无穷大
- 负无穷大
我猜想负 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.
据我了解,java 会将浮点数作为具有以下属性的 32 位整数存储在内存中:
- 第一位用于判断符号
- 接下来的8位代表指数
- 后23位用来存放小数
这三种特殊情况没有多余的位:
- 南
- 正无穷大
- 负无穷大
我猜想负 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.