JavaScript中的浮点数精度问题 🔢
问题现象 ❓
在JavaScript中进行浮点数运算时,经常会遇到一些令人困惑的结果:
javascript
console.log(0.1 + 0.2 === 0.3) // false
console.log(0.1 + 0.2) // 0.30000000000000004
console.log(0.5 - 0.4 === 0.1) // false原因分析 🔍
- JavaScript中的所有数字都遵循 IEEE 754 标准,使用64位双精度浮点数存储
- 计算机使用二进制存储数字,某些十进制小数在转换为二进制时会出现无限循环
二进制转换示例 📝
javascript
// 0.125的二进制转换过程
0.125 * 2 = 0.25 // 取整数部分: 0
0.25 * 2 = 0.5 // 取整数部分: 0
0.5 * 2 = 1.0 // 取整数部分: 1
// 最终结果: 0.125(十进制) = 0.001(二进制)
// 0.2的二进制转换过程
0.2 * 2 = 0.4 // 取整数部分: 0
0.4 * 2 = 0.8 // 取整数部分: 0
0.8 * 2 = 1.6 // 取整数部分: 1
0.6 * 2 = 1.2 // 取整数部分: 1
0.2 * 2 = 0.4 // 取整数部分: 0
// 循环继续...最终是无限循环的 0.001100110011...(二进制)解决方案 💡
- 使用toFixed()进行四舍五入
javascript
(0.1 + 0.2).toFixed(2) === '0.30' // true- 乘以倍数转为整数运算
javascript
(0.1 * 10 + 0.2 * 10) / 10 === 0.3 // true- 使用专业的数学库
javascript
import Decimal from 'decimal.js';
new Decimal(0.1).plus(0.2).equals(0.3) // true最佳实践建议 ✨
- 金融计算必须使用专业的数学库
- 展示金额时,始终使用toFixed()固定小数位数
- 对精度要求不高的场景,可以使用Math.round()或toFixed()适当处理
注意事项 ⚠️
- 不要直接比较浮点数是否相等
- 需要精确计算时,将数值转换为整数后再进行计算
- 展示货币金额时,推荐使用专业的格式化库,如Intl.NumberFormat
javascript
// 货币格式化示例
const formatter = new Intl.NumberFormat('zh-CN', {
style: 'currency',
currency: 'CNY'
});
console.log(formatter.format(0.1 + 0.2)); // ¥0.30希望这篇优化后的博客对你有帮助!🎉