zoukankan      html  css  js  c++  java
  • js 计算精度问题

    一 浮点计算精读出现的问题枚举

    0.1 + 0.2               // 0.30000000000000004  not  0.3
    0.3 - 0.2             // 0.09999999999999998    not 0.1
    1.005 * 100         //100.49999999999999  not  100.5 , 所以用 Math.round(1.005*100)/100 得到的也是1 not  1.01
    0.69 / 10           // 0.06899999999999999  not 0.069
    1.005.toFixed(2)  // '1.00' not '1.01' (四舍五入:采用银行家算法 - 不准确)
    

    二 js 浮点计算 精度出现精读问题的原因

    js所有数字包括整数浮点数只有一种类型 - Number类型,它遵循IEEE 754标准,使用固定的64位固定长度来表示,也就是标准的double 双精度浮点数。(单精读 是float 32位) 。
    这样的存储结构优点是可以归一化处理整数和小数,节省存储空间。
      64位比特又可分为三个部分:

    符号位S:第 1 位是正负数符号位(sign),0代表正数,1代表负数

    指数位E:中间的 11 位存储指数(exponent),用来表示次方数

    尾数位M:最后的 52 位是尾数(mantissa),超出的部分自动进一舍零

    所以产生误差的原因:由于有一些浮点数用二进制表示时是无穷的,当浮点数转化为二进制进行存储时,会把超过53位之后的进行合并导致精读丢失。

    三 js 浮点运算解决方案 (保留多少位数小数,末尾实现四舍五入)

    方法一: 自定义函数
        function toFixed(n, d) {
          if (n > Number.MAX_SAFE_INTEGER || n < Number.MIN_SAFE_INTEGER) {
            throw new Error('超过js安全计算值范围,此函数暂不支持!');
          }
          const radix = 10 ** d;
          let num = math.floor(n * radix);
          const a = String(n).split('.');
          if (a[1] && a[1].length >= d) {
            if (Number(a[1][d]) >= 5) {
              num += 1;
            }
          }
          return num / radix;
        }
    
    方法二 利用mathjs 库
    import { create, all, round } from 'mathjs';
    
    const config = {
      number: 'BigNumber',
      precision: 64,
    };
    
    const mathJs = create(all, config);
    // number 和 bignumber类型
    // mathJs.evaluate('0.1 + 0.2');  // 0.3
    // 默认保留两位小数,实现四舍五入
    
    export const math = (expression, precision = 2) => {
      return round(mathJs.number(mathJs.evaluate(expression)), precision);
    };
    
    math('0.1 + 0.2'); // 0.3
    
  • 相关阅读:
    notepad++ 编辑器链接地址可点击
    window的cmd窗口运行git
    php update for mac
    sublime打开文件时自动生成并打开.dump文件
    不能设置sublime text 2 为默认编辑器
    sublime text 2 配置文件
    Compass被墙后如何安装安装
    everything搜索工具小技巧
    Ubuntu安装已经下载好的文件包
    Flutter 异步Future与FutureBuilder实用技巧
  • 原文地址:https://www.cnblogs.com/honkerzh/p/14551197.html
Copyright © 2011-2022 走看看