在前端开发过程中,大家有没有被数字运算 “背刺” 过?0.1 + 0.2 居然不等于 0.3,购物车结算金额突然 “抽风”…… 别慌!今天手把手教你驯服这些 “不听话” 的数字!
一、前端数字运算的 “玄学时刻”
先来看看那些让人崩溃的经典案例:
console.log(0.1 + 0.2);
// 输出 0.30000000000000004
console.log(1.0 - 0.9);
// 输出 0.09999999999999998
这不是代码出了 bug,而是 JavaScript 的 “锅”!JavaScript 使用 64 位双精度浮点数存储数字,在二进制转换时,有些十进制小数无法精确表示,导致精度丢失。就像用有限的格子去装无限循环的珠子,肯定装不全!
二、四大 “救命神器”,精准拿捏数字
1. 字符串拼接法:最朴实的智慧
把数字转成字符串,进行字符串拼接后再转回来。虽然简单粗暴,但在一些简单场景下超实用!
function add(a, b) {
return Number((BigInt(a * 100) + BigInt(b * 100)).toString()) / 100;
}
console.log(add(0.1, 0.2));
// 输出 0.3
2. BigInt 登场:专治 “大数焦虑”
BigInt 是 ES2020 引入的新类型,能安全存储和操作大整数,连超大金额计算都不怕!
const num1 = 1234567890123456789n;
const num2 = 9876543210987654321n;
console.log(num1 + num2);
// 输出 11111111101111111110n
3. Decimal.js:专业选手的选择
引入 Decimal.js 库,一行代码搞定高精度运算!
const Decimal = require('decimal.js');
const num1 = new Decimal('0.1');
const num2 = new Decimal('0.2');
console.log(num1.plus(num2).toNumber());
// 输出 0.3
4. math.js:全能型 “瑞士军刀”
支持矩阵、复数、单位转换等复杂运算,堪称数学运算界的天花板!
const math = require('mathjs');
console.log(math.add(0.1, 0.2));
// 输出 0.3
三、实战场景:从踩坑到封神
场景 1:电商购物车结算
用户下单 10 件单价 99.99 元的商品,用普通运算可能出现结算金额错误。使用 Decimal.js,轻松实现精确计算:
const price = new Decimal('99.99');
const quantity = new Decimal('10');
const total = price.times(quantity);
console.log(total.toNumber());
// 输出 999.9
场景 2:金融交易系统
涉及分厘必争的金额计算,BigInt 和 Decimal.js 双剑合璧,让每一笔账都清清楚楚!
四、避坑小妙招,细节决定成败
- 尽量用整数运算:比如金额以 “分” 为单位,最后再换算成元。
- 四舍五入有讲究:别直接用 Math.round,Decimal.js 的 toFixed 方法更靠谱!
- 测试不能少:覆盖各种边界值,防止 “隐藏炸弹”!
以上这些方法,能有效解决前端精确数字运算的难题。觉得有用的话,不妨收藏起来,下次遇到相关问题就能轻松应对!也欢迎大家在评论区分享自己的实战经验和技巧 。