Vue.js 四舍五入数字出现异常,parseFloat处理价格返回奇怪数值问题
问题原因
这是JavaScript中IEEE 754双精度浮点数存储规则导致的精度丢失问题。十进制的多位小数转换为二进制时会出现无限循环的情况,parseFloat()转换后存储的是近似值,多次累加后误差会被放大,最终出现类似X.9999999999999或者X.0000000000001这类不符合预期的结果。
解决方案
- 方法1:整数转换法(最推荐,无额外依赖,精度稳定)
将金额统一放大100倍转换为整数(以分为单位)进行计算,全部累加完成后再缩小100倍保留2位小数,整数的浮点数存储是完全精确的,不会出现误差。
修改后的代码示例:
this.selectedCompaniesDetails.forEach((company)=>{ if(company.id == p.company_id) { if (!tot[p.company_id]) { // 存储改为存整数(单位:分) tot[p.company_id] = 0 } // 价格转分,用四舍五入避免小数转整数时的误差 const centPrice = Math.round(parseFloat(p.price) * 100) tot[p.company_id] += centPrice } }); // 最终取合计值的时候再转成元,保留2位小数 const totalPrice = (tot[p.company_id] / 100).toFixed(2)
- 方法2:使用高精度计算库
如果涉及非常复杂的金融级金额计算,可以引入bignumber.js、decimal.js这类专门处理精度问题的第三方库,直接调用封装好的加减方法即可避免误差。 - 注意事项
不要在累加过程中每次都调用toFixed()处理,toFixed()本身是四舍五入操作,多次执行会累积新的误差,最好在所有计算完成后最后一步再做格式化保留小数。
内容的提问来源于stack exchange,提问作者Brian Highforce Thomas
相关产品推荐
相关产品推荐

