js中浮点数的精度问题

为什么JavaScript里面0.1+0.2 === 0.3是false

我们需要有以下基础知识:

1.计算机将所有数据以二进制的形式存储。
2.计算机用有限的大小来存储数据(因为现实生活中不存在无限大的内存或硬盘)。

结论:十进制的 0.1 转为二进制,得到一个无限小数:
0.0001100110011001100110011001100110011001100110011001101
也就是说,二进制无法用有限的位数来表示 0.1。对于 0.2 也是一样的,不赘述。
二进制能用有限的位数表示的有:0.5、0.25、0.125 等。

总结
1.问题的根源是十进制小数转为二进制小数的过程中,会损失精度
2.你在写代码的过程中,遇到小数都要小心,比如下面的代码会造成死循环

let i = 0.1
while(i!=1){
console.log(i)
i += 0.1
}

在JavaScript的新规范ES6加入了一个新的东西–>Number.EPSILON

EPSILON:希腊字母表的第5个字母 ε

Number.EPSILON是在Number对象上面,新增一个极小的常量。根据规格,它表示 1 与大于 1 的最小浮点数之间的差。

对于 64 位浮点数(double)来说,大于 1 的最小浮点数相当于二进制的 1.00…001 ,小数点后面有连续 51 个零。这个值减去 1 之后,就等于 2 的-52 次方。

Number.EPSILON 
2.220446049250313e-16

Math.pow(2, -52)
2.220446049250313e-16

5.551115123125783e-17 < Number.EPSILON * Math.pow(2, 2) // true

Number.EPSILON 可以用来设置“能够接受的误差范围”
比如,误差范围设为 2 的-50 次方(即 Number.EPSILON * Math.pow(2, 2) ),
即如果两个浮点数的差小于这个值,我们就认为这两个浮点数相等。

function withinErrorMargin (left, right) {
    return Math.abs(left - right) < Number.EPSILON * Math.pow(2, 2);
}

0.1 + 0.2 === 0.3 // false
withinErrorMargin(0.1 + 0.2, 0.3) // true

1.1 + 1.3 === 2.4 // false
withinErrorMargin(1.1 + 1.3, 2.4) // true

//上面的代码为浮点数运算,部署了一个误差检查函数。

参考:
为什么 0.1 + 0.2 结果为 0.30000000000000004
为什么JavaScript里面0.1+0.2 === 0.3是false

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值