美文网首页
0.1 + 0.2为什么等于 0.300000000000000

0.1 + 0.2为什么等于 0.300000000000000

作者: Christoles | 来源:发表于2019-02-25 20:32 被阅读0次

1. 原因 :

\color{red}{JS仅有Number这个数值类型,而Number 采用的是 IEEE-754-64位双精度浮点数编码。}
\color{blue}{ 这是一种二进制表示法,采用 IEEE-754-64 规范的语言都有这个问题}

详细解析:
  计算机内部存储数据的编码的时候,0.1在计算机内部根本就不是精确的0.1,而是一个有舍入误差的0.1。当代码被编译或解释后,0.1已经被四舍五入成一个与之很接近的计算机内部数字,以至于计算还没开始,一个很小的舍入错误就已经产生了。这也就是 0.1 + 0.2 不等于0.3 的原因。

对于 0.1 + 0.2 这样的运算,操作数会先被转成二进制,然后再计算:
0.1 => 0.0001 1001 1001 1001…(无限循环)
0.2 => 0.0011 0011 0011 0011…(无限循环)

  双精度浮点数的小数部分最多支持 52 位,所以两者相加之后得到这么一串 0.0100110011001100110011001100110011001100... 因浮点数小数位的限制而截断的二进制数字,这时候,再把它转换为十进制,就成了 0.30000000000000004 。

console.log(0.1+0.2==0.3);//false

2. 解决方法:

方法一:
function numEqual(a,b){
//abs()绝对值
    return Math.abs(a-b)<Number.EPSILON;
}
var a=0.1+0.2,b=0.3;
console.log("Number.EPSILON:",numEqual(a,b));//true

原理: --- 对于JS来说,这个值通常是 2^-52 , 而在ES6中,提供了一个属性:Number.EPSILON,而这个值正等于2^-52。这个值非常非常小,在底层计算机已经帮我们运算好,并且无限接近0,但不等于0。这个时候我们只要判断(0.1+0.2)-0.3小于Number.EPSILON,在这个误差的范围内就可以判定0.1+0.2===0.3为true。

方法二:
var equl=(0.1*1000+0.2*1000)/1000==0.3;
console.log("10的N次方倍:",equl);//true

原理: --- 把计算数字 提升 10 的N次方 倍 再 除以 10的N次方。一般都用 1000 就行了。

\color{red}{注:} 不是所有浮点数都有舍入误差。二进制能精确地表示位数有限且分母是2的倍数的小数,比如0.5,0.5在计算机内部就没有舍入误差。所以0.5 + 0.5 === 1

相关文章

网友评论

      本文标题:0.1 + 0.2为什么等于 0.300000000000000

      本文链接:https://www.haomeiwen.com/subject/zoknyqtx.html