浮点数在计算机中存储格式详解

📅 2026/7/15 19:56:21 👁️ 阅读次数 📝 编程学习
浮点数在计算机中存储格式详解

博主的另一篇文章讲解浮点数的相关知识:

https://blog.csdn.net/ouyangxiaozi/article/details/161105232?sharetype=blogdetail&sharerId=161105232&sharerefer=PC&sharesource=ouyangxiaozi&spm=1011.2480.3001.8118

本文再讲解浮点数再计算机中存储的详细过程,比如double类型的9.721的整个转换和存储过程。

先按主流平台讲:在绝大多数 PC 和服务器上,C++ 里的double使用 IEEE 754 双精度格式,也就是 binary64。9.721字面量,默认就是double,编译器会把它转换成“最接近 9.721 的那个 binary64 值”。

1.double的 64 位结构

double一共 64 位,分成 3 段:

  1. 1 位符号位sign
  2. 11 位指数位exponent
  3. 52 位尾数字段fraction

正规数的值按这个公式解释:

这里的1023是指数偏移量。


2.9.721先变成二进制是什么样

十进制整数部分很简单:

910=10012910​=10012​

小数部分0.721要靠“乘 2 取整”反复展开,它不是一个有限二进制小数,所以会变成无限展开。

前几步例如:

  1. 0.721 × 2 = 1.442,取1
  2. 0.442 × 2 = 0.884,取0
  3. 0.884 × 2 = 1.768,取1
  4. 0.768 × 2 = 1.536,取1
  5. 0.536 × 2 = 1.072,取1

所以它的二进制大致是:

因为是无限展开,double不可能把它完整存下,只能截断并舍入到 52 位尾数。


3. 规格化

9.721落在区间 [8,16)[8,16),所以规格化后指数是3

这就是写进double前的“规格化形式”。


4. 三段字段分别是什么

9.721这个double,三段内容是:

  1. 符号位
    0
    因为它是正数。

  2. 指数位
    真实指数是3,存储时要加偏移量1023

3+1023=1026

1026的二进制是:

  1. 尾数字段
    去掉规格化里隐含的前导1后,存这 52 位:

0011011100010010011011101001011110001101010011111110

所以完整位模式就是:

0 | 10000000010 | 0011011100010010011011101001011110001101010011111110


5. 最终 64 位十六进制表示

把上面的 64 位合起来,得到:40237126E978D4FE

也就是:0x40237126E978D4FE

这是最常见、最方便看的表示法。

如果你的机器是常见的 x86/x64 小端序,那么内存里按地址从低到高看到的 8 个字节通常是:

FE D4 78 E9 26 71 23 40

注意:

  1. IEEE 754 规定的是位意义
  2. 小端/大端影响的是字节在内存里的摆放顺序

6. 它实际存的值并不等于数学上的 9.721

真正被存进去的精确值是:

它对应的十进制是:

9.721000000000000085265128291212022304534912109375

所以它比真正的9.721稍微大一点,误差大约是:

这就是为什么浮点数经常会出现“看起来一样,底层并不完全相等”的现象。


7. 你可以自己验证

下面这段代码可以把9.721的位模式打印出来:

#include <cstdint> #include <cstring> #include <iomanip> #include <iostream> int main() { double x = 9.721; std::uint64_t bits = 0; std::memcpy(&bits, &x, sizeof(x)); std::cout << "hex bits = 0x" << std::hex << std::uppercase << bits << '\n'; std::cout << std::dec << std::setprecision(30) << "stored value = " << x << '\n'; }

在主流 IEEE 754 平台上,通常会看到接近这样的输出:

hex bits = 0x40237126E978D4FE stored value = 9.72100000000000008526512829121

一句话总结

double 9.721在计算机里不是直接存“9.721 这几个十进制字符”,而是先转成二进制科学计数法,再按 IEEE 754 的符号位 + 指数位 + 尾数位存成 64 位。对这个数来说,最终常见的 binary64 编码是:

0x40237126E978D4FE

而它真正存储的十进制值其实是:

9.721000000000000085265128291212...