在 JavaScript 中处理 `0.1 + 0.2` 这类精度问题
在 JavaScript 中处理 0.1 + 0.2
这类精度问题,核心思路是规避二进制浮点数的固有误差,以下是几种常用方案,根据场景选择即可:
方案1:固定小数位数(简单场景,如展示)
用 toFixed(n)
强制保留指定小数位数(会自动四舍五入),适合仅需展示结果的场景。
const result = 0.1 + 0.2;
console.log(result.toFixed(1)); // 输出 "0.3"(注意返回的是字符串)
// 如需转成数字:
console.log(Number(result.toFixed(1))); // 输出 0.3
⚠️ 注意:toFixed
适合展示,不适合高精度计算(如金融场景),因为它本质是对结果做了“截断美化”。
方案2:放大为整数计算(推荐简单业务)
把小数放大成整数(避开小数运算),计算后再缩小回去,从根源上避免浮点数误差。
// 计算 0.1 + 0.2:放大10倍转整数
const a = 0.1;
const b = 0.2;
const scale = 10; // 放大倍数(根据小数位数定,如0.01需放大100倍)
const sum = (a * scale + b * scale) / scale;
console.log(sum); // 输出 0.3
方案3:用 Number.EPSILON
比较误差(判断相等场景)
如果需要判断两个浮点数是否“实际相等”(允许微小误差),可用 JS 内置的最小精度 Number.EPSILON
(约 2.2e-16)。
function isEqual(a, b) {// 两个数的差小于最小精度,视为相等return Math.abs(a - b) < Number.EPSILON;
}const result = 0.1 + 0.2;
console.log(isEqual(result, 0.3)); // 输出 true(认为两者相等)
方案4:使用高精度计算库(金融/严谨场景)
如果涉及金额、科学计算等高精度场景,推荐用成熟库处理(内置十进制小数算法)。
常用库:decimal.js
、big.js
(轻量)、bignumber.js
。
以 decimal.js
为例(需先安装):
- 安装:
npm install decimal.js
- 使用:
import Decimal from 'decimal.js';const a = new Decimal('0.1'); // 注意用字符串传参,避免初始化时的精度丢失
const b = new Decimal('0.2');
const sum = a.plus(b); // 用库的方法计算
console.log(sum.toString()); // 输出 "0.3"
console.log(sum.toNumber()); // 输出 0.3(转成数字)
总结
- 简单展示:用
toFixed(n)
- 简单计算:放大为整数
- 判断相等:用
Number.EPSILON
- 高精度场景(如钱):必用
decimal.js
等库
日常开发中,放大为整数
和 toFixed
基本能覆盖大部分场景,复杂场景直接上库更稳妥~