0.1+0.2===0.3为什么是false,怎么解决?

175 阅读1分钟

问题背景

当我们被问到0.1+0.2等于多少时肯定会想到是0.3啊,在数学角度是正确的,但浏览器里确不是等于。如下图:

WechatIMG571.png

解决问题

分析出现上诉问题的原因

我们都知道,计算机是通过二进制的方式存储数据的,所以计算机计算0.1+0.2的时候,实际上是计算的两个数的二进制的和。0.1的二进制是​​0.0001100110011001100...​​​(1100循环),0.2的二进制是:​​0.00110011001100...​​(1100循环),这两个数的二进制都是无限循环的数。那JavaScript是如何处理无限循环的二进制小数呢?

JavaScript中所用的数字包括整数和小数,但是只有一种类型——Number,它的实现遵循IEEE 754标准,使用64位固定长度来表示,也就是标准的double双精度浮点数。在二进制科学表示法中,双精度浮点数的小数部分最多只能保留52位,再加上前面的1,其实就是保留53位有效数字,剩余的舍去,遵从“0舍1入”的原则。

怎么解决问题

    // 方案1 toFixed(不推荐)
    parseFloat((0.1+0.2).toFixed(1)) === 0.3 //true
    // 但是 多为小数不准确
    parseFloat((0.1+0.25).toFixed(1)) === 0.3 //true
    
    // 最终解决方案
    
    Number.EPSILON=(function(){   //解决兼容性问题
        return Number.EPSILON?Number.EPSILON:Math.pow(2,-52);
    })();
    //上面是一个自调用函数,当JS文件刚加载到内存中,就会去判断并返回一个结果,相比     
    //if(!Number.EPSILON){
    //   Number.EPSILON=Math.pow(2,-52);
    //}这种代码更节约性能,也更美观。
    function numbersequal(a,b){ 
      return Math.abs(a-b)<Number.EPSILON;
    }
    //接下来再判断   
    var a=0.1+0.2, b=0.3;
    console.log(numbersequal(a,b)); //这里就为true了