AngularJS中ng-repeat内作用域变量计算异常问题咨询
浮点数精度问题导致的计算误差,附解决办法
这是典型的浮点数精度陷阱,在JavaScript(Angular框架基于JS运行)里太常见了,我给你理清楚原因和解决办法:
问题根源
JavaScript采用IEEE 754双精度浮点数标准存储数值,很多十进制小数没法被精确转换成二进制浮点数——比如0.1在二进制里是无限循环的,只能近似存储。当你对多个这样的近似值做加减运算时,微小的误差会慢慢累积,最终就出现了0.0005000000019208528这种看起来诡异的结果。
至于两个变量运算时正常,只是刚好误差没累积到能被你察觉的程度而已,本质上还是存在精度问题的,只是没暴露出来。
解决办法
针对金额这种需要精确计算的场景,有几种靠谱的处理方式:
用Angular的
number管道格式化展示
直接在表达式里添加管道,指定保留的小数位数(比如金额通常保留2位),它会自动帮你做四舍五入处理:<td>{{ ((total.drawerAmount + total.totalReturns ) - total.totalWithd) | number:2 }}</td>这样计算结果会被格式化为
0.00,符合金额的展示需求。手动调用
toFixed()方法
如果你更倾向于原生JS的方式,可以用toFixed()来固定小数位数:<td>{{ ((total.drawerAmount + total.totalReturns ) - total.totalWithd).toFixed(2) }}</td>注意
toFixed()返回的是字符串,要是后续需要做数值运算,记得转成数字类型。从根源避免:用整数存储金额
这是处理金额最稳妥的方案——把所有金额都以最小单位(比如分)存储为整数,运算时用整数计算,最后再转换成元(除以100)。比如10.5元存成1050分,这样所有运算都是整数操作,完全不会有浮点数精度问题。
内容的提问来源于stack exchange,提问作者Ali
相关产品推荐
相关产品推荐

