数字求和精度, 不存在精度丢失, 大值计算,无限制长度)

18 阅读1分钟

数字计算(保留任意精度, 不存在精度丢失, 大值计算,无限制长度) - 码上掘金 (juejin.cn)

/**
 * 数字求和精度, 不存在精度丢失, 大值计算,无限制长度)
 * @param num1
 * @param num2
 * @return 保留精度
 */
function plus(num1: number | string, num2: string) { 

  const s1 = typeof num1 === 'string' ? num1 : `${num1}`;
  const s2 = typeof num1 === 'string' ? num2 : `${num2}`;

  const a1 = s1.split('.');
  if (a1.length > 2) return NaN;
  const a2 = s2.split('.');
  if (a2.length > 2) return NaN;

  const sn1 = a1.join('');
  const sn2 = a2.join(''); 

  // 小数点长度
  const sl = Math.max(a1[1].length, a2[1].length); 

  // 最大长度
  const ml = Math.max(sn1.length, sn2.length);
  // 计算时, 间隔计算长度
  const rl = 12;
  // 总共计算几次区间分段计算
  const rlc = Math.ceil(ml / rl);

  // 区间计算汇总
  const ns: string[] = [];

  for (let i = 0; i < rlc; i++) { 
     
    const rn1 = parseInt(sn1.substr(i*rl, rl)) || 0;
    const rn2 = parseInt(sn2.substr(i * rl, rl)) || 0;

    // 上端计算是否存在进值
    const pns = typeof ns[i] !== "string" ? 0 : parseInt(ns[i].substring(0, ns[i].length - rl)) || 0;
    const rns = (pns + rn1 + rn2).toString();
    ns[i] = rns;
  }

  const rs = ns.join("");
  // 没有小数位, 直接返回
  if (sl <= 0) return rs;
  // 有小数位, 添加小数位
  return rs.substring(0, rs.length - sl) + '.' + rs.substr(rs.length - sl);
}

// export { plus };

console.log(plus('25949420.05635273', '57193472.45773819'));
console.log(plus('25949420.05635273', '57190472.45773819'));

image.png