智享教程网
白蓝主题五 · 清爽阅读
首页  > 日常经验

C++浮点精度问题实战避坑指南

做嵌入式开发那会儿,我写了个温度采集程序,结果发现明明传感器返回的是 36.6℃,程序里一比较却对不上。查了半天才发现,是 C++ 浮点精度在作怪。

浮点数不是精确存储的

C++ 中的 float 和 double 看着能存小数,其实底层是用二进制近似表示十进制小数。比如 0.1 这个数,二进制根本无法精确表达,就像 1/3 在十进制里是无限循环小数一样。

这就导致:

#include <iostream>
using namespace std;

int main() {
    float a = 0.1f;
    float b = 0.2f;
    if (a + b == 0.3f) {
        cout << "相等";
    } else {
        cout << "不相等";  // 实际输出这个
    }
    return 0;
}

这段代码输出“不相等”,因为 a + b 的结果其实是 0.3000001 左右,肉眼看不出来,但计算机比得可严了。

别直接用 == 比较浮点数

想判断两个浮点数是否“相等”,得引入一个极小的误差范围,也就是常说的 epsilon。

#include <iostream>
#include <cmath>
using namespace std;

const float EPSILON = 1e-6;

bool isEqual(float a, float b) {
    return fabs(a - b) < EPSILON;
}

int main() {
    float a = 0.1f + 0.2f;
    float b = 0.3f;
    
    if (isEqual(a, b)) {
        cout << "可以认为相等";
    }
    return 0;
}

这样处理后,逻辑就稳了。EPSILON 通常取 1e-6 或 1e-7,具体看你的数据精度需求。

计算累计误差会放大

有次写金融计算模块,用 float 累加每天的利息,跑了几百天后结果差了几块钱。换成 double 才缓解。

建议:涉及钱、科学计算、大量迭代时,优先用 double。float 适合图形渲染这类对精度要求不高的场景。

打印时也得小心

用 cout 输出浮点数,默认只显示6位有效数字,可能掩盖真实问题。

#include <iomanip>
cout << fixed << setprecision(9) << a + b;

加上 setprecision 可以看清实际值,调试时很有用。

整数运算更可靠

如果业务允许,比如金额可以先乘100转成分来算,全程用整数,最后再除回去。这样彻底避开浮点坑。

像微信支付接口内部处理金额都是用分,不是元,就是这个道理。