float与double的本质区别在于IEEE 754标准下三段式结构的位数分配不同:float为1位符号位+8位指数位+23位尾数位(共32位),double为1位符号位+11位指数位+52位尾数位(共64位),这直接决定其数值范围与精度。

float 和 double 的内存结构完全遵循 IEEE 754 标准,核心都是三段式:符号位、指数位、尾数位。区别不在“精度高低”的模糊说法,而在每一段分配的位数不同——这直接决定能表示多大的数、能保留几位有效数字。
float(单精度,32 位)
共 4 字节,严格拆分为:
- 符号位 1 位:0 表正,1 表负
- 指数位 8 位:存储时加偏移量 127(即“移码”),实际指数 = 内存值 − 127;有效范围为 −126 到 +127(全 0 和全 1 被保留用于表示 0、无穷大、NaN 等特殊值)
- 尾数位 23 位:不显式存储二进制科学计数法中隐含的整数位“1”,只存小数点后的 23 位;因此实际精度相当于 24 位二进制,约 6–7 位十进制有效数字
double(双精度,64 位)
共 8 字节,结构同理但更宽:
- 符号位 1 位:同样 0 正 1 负
- 指数位 11 位:偏移量为 1023,实际指数 = 内存值 − 1023;有效范围为 −1022 到 +1023
- 尾数位 52 位:同样隐含前导 1,实际精度为 53 位二进制,对应约 15–16 位十进制有效数字
为什么指数和尾数要这样设计?
这不是随意划分,而是职责分明:
- 符号位管正负,最直观
- 指数位管“数量级”——位数越多,能表示的数越大或越接近零(比如 double 指数多出 3 位,范围从 ~10³⁸ 跃升至 ~10³⁰⁸)
- 尾数位管“细节”——它决定了同一个数量级内,你能区分多少个不同的值(比如 float 尾数 23 位,相邻两个可表示数的间隔远大于 double)
一个典型例子:0.1 的存储
十进制 0.1 在二进制中是无限循环小数:0.0001100110011…(周期为 1001)。float 只能取前 23 位尾数并舍入,double 取前 52 位并舍入——两者都是近似值,且近似方式不同。这就是为什么 0.1f + 0.2f != 0.3f,而 0.1 + 0.2 != 0.3 在 double 下依然不成立:底层是同一套规则,只是截断位置不同。

















