JavaScript 使用 IEEE 754 双精度浮点数表示所有数字,这会导致一些常见的小数精度问题,例如 0.1 + 0.2 !== 0.3。以下是处理 JavaScript 小数精度的常用技巧:
1. 四舍五入方法
// toFixed方法(返回字符串)
let num = 0.1 + 0.2; // 0.30000000000000004
let fixed = num.toFixed(2); // "0.30"
// 使用Math.round四舍五入
function round(value, decimals) {
return Number(Math.round(value + 'e' + decimals) + 'e-' + decimals);
}
round(1.005, 2); // 1.01
2. 精度运算库
使用专门的数学库处理精确计算:
- decimal.js —— 功能相对简单,适合基本的高精度计算需求
- big.js —— 支持三角函数、指数、对数等高级数学运算
// 使用decimal.js示例
import Decimal from 'decimal.js';
let sum = new Decimal(0.1).add(new Decimal(0.2)); // 0.3
3. 整数运算技巧
将小数转换为整数进行计算,再转换回去:
function add(num1, num2) {
const multiplier = Math.pow(10, Math.max(getDecimalLength(num1), getDecimalLength(num2)));
return (num1 * multiplier + num2 * multiplier) / multiplier;
}
function getDecimalLength(num) {
const decimalStr = num.toString().split('.')[1];
return decimalStr ? decimalStr.length : 0;
}
4. 比较数字时的容差方法
function numbersEqual(a, b, tolerance = 1e-10) {
return Math.abs(a - b) < tolerance;
}
5. 格式化显示
// 使用Intl.NumberFormat
const formatter = new Intl.NumberFormat('en-US', {
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
formatter.format(0.1 + 0.2); // "0.30"
6. 避免常见陷阱
- 不要直接比较浮点数
- 对于货币计算,通常使用整数表示分(如用100表示1.00元)
- 大整数计算考虑使用BigInt类型
对于简单的显示问题,toFixed可能足够;对于复杂的财务计算,建议使用专门的库。
发表回复