You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

JavaScript浮点数相减精度问题:为何计算结果不符合预期?

为什么JavaScript中3.0减2.6会得到0.3999999999999999而非0.4?

这个问题是JavaScript浮点数精度的经典陷阱,我来帮你理清楚前因后果:

核心原因:浮点数的二进制存储限制

首先得明确:大部分十进制小数无法被二进制浮点数精确表示。比如0.1、0.6这类数,在二进制里是无限循环的小数,就像十进制里的1/3=0.3333...一样。当你把2.6存入JS的Number类型时,实际存储的是一个非常接近2.6但存在微小误差的近似值。

而你代码里的toFixed(1)又额外加了一层坑:toFixed()返回的是字符串,不是数字!虽然JS会在减法时自动把字符串转成数字,但这个转换过程依然逃不过浮点数的精度问题。

那为什么discount_amt=2.5时结果正常?因为2.5是2 + 1/2,对应的二进制是10.1,可以被精确存储,所以3.0-2.5=0.5的计算完全精确。

解决方法

针对你的场景,有几个简单有效的方案:

1. 先计算,后格式化

不要在计算前用toFixed()处理数值,先完成所有运算,最后再用toFixed()格式化输出结果:

var total = parseFloat('3');
var discount_amt = parseFloat('2.6');
total = total - discount_amt;
console.log(total.toFixed(1)); // 输出 "0.4"

2. 转整数计算,避免浮点数误差

把所有小数乘以10(或10的n次方,n是你需要保留的小数位数)转成整数,计算完成后再转回去:

var total = parseFloat('3') * 10;
var discount_amt = parseFloat('2.6') * 10;
total = (total - discount_amt) / 10;
console.log(total); // 输出 0.4

3. 用精度阈值判断近似相等(如果需要比较结果)

如果你的场景需要判断计算结果是否等于某个值,可以用Number.EPSILON(JS中表示两个可表示浮点数之间的最小差值)来做近似判断:

var result = 3.0 - 2.6;
if (Math.abs(result - 0.4) < Number.EPSILON) {
  console.log("结果近似等于0.4");
}

内容的提问来源于stack exchange,提问作者Bhautik

火山引擎 最新活动