为什么代表 1.0 和 2.0 的位串如此不同?
Why are the bit strings representing 1.0 and 2.0 so different?
我最近开始使用 Julia 并发现了 bits
函数,它 returns 其数字参数的位串表示。例如:
julia> bits(1.0)
"0011111111110000000000000000000000000000000000000000000000000000"
然而,在使用这个函数时,我惊讶地发现 bits
returns 1.0
和 2.0
的位串非常不同:
julia> bits(1.0)
"0011111111110000000000000000000000000000000000000000000000000000"
julia> bits(2.0)
"0100000000000000000000000000000000000000000000000000000000000000"
我原以为这两个值是相似的...
这些位的含义是什么?我依稀记得一些关于对指数进行编码的位(来自我的数值分析class),但我真的不知道记得很清楚,我没能在网上找到一个好的描述...
要理解为什么 bits(1.0)
和 bits(2.0)
的 ASCIIString
值是 "so different",您需要了解一些 (!) 关于 IEEE-754 (binary) floating-point numbers. Each such double-precision 数字存储为 64 位字,分为三部分:
- 符号位(非负数为0,非正数为1),后跟
- biased exponent(11位),后面是
- 有效数(52 位)。
一个normalized number的值(比如1.0
和2.0
)可以用下面的公式得到:
(-1)^sign_bit x 1.significand x 2^(biased_exponent - bias)
(对于双精度浮点数,偏差值为 2^10 - 1 = 1023)
现在,
1.0 = +1.000... x 2^(1023 - 偏差)
而1023对应的是以2为底的(0)1111111111,所以对应的位串是
0 01111111111 0000000000000000000000000000000000000000000000000000
2.0 = +1.000... x 2^(1024 - 偏差)
而1024对应的是2进制的10000000000,所以对应的位串是
0 10000000000 0000000000000000000000000000000000000000000000000000
3.0 = +1.100... x 2^(1024 - 偏差)
所以对应的位串是
0 10000000000 1000000000000000000000000000000000000000000000000000
等等
综上所述,2.0
的位串可以通过将1.0
的位串中的偏指数部分递增得到,即2的幂减1。递增这样一个数字会导致其二进制表示的所有位发生变化,就像递增数字 9999(十进制表示)会导致所有数字发生变化一样。
我最近开始使用 Julia 并发现了 bits
函数,它 returns 其数字参数的位串表示。例如:
julia> bits(1.0)
"0011111111110000000000000000000000000000000000000000000000000000"
然而,在使用这个函数时,我惊讶地发现 bits
returns 1.0
和 2.0
的位串非常不同:
julia> bits(1.0)
"0011111111110000000000000000000000000000000000000000000000000000"
julia> bits(2.0)
"0100000000000000000000000000000000000000000000000000000000000000"
我原以为这两个值是相似的...
这些位的含义是什么?我依稀记得一些关于对指数进行编码的位(来自我的数值分析class),但我真的不知道记得很清楚,我没能在网上找到一个好的描述...
要理解为什么 bits(1.0)
和 bits(2.0)
的 ASCIIString
值是 "so different",您需要了解一些 (!) 关于 IEEE-754 (binary) floating-point numbers. Each such double-precision 数字存储为 64 位字,分为三部分:
- 符号位(非负数为0,非正数为1),后跟
- biased exponent(11位),后面是
- 有效数(52 位)。
一个normalized number的值(比如1.0
和2.0
)可以用下面的公式得到:
(-1)^sign_bit x 1.significand x 2^(biased_exponent - bias)
(对于双精度浮点数,偏差值为 2^10 - 1 = 1023)
现在,
1.0 = +1.000... x 2^(1023 - 偏差)
而1023对应的是以2为底的(0)1111111111,所以对应的位串是
0 01111111111 0000000000000000000000000000000000000000000000000000
2.0 = +1.000... x 2^(1024 - 偏差)
而1024对应的是2进制的10000000000,所以对应的位串是
0 10000000000 0000000000000000000000000000000000000000000000000000
3.0 = +1.100... x 2^(1024 - 偏差)
所以对应的位串是
0 10000000000 1000000000000000000000000000000000000000000000000000
等等
综上所述,2.0
的位串可以通过将1.0
的位串中的偏指数部分递增得到,即2的幂减1。递增这样一个数字会导致其二进制表示的所有位发生变化,就像递增数字 9999(十进制表示)会导致所有数字发生变化一样。