JavaScript 浮点数精度问题解析与解决方案

作者:半夏

时间:2026-10-28

浏览:387

本文分析JavaScript中浮点数运算精度丢失的根本原因,指出其源于IEEE-754标准及二进制表示的局限性。通过对比测试展示常见计算误差,并提供基于toFixed()和parseFloat()的精度修正方案,以及封装isEqual工具方法,确保数值比较的准确性。

文章目录

浮点数精度问题分析

分析

JavaScript 仅包含 Number 一种数字类型,且所有数值均遵循 IEEE-754 标准格式进行存储。需要注意的是,浮点数精度问题并非 JavaScript 独有,其根本原因在于部分小数在二进制表示下位数是无限的:

十进制 二进制 0.1 0.0001 1001 1001 1001 ... 0.2 0.0011 0011 0011 0011 ... 0.3 0.0100 1100 1100 1100 ... 0.4 0.0110 0110 0110 0110 ... 0.5 0.1 0.6 0.1001 1001 1001 1001 ...

因此,程序无法精确表示如 1.1 这样的数值,只能达到一定程度的近似,这导致了不可避免的精度丢失:

1.09999999999999999

在 JavaScript 中,情况可能更为复杂。以下数据基于 Chrome 浏览器测试得出:

输入 输出 1.0-0.9 == 0.1 False 1.0-0.8 == 0.2 False 1.0-0.7 == 0.3 False 1.0-0.6 == 0.4 True 1.0-0.5 == 0.5 True 1.0-0.4 == 0.6 True 1.0-0.3 == 0.7 True 1.0-0.2 == 0.8 True 1.0-0.1 == 0.9 True

浮点数精度解决方案

解决

如何避免此类非 Bug 型的浮点数计算误差(如 1.0-0.9 != 0.1)?目前常用的一种解决方案是在判断结果前对计算值进行精度缩小处理。由于在缩小精度的过程中会自动执行四舍五入,从而消除误差:

代码如下:

(1.0-0.9).toFixed(digits) // toFixed() 精度参数须在 0 与20 之间
parseFloat((1.0-0.9).toFixed(10)) === 0.1 // 结果为True
parseFloat((1.0-0.8).toFixed(10)) === 0.2 // 结果为True
parseFloat((1.0-0.7).toFixed(10)) === 0.3 // 结果为True
parseFloat((11.0-11.8).toFixed(10)) === -0.8 // 结果为True

方法提炼


代码如下:

// 通过isEqual工具方法判断数值是否相等
function isEqual(number1, number2, digits){
digits = digits == undefined? 10: digits; // 默认精度为10
return number1.toFixed(digits) === number2.toFixed(digits);
}
isEqual(1.0-0.7, 0.3); // return true
// 原生扩展方式,更喜欢面向对象的风格
Number.prototype.isEqual = function(number, digits){
 digits = digits == undefined? 10: digits; // 默认精度为10
 return this.toFixed(digits) === number.toFixed(digits);
}
(1.0-0.7).isEqual(0.3); // return true

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章