double类型变量精度疑问:打印0.1时末尾出现非零数值的原因
为什么double类型的0.1打印20位小数时会出现非零尾数
你运行的代码如下:
double a = 0.10; printf("%.20lf", a);
这个结果是二进制浮点数的固有特性导致的,和编辑器、编译器没有直接关系,核心原因如下:
- 十进制的0.1无法用二进制浮点数精确表示,所有遵循IEEE 754浮点数标准的平台都会存在这个现象。
- 十进制小数转二进制采用「乘2取整」规则,我们可以手动推演0.1的转换过程:
0.1 * 2 = 0.2 → 取整数位 0
0.2 * 2 = 0.4 → 取整数位 0
0.4 * 2 = 0.8 → 取整数位 0
0.8 * 2 = 1.6 → 取整数位 1
0.6 * 2 = 1.2 → 取整数位 1
0.2 * 2 = 0.4 → 进入循环,循环节为0011
最终0.1的二进制表示是无限循环的0.0001100110011...,不存在有限长度的二进制编码。 - C语言的
double类型是IEEE 754标准定义的双精度浮点数,总共只有64位存储空间,其中用来存储小数有效位的尾数部分仅52位,只能截取无限循环序列的前若干位再做舍入,最终存储的是和0.1最接近的可表示二进制值,而非精确的0.1。 - 把这个舍入后的二进制值转回十进制、打印20位小数时,就会出现你看到的
0.10000000000000001000结果,末尾的非零值就是舍入误差的直观体现。
内容的提问来源于stack exchange,提问作者Unstuck
相关产品推荐
相关产品推荐

