JavaScript使用Math.round四舍五入保留2位小数时4.225计算错误如何解决?
两位小数四舍五入精度问题解决方案
问题根因
JavaScript 采用 IEEE 754 双精度浮点数标准存储数值,部分十进制小数无法被二进制精确表示,比如4.225实际存储的值略小于字面量值,乘以100后得到422.49999999999994,最终导致Math.round计算结果不符合预期。
可用解决方案
方案1:字符串处理(最稳定,无精度误差)
直接对数字的字面量字符串做拆分处理,完全规避浮点数计算偏差:
function roundToTwo(num) { const numStr = num.toString(); // 无小数位直接补两位0 if (!numStr.includes('.')) { return Number(`${numStr}.00`); } const [integerPart, decimalPart] = numStr.split('.'); // 小数位补全到3位,取前三位判断进位 const fullDecimal = decimalPart.padEnd(3, '0').slice(0, 3); const decimalPreTwo = fullDecimal.slice(0, 2); const thirdDigit = Number(fullDecimal[2]); let resInt = Number(integerPart); let resDec = decimalPreTwo; if (thirdDigit >= 5) { const newDec = Number(decimalPreTwo) + 1; // 处理小数进位到整数的场景,比如 1.995 进位后为2.00 if (newDec === 100) { resInt += 1; resDec = '00'; } else { resDec = newDec.toString().padStart(2, '0'); } } return Number(`${resInt}.${resDec}`); }
测试用例结果:
roundToTwo(3.342)→ 3.34roundToTwo(4.565)→ 4.57roundToTwo(4.225)→ 4.23
方案2:精度偏移修正(轻量,适配常规场景)
你之前使用Math.Epsilon未生效是因为拼写错误,正确的内置常量为Number.EPSILON,代表1和大于1的最小浮点数之间的差值,用来修正精度偏差:
function roundToTwo(num) { return Math.round((num + Number.EPSILON) * 100) / 100; }
该方案适配绝大多数日常数值计算场景,仅在数值极大/极小的极端场景下可能存在误差。
方案3:高精度计算库(适配金额等高要求场景)
如果是金融、电商金额等对精度要求极高的业务场景,建议直接使用成熟的高精度计算库,从底层规避浮点数精度问题,以decimal.js为例:
import Decimal from 'decimal.js'; function roundToTwo(num) { // ROUND_HALF_UP 对应标准四舍五入规则 return new Decimal(num).toFixed(2, Decimal.ROUND_HALF_UP); }
内容的提问来源于stack exchange,提问作者GetSet
相关产品推荐
相关产品推荐

