浮点数比较应避免直接用==,而采用误差范围(epsilon)判断是否足够接近,如Math.abs(a - b)
浮点数比较不能直接用
==,因为float和double的二进制表示天然存在舍入误差,哪怕两个“看起来一样”的值在内存中也可能不等。修正的关键不是强行让它们相等,而是用合理方式判断“是否足够接近”。用误差范围(epsilon)代替相等判断
这是最通用、最轻量的修复方式,适用于大多数非金融类逻辑,比如图形坐标、物理模拟、传感器归一化等。
- 定义一个极小阈值,如
1e-6(double)或1e-5(float),代表你可接受的误差上限- 把
if (a == b)改成if (Math.abs(a - b)- 注意:epsilon 值要匹配业务场景——科学计算可用
1e-10,而 GPS 经纬度差 0.00001° 已远超设备精度,用1e-5就绰绰有余统一类型再比较,避免隐式转换
C/C++/Java 等语言中,
float和double混用常因自动提升引发意外不等。例如float t = 3.197f;与字面量3.197(默认为 double)比较,实际比的是两个不同精度的近似值。
- 显式声明字面量类型:写
3.197f而非3.197,确保参与比较的都是 float- 或统一转为更高精度:将 float 变量转为 double 再比(但仅限于对精度要求不高时)
- 更稳妥的做法是:从源头控制——变量和字面量使用同一类型,不依赖编译器推断
金融或强一致性场景:改用精确类型+字符串构造
当比较结果直接影响账务、权限、状态跃迁(如“余额 ≥ 100 元才允许提现”),就不能容忍任何浮点误差。
- Java 中用
BigDecimal,且必须用字符串构造:new BigDecimal("100.00"),禁用new BigDecimal(100.00)- 比较用
compareTo()方法:amount.compareTo(threshold) >= 0,它按十进制数值大小严格比较- JavaScript 可选
decimal.js:new Decimal("100.00").gte("99.99")循环终止条件别依赖浮点相等
像
for (float x = 0.0f; x != 1.0f; x += 0.1f)极易陷入死循环,因为x永远达不到精确的1.0f。
- 改用整数计数:
for (int i = 0; i- 或用不等式判断:
for (float x = 0.0f; x ,加一点安全余量- 核心原则:循环边界应基于整数或预计算的确定值,而非累加浮点数











