为什么代表 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.02.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.02.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(十进制表示)会导致所有数字发生变化一样。