关于 js 中的精度丢失问题以及处理方法

        今天在处理后端数据时,需要将一数组值求和,由于传递的是字符型,所以就直接使用Number()转化后直接遍历相加了, 结果发现得出的值是一串神秘数字.

        经典示例
0.1 + 0.2
//0.30000000000000004
Number('0.11') + Number('0.12')
//0.22999999999999998

        了解了一下,在 JavaScript 中,由于采用了 IEEE 754 标准的浮点数表示方法,可能会导致精度丢失问题。这主要是因为浮点数在内存中以二进制的形式存储,而某些十进制数无法精确地转换成二进制表示。当进行计算时,就会出现舍入误差。

        关于转化成二进制

        整数部分遵从:除2取余 + 逆序排列

        即:

Number 8 to binary

8 / 2 = 4 ...... 0
4 / 2 = 2 ...... 0
2 / 2 = 1 ...... 0
1 / 2 = 0 ...... 1

8 ==> 1000

Number 10 to binary

10 / 2 = 5 ...... 0
5 / 2 = 2 ...... 1
2 / 2 = 1 ...... 0
1 / 2 = 0 ...... 1

10 ==> 1010


         而对于小数部分,则是:乘2取整 + 顺序排列

        

Number 0.1 to binary

0.1 * 2 = 0.2 ...... 0

0.2 * 2 = 0.4 ...... 0
0.4 * 2 = 0.8 ...... 0
0.8 * 2 = 1.6 ...... 1
0.6 * 2 = 1.2 ...... 1

0.2 * 2 = 0.4 ...... 0
0.4 * 2 = 0.8 ...... 0
0.8 * 2 = 1.6 ...... 1
0.6 * 2 = 1.2 ...... 1
......

0.1 ==> 0.00110011......

        而刚才提到的  IEEE 754 标准 64 位存储 分为 3 个部分,包括 符号位(1)指数位(11) 和 小数位(52) , 这就导致了当小数第53位为1时,需要往前进一位再保存,这里就造成了第一次的精度丢失,

而当小数相加时,位数再次超过52位,就会再次进位截取,导致第二次精度丢失,从而出现问题.

        解决方法

        明细了问题所在,想要解决就很简单了.既然小数会丢失精度,就直接扩大倍数使用整数计算,最后再还原即可.

(Math.round(Number('1.11') * 100) + Math.round(Number('1.12') * 100)) / 100
//2.23

(Math.round(Number('0.1111') * 10000) + Math.round(Number('0.1112') * 10000)) / 10000
//0.2223

        

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值