为什么C语言中累加0.1十次后double变量d不等于1.0?
为什么累加0.1十次不等于1.0?
这是浮点数的二进制表示局限性导致的问题,核心原因是:0.1无法用二进制浮点数精确存储。
具体解释:
- 我们常用的
double类型遵循IEEE 754标准,是64位浮点数,它的存储依赖二进制。十进制里的0.1等于1/10,而10的质因数是2和5,分母包含无法被2的幂次消去的因子5,所以0.1在二进制中是无限循环小数,就像十进制里的1/3是0.333...一样。 double只能用53位有效位去近似存储这个无限循环的二进制小数,所以程序里的.10其实是0.1的一个近似值,而非精确值。每次累加这个近似值,误差会逐步累积,十次之后的总和就会是一个接近1.0但存在微小偏差的数(比如你看到的0.999999999998左右),自然无法和精确的1.0通过==判定相等。
验证方法:
你可以打印变量d的高精度值来直观看到偏差:
#include <stdio.h> int main(void) { double d = 0.; int i; for (i = 0; i < 10; i++) d += .10; printf("d = %.20f\n", d); // 打印高精度数值 if (d == 1.) printf("d is 1.\n"); else printf("d is not 1.\n"); return 0; }
运行后会输出类似d = 0.99999999999999988898的结果,明显和1.0有偏差。
正确的浮点数比较方式:
永远不要直接用==比较两个浮点数是否相等,应该比较它们的差值是否小于一个极小的阈值(比如1e-9,这个值可以根据你的精度需求调整):
#include <stdio.h> #include <math.h> // 需要包含math.h来使用fabs函数 int main(void) { double d = 0.; int i; for (i = 0; i < 10; i++) d += .10; if (fabs(d - 1.0) < 1e-9) printf("d is approximately 1.\n"); else printf("d is not 1.\n"); return 0; }
这样就能正确判断浮点数是否在可接受的精度范围内相等。
内容的提问来源于stack exchange,提问作者cfdemirkiran
相关产品推荐
相关产品推荐

