为什么 0.1 + 0.2 不等于 0.3?浮点数与精度
0.1 + 0.2 的真实结果是 0.30000000000000004,与 0.3 比较相等得到"假"。
原因:小数按二进制存储,0.1、0.2 都只能是近似值。浮点比较不要用 ==,
要判断两数之差的绝对值是否足够小。
double:装小数的类型
double 是小数(浮点数)类型,约 15 位有效数字,日常使用一律选它。float 精度只有约 7 位,入门阶段不需要碰。
一个反直觉的事实
double a = 0.1;
double b = 0.2;
double c = a + b;
cout << c << endl; // 看起来是 0.3
cout << (c == 0.3) << endl; // 输出 0(假)
小数在计算机里按二进制存储。十进制的 0.1 写成二进制是无限循环小数,存不下精确值,只能存一个非常接近的近似值——0.2 同理。两个近似值相加,得到的是 0.30000000000000004,与 0.3 差一丁点,== 比较结果是假。
cout 默认只显示 6 位有效数字,把 0.30000000000000004 显示成了 0.3——输出的"看起来对",掩盖了存储的"实际不对"。
正确的比较方法
浮点数之间不用 ==,改判"差得够不够小":
#include <cmath>
bool equal = fabs(c - 0.3) < 1e-9; // 相差小于 0.000000001 视为相等
fabs 是绝对值函数,1e-9 是科学计数法表示的 0.000000001。
可视化观察
在 CppStudio 中打开本课示例,点击播放:
- a、b、c 依次出现在监视区,执行加法后可以暂停,核对 c 的值;
- 第一条 cout 输出
0.3——看起来一切正常; - 第二条 cout 输出
0——比较结果是假。两行输出放在一起,就是浮点精度问题最直观的演示。
常见错误
- 用 == 比较浮点数:刚算出来"相等"的两个值,换一组数就不等了,一律改用差值判断;
- 误以为输出值就是真实值:cout 默认只显示 6 位,真实存储值可能更长;
- 整数小数混用:
double d = 1 / 2;先得整数 0 再转成 0.0,应写1.0 / 2(承接上一课整数除法)。
下一课:char 与 bool——字符其实是一个数字,真假值也有自己的类型。
▶ 运行本课示例 弹窗里直接跑,流程图同步展开;也可新窗口打开
常见问题
为什么 0.1 + 0.2 不等于 0.3?
小数在计算机里用二进制存储,0.1 和 0.2 的二进制是无限循环小数,只能存近似值。两个近似值相加得到 0.30000000000000004,与 0.3 不完全相等。
float 和 double 有什么区别?
都是小数类型。float 约 7 位有效数字,double 约 15 位。日常一律用 double,float 只在对内存敏感的大规模数据场景使用。
浮点数应该怎么比较相等?
不要用 ==。判断两个浮点数是否"足够接近":相减取绝对值,小于一个很小的数(如 1e-9)即视为相等。