美文网首页
数值精度的解决方案

数值精度的解决方案

作者: 阿布朗迪 | 来源:发表于2018-10-24 10:11 被阅读0次
    console.log(0.1 + 0.2);   //0.30000000000000004
    console.log(0.1 + 0.2 == 0.3);  //false
    JavaScript 中的 number 类型就是浮点型,JavaScript 中的浮点数采用IEEE-754 格式的规定,这是一种二进制表示法,可以精确地表示分数,比如1/2,1/8,1/1024,每个浮点数占64位。但是,二进制浮点数表示法并不能精确的表示类似0.1这样 的简单的数字,会有舍入误差。
    
    由于采用二进制,JavaScript 也不能有限表示 1/10、1/2 等这样的分数。在二进制中,1/10(0.1)被表示为 0.00110011001100110011…… 注意 0011 是无限重复的,这是舍入误差造成的,所以对于 0.1 + 0.2 这样的运算,操作数会先被转成二进制,然后再计算:
    
    0.1 => 0.0001 1001 1001 1001…(无限循环)
    0.2 => 0.0011 0011 0011 0011…(无限循环)
    双精度浮点数的小数部分最多支持 52 位,所以两者相加之后得到这么一串 0.0100110011001100110011001100110011001100...因浮点数小数位的限制而截断的二进制数字,这时候,再把它转换为十进制,就成了 0.30000000000000004。
    
    对于保证浮点数计算的正确性,有两种常见方式。
    
    一是先升幂再降幂:
    
    function add(num1, num2){
      let r1, r2, m;
      r1 = (''+num1).split('.')[1].length;
      r2 = (''+num2).split('.')[1].length;
    
      m = Math.pow(10,Math.max(r1,r2));
      return (num1 * m + num2 * m) / m;
    }
    console.log(add(0.1,0.2));   //0.3
    console.log(add(0.15,0.2256)); //0.3756
    二是是使用内置的 toPrecision() 和 toFixed() 方法,注意,方法的返回值字符串。
    
    function add(x, y) {
        return x.toPrecision() + y.toPrecision()
    }
    console.log(add(0.1,0.2));  //"0.10.2"
    

    原文:https://github.com/chenjinxinlove/javascriptInterview

    相关文章

      网友评论

          本文标题:数值精度的解决方案

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