zoukankan      html  css  js  c++  java
  • 浮点问题

    浮点精度
    bug:
    小数计算有可能出现精度误差
     
    例如:
    0.1 + 0.2 = 0.30000000000000004
    0.12 - 0.04 = 0.07999999999999999
    0.1 * 0.7 = 0.06999999999999999
     
    原因:
    0.1 + 0.2 这个看似简单的问题,众所周知,能被计算机读懂的是二进制,而不是我们经常看见的十进制,所以我们先把0.1 + 0.2转换为十进制,
    0.1 => 0.0001 1001 1001 1001…(无限循环)
    0.2 => 0.0011 0011 0011 0011…(无限循环)
    双精度浮点数的小数部分最多支持 52 位,所以两者相加之后得到这么一串 0.0100110011001100110011001100110011001100110011001100 因浮点数小数位的限制而截断的二进制数字,这时候,我们再把它转换为十进制,就成了 0.30000000000000004。
     
    执行过程:
    计算机在计算的时候,会先把数值转换为二进制,然后在进行相加,得到的二进制结果,在转化为十进制,这个时候结果就会变成后面多了很多位数的数字;
     
    解决:
    方法一:
    function formatFloat(f,digit){
        let m = Math.pow(10, digit);
        num = Math.round(f * m) / m;
        return num;
    }
    f是计算表达式,digit是需要乘以10的多少次方
     
    例如:
    formatFloat(0.1+0.2,2);  // 0.3
     
    tip:
    digit数必须大于等于 结果小数位数(不知道位数设置远大于即可)
    0.1+0.2   // digit >= 1
    0.12-0.04   // digit >= 2
    0.1*0.7   // digit >= 1
     
    方法二:
    function add(num1, num2) {
      const num1Digits = (num1.toString().split('.')[1] || '').length;
      const num2Digits = (num2.toString().split('.')[1] || '').length;
      const baseNum = Math.pow(10, Math.max(num1Digits, num2Digits));
      return (num1 * baseNum + num2 * baseNum) / baseNum;   // 数据处理逻辑
    }
     
    tip:
    以上方法能适用于大部分场景。遇到科学计数法如 2.3e+1(当数字精度大于21时,数字会强制转为科学计数法形式显示)时还需要特别处理一下。
     
    方法三:
    function floatSub(num1, num2) {
        var r1, r2, m, n;
        try {
            r1 = num1.toString().split('.')[1].length;
        } catch (e) {
            r1 = 0;
        }
        try {
            r2 = num2.toString().split('.')[1].length;
        } catch (e) {
            r2 = 0;
    }
     
     
    m = Math.pow(10, Math.max(r1, r2));
    n = r1 >= r2 ? r1 : r2;
    n > 10 ? (n = 10) : (n = n);
    let str_ = (Math.round(num1 * m - num2 * m) / m).toFixed(n);
     
    return str_;
     
    }
     
    插件:
    https://github.com/dt-fe/number-precision
     
    参考网址:
    https://blog.csdn.net/u013935095/article/details/81119953
    https://github.com/camsong/blog/issues/9
     

    ]]>20200826T062940Z20200826T080213Z39.96441650390625116.318754897597758.3325958251953118333131121@163.comdesktop.mac0

  • 相关阅读:
    结对-结对编项目作业名称-开发环境搭建过程
    课后作业-阅读任务-阅读提问-3
    团队-象棋游戏-项目进度
    结对-五子棋游戏-测试过程
    课后作业-阅读任务-阅读提问2
    201501006-构建之法:现代软件工程-阅读笔记
    结对编程-五子棋游戏-开发过程
    象棋游戏,代码规范
    结编程队-五子棋游戏-项目进度
    《个人-GIT使用方法》
  • 原文地址:https://www.cnblogs.com/maomao-Sunshine/p/13565852.html
Copyright © 2011-2022 走看看