js 精度计算 & 小数正常四舍五入保留小数位

math = {
    /**
     * +
     * @param arg1
     * @param arg2
     * @returns {number}
     */
    add: function (...argArr: number[]): number {
      if (!argArr.length) {
        return 0;
      }
      if (argArr.length == 1) {
        return argArr[0] || 0;
      }
      let arg1 = argArr.shift() || 0;
      let arg2 = this.add(...argArr) || 0;
      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;
    },
    /**
     * -
     * @param arg1
     * @param arg2
     * @returns {number}
     */
    sub: function (arg1: number, arg2: number): number {
      arg1 = arg1 || 0;
      //let arg2 = this.add(...argArr) || 0;
      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));
      n = r1 >= r2 ? r1 : r2;
      return parseFloat(((arg1 * m - arg2 * m) / m).toFixed(n));
    },
    /**
     *  *
     * @param arg1
     * @param arg2
     * @returns {number}
     */
    mul: function (...argArr: number[]): number {
      if (!argArr.length) {
        return 0;
      }
      if (argArr.length == 1) {
        return argArr[0] || 0;
      }
      let arg1 = argArr.shift() || 0;
      let arg2 = this.mul(...argArr) || 0;
      let m = 0,
        s1 = arg1.toString(),
        s2 = arg2.toString();
      try {
        m += s1.split('.')[1].length;
      } catch (e) {
      }
      try {
        m += s2.split('.')[1].length;
      } catch (e) {
      }
      return (
        (Number(s1.replace('.', '')) * Number(s2.replace('.', ''))) /
        Math.pow(10, m)
      );
    },
    /**
     * /
     * @param arg1
     * @param arg2
     * @returns {number}
     */
    div: function (arg1: number, ...argArr: number[]): number {
      arg1 = arg1 || 0;
      let arg2 = this.mul(...argArr) || 0;
      let t1 = 0,
        t2 = 0,
        r1,
        r2;
      try {
        t1 = arg1.toString().split('.')[1].length;
      } catch (e) {
      }
      try {
        t2 = arg2.toString().split('.')[1].length;
      } catch (e) {
      }
      r1 = Number(arg1.toString().replace('.', ''));
      r2 = Number(arg2.toString().replace('.', ''));
      return (r1 / r2) * Math.pow(10, t2 - t1);
    },
    /**
     * 保留有效小数位 四舍五入,解决toFixed方法bug
     * @param num 需要操作的数字
     * @param decimal 保留小数的位数
     * @returns {string}
     */
    toFixed(num: number, decimal: number = 2): string {
      if (isNaN(num)) {
        return '';
      }
      const p = Math.pow(10, decimal);
      let r = (Math.round(num * p) / p) + '';
      const len = decimal - (r.split('.')[1] || '').length;
      if (len) {
        r += (len == decimal ? '.' : '') + Array(len).fill('0').join('')
      }
      return r;
    }
  };
原文地址:https://www.cnblogs.com/zhenguo-chen/p/14672347.html