解决js计算精度问题

问题

浮点数,常用的办法是四舍五入保留2位小数来解决。但是在向上、向下保留小数的时候,比如:0.1+0.2=0.30000000000000004,向上保留2位小数就变成了0.31。

大整数,在超出Number的最大安全整数时,计算也会存在精度问题。

原因

二进制最大尾数是52位,超出长度的部分计算就会丢失精度

解决办法

浮点数使用 js-big-decimal 计算浮点数

npm官网:js-big-decimal - npm

安装

npm i js-big-decimal -S

封装方法 /utils/big-decimal.js

import bigDecimal from "js-big-decimal";

export default {
  // 声明
  state(number) {
    return new bigDecimal(number);
  },
  // 加
  add(number1, number2) {
    return bigDecimal.add(number1, number2);
  },
  // 减
  subtract(number1, number2) {
    return bigDecimal.subtract(number1, number2);
  },
  // 乘
  multiply(number1, number2) {
    return bigDecimal.multiply(number1, number2);
  },
  // 除
  // precision: 精确度,默认最多保留8位小数
  divide(number1, number2, precision = 8) {
    // 添加number,移除小数末尾多余0
    return Number(bigDecimal.divide(number1, number2, precision));
  },
  /**
   * 保留小数
   * length: 小数位长度,默认两位小数
   * option:选项,默认四舍五入
   *   HALF_EVEN 四舍五入
   *   CEILING 向上取
   *   DOWN 向下取
   */
  round(number, length = 2, option = "HALF_EVEN") {
    const num = new bigDecimal(number);
    return num.round(length, bigDecimal.RoundingModes[option]).getValue();
  },
  // 绝对值
  abs(number) {
    return bigDecimal.abs(number);
  },
  // 向上取整
  ceil(number) {
    return bigDecimal.ceil(number);
  },
  // 向下取整
  floor(number) {
    return bigDecimal.floor(number);
  },
};

使用

import decimal from '@/utils/big-decimal';
decimal.add(0.1, 0.2);

大数使用bignumber.js

npm官网:bignumber.js - npm

安装

npm install bignumber.js -S

使用

a = new BigNumber(1011, 2)          // "11"
b = new BigNumber('zz.9', 36)       // "1295.25"
c = a.plus(b)                       // "1306.25"