0.1+0.2等于0.3吗
在js内部所有的计算都是二进制进行的,所以运算 0.1+ 0.2 时,要先把 0.1和 0.2 从十进制转成二进制。
在现代浏览器中是用浮点数形式的二进制来存储二进制,所以还要把二进制转成浮点数形式的二进制。
浮点数相加时,需要先比较指位数是否一致,如果一致则小数位直接相加,如果不一致,要先把指位数调成一致的,指位数小的向大的调整。
0.1+0.2 不等于 0.3 ,因为在 0.1+0.2 的计算过程中发生了两次精度丢失。第一次是在 0.1 和 0.2 转成双精度二进制浮点数时,由于二进制浮点数的小数位只能存储52位,导致小数点后第53位的数要进行为1则进1为0则舍去的操作,从而造成一次精度丢失。第二次在 0.1 和 0.2 转成二进制浮点数后,二进制浮点数相加的过程中,小数位相加导致小数位多出了一位,又要让第53位的数进行为1则进1为0则舍去的操作,又造成一次精度丢失。最终导致 0.1+0.2 不等于0.3 。
0.1+0.2 不等于 0.3 会引起那些BUG?
会引起统计页面展示错乱的BUG,还有 300.01 优惠300 元后,支付金额不足0.01 元等类似的BUG。
怎么解决 0.1+0.2 不等于 0.3 这个问题。
可以用Math.js数学计算库来解决,或者用toFixed()
给计算结果四舍五入,但是toFixed()
在chrome或者火狐浏览器下四舍五入也有精度误差。可以用Math.round
来解决精度误差,比如要把 2.55 四舍五入保留 1 位小数,先把 2.55∗10 得到 25.5 ,再用Math.round
取整25.5 ,会得到25,再把 25÷10 得到 2.5 ,就这样间接实现了四舍五入。可以用Math.pow
来做个简单的封装Math.round(Math.pow(10, m) * number) / Math.pow(10, m)
,其中number
是要四舍五入的数,m
是保留几位小数。