双精度数的 C++ 位表示

Nat*_*e K 4 c++ compression double ieee-754

我的理解是,双精度数是根据C++中的IEEE 754-2008标准存储的,其中第一位是符号,后面的11位是指数,其余52位是分数。然而,下面的代码+输出显示了其他内容。

代码

#include <bitset>
#include <iostream>

int main() {
    
    double value_float = 1.5;
    uint64_t value_uint = 0;


    std::memcpy(&value_uint, &value_float, 8);
    std::cout << value_uint << std::endl;

    std::bitset<64>doubleBitset(value_uint);
    std::cout << "DoubleBitset for " << value_float << " is: ";
    std::cout << doubleBitset << std::endl;

}
Run Code Online (Sandbox Code Playgroud)

输出:DoubleBitset for 1.5 is: 0011111111111000000000000000000000000000000000000000000000000000

为什么没有输出0b0 - 00000000001 1000000000000000000000000000000000000000000000000000;

Lal*_*5th 8

存储double有偏差的指数。这意味着本质上它被存储为无符号整数,并且每当使用它时1023都会被减去。这本质上意味着正数将设置其第一位,而0仅该位未设置。Wiki 文章对该标准进行了很好的概述。

回到问题,如果我们手动计算表示,我们会​​得到:1)第一位是0正数。2) 指数需要如此,0因此将其设置0b01111111111为代表0指数。3) 尾数将是您所期望的,即在开始处设置一位,然后是 51 个零。

编辑:正如评论中所指出的,在某些情况下指数有一些特殊含义。如果指数为2047则如果所有尾数为0则它代表Inf-Inf。如果尾数不全0是前一种情况,则该值为NaN。为了表示零,尾数也必须0带有指数。0我喜欢将这些视为特殊情况而不是代码,因为其中大多数都以双精度表示的其他部分为条件,但 Eric Postpischil 的评论是思考此问题的另一种方式。