为什么C++ for循环中使用float和double会得到不同运行结果
两个基础前提:
- 十进制0.1无法被二进制浮点数(float/double)精确表示,两者存储的都是0.1的近似值,精度不同,近似值本身存在差异
- C++中不带后缀的小数字面量
0.1默认是double类型,不同类型变量运算时会发生隐式类型转换,误差累积路径完全不同
为什么double版本会输出1
for循环的执行顺序是:先判断i<1是否成立 → 成立则执行循环体输出i → 再执行i += 0.1
你看到的输出1,本质是cout默认输出精度(6位有效数字)的四舍五入结果:此时i的实际值略小于1,仍满足i<1的条件可以进入循环体。
double类型下,每次累加的都是double类型的0.1近似值(约为0.10000000000000000555),经过10次累加后,i的实际值约为0.9999999999999999,小于1,因此会进入循环体输出,cout会把这个极接近1的值四舍五入显示为1,之后再加0.1得到的结果才会大于等于1,下次判断时直接跳出循环。
为什么float版本符合预期
当i是float类型时,i += 0.1的运算会多一步类型转换:先把float类型的i提升为double,和double类型的0.1相加后,再把结果截断为float赋值给i。
每次截断会抵消掉一部分累加的正向误差,10次累加后的i实际值已经略大于1,因此第11次判断i<1时不成立,直接跳出循环,不会触发输出,自然不会显示1。
如果你把代码里的0.1改为float类型字面量0.1f,运行结果会和现在完全不同。
验证方法
你可以在输出前加上cout << fixed << setprecision(20);(需要引入<iomanip>头文件),输出i的完整20位小数,就能看到i的真实值和显示值的差异,也能明确观测到两种类型下的误差区别。
注意:永远不要直接用浮点变量作为循环边界的判断条件,最优做法是用整数计数控制循环次数,避免精度误差带来的非预期行为。
内容的提问来源于stack exchange,提问作者shawarma

