美文网首页
解决浮运算问题

解决浮运算问题

作者: overflow_hidden | 来源:发表于2017-12-07 15:30 被阅读32次
    /*js浮点数运算问题解决办法
       @params type: 1乘法,2除法 3减法,4加法
       @params arg1 arg2 按照表达式顺序来
       */
    
      floatCalculation(arg1, arg2, type) {
        if (type == 1) {
          let m = 0,
            s1 = arg1.toString(),
            s2 = arg2.toString();
          try {
            m += s1.split(".")[1].length
          } catch (e) {
            console.log(e)
          }
          try {
            m += s2.split(".")[1].length
          } catch (e) {
            console.log(e)
          }
          return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m);
        } else if (type == 2) {
          let t1 = 0,
            t2 = 0,
            r1, r2;
          try {
            t1 = arg1.toString().split(".")[1].length
          } catch (e) {
            console.log(e)
          }
          try {
            t2 = arg2.toString().split(".")[1].length
          } catch (e) {
            console.log(e)
          }
          r1 = Number(arg1.toString().replace(".", ""));
          r2 = Number(arg2.toString().replace(".", ""));
          return (r1 / r2) * Math.pow(10, t2 - t1);
        } else if (type == 3) {
          let r1, r2, m, n;
          try {
            r1 = arg1.toString().split(".")[1].length
          } catch (e) {
            r1 = 0
          }
          try {
            r2 = arg2.toString().split(".")[1].length
          } catch (e) {
            r2 = 0
          }
          m = Math.pow(10, Math.max(r1, r2));
          //last modify by deeka
          //动态控制精度长度
          n = (r1 >= r2) ? r1 : r2;
          return ((arg2 * m - arg1 * m) / m).toFixed(n);
        } else if (type == 4) {
          let r1, r2, m;
          try {
            r1 = arg1.toString().split(".")[1].length
          } catch (e) {
            r1 = 0
          }
          try {
            r2 = arg2.toString().split(".")[1].length
          } catch (e) {
            r2 = 0
          }
          m = Math.pow(10, Math.max(r1, r2));
          return (arg1 * m + arg2 * m) / m;
        }
      }
    

    另外一遍文章里面原文地址

    /**
     * @file 解决浮动运算问题,避免小数点后产生多位数和计算精度损失。
     * 问题示例:2.3 + 2.4 = 4.699999999999999,1.0 - 0.9 = 0.09999999999999998
     */
    
    /**
     * 把错误的数据转正
     * strip(0.09999999999999998)=0.1
     */
    function strip(num, precision = 12) {
      return +parseFloat(num.toPrecision(precision));
    }
    
    /**
     * Return digits length of a number
     * @param {*number} num Input number
     */
    function digitLength(num) {
      // Get digit length of e
      const eSplit = num.toString().split(/[eE]/);
      const len = (eSplit[0].split('.')[1] || '').length - (+(eSplit[1] || 0));
      return len > 0 ? len : 0;
    }
    
    /**
     * 把小数转成整数,支持科学计数法。如果是小数则放大成整数
     * @param {*number} num 输入数
     */
    function float2Fixed(num) {
      if (num.toString().indexOf('e') === -1) {
        return Number(num.toString().replace('.', ''));
      }
      const dLen = digitLength(num);
      return dLen > 0 ? num * Math.pow(10, dLen) : num;
    }
    
    /**
     * 检测数字是否越界,如果越界给出提示
     * @param {*number} num 输入数
     */
    function checkBoundary(num) {
      if (num > Number.MAX_SAFE_INTEGER || num < Number.MIN_SAFE_INTEGER) {
        console.warn(`${num} is beyond boundary when transfer to integer, the results may not be accurate`);
      }
    }
    
    /**
     * 精确乘法
     */
    function times(num1, num2) {
      const num1Changed = float2Fixed(num1);
      const num2Changed = float2Fixed(num2);
      const baseNum = digitLength(num1) + digitLength(num2);
      const leftValue = num1Changed * num2Changed;
    
      checkBoundary(leftValue);
    
      return leftValue / Math.pow(10, baseNum);
    }
    
    /**
     * 精确加法
     */
    function plus(num1, num2) {
      const baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2)));
      return (times(num1, baseNum) + times(num2, baseNum)) / baseNum;
    }
    
    /**
     * 精确减法
     */
    function minus(num1, num2) {
      const baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2)));
      return (times(num1, baseNum) - times(num2, baseNum)) / baseNum;
    }
    
    /**
     * 精确除法
     */
    function divide(num1, num2) {
      const num1Changed = float2Fixed(num1);
      const num2Changed = float2Fixed(num2);
      checkBoundary(num1Changed);
      checkBoundary(num2Changed);
      return times((num1Changed / num2Changed), Math.pow(10, digitLength(num2) - digitLength(num1)));
    }
    
    /**
     * 四舍五入
     */
    function round(num, ratio) {
      const base = Math.pow(10, ratio);
      return divide(Math.round(times(num, base)), base);
    }
    
    export { strip, plus, minus, times, divide, round, digitLength, float2Fixed };
    export default { strip, plus, minus, times, divide, round, digitLength, float2Fixed };
    

    相关文章

      网友评论

          本文标题:解决浮运算问题

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