高精度之decimal

527 阅读4分钟

开发过程中难免会碰到高精度、大数字等问题,尤其是后台开发,碰到大数字或者需要精确小数点后的数字,那么使用单纯的float和字符串也许都不是一个更好的选择

单纯的float位数较少,对于金额类很容易丢失精度,金额少了还好说,数据量一大差的钱谁补是吧,并且可能还会出现位数不够用问题,也可能出现前后台数字显示不一致问题

字符串:对于精度要求不高不会出现问题的,可以普通数字和字符串怎么放都行,对于对精度有一些要求的(无论是超大数字,还是小数点后面的要求精确),使用decimal保存,并且数据库也支持设置decimal类型,那么无论是使用还是给前端显示都很好,这个类型返回给客户端一般自动转化为字符串,如果保存到数据库中的是字符串,就是我们参与计算的过程中还需要转化一下(存入和取出都会有多余的转化操作,纯粹浪费性能了),

decial.js地址

我们直接导入即可

yarn add decimal.js

我们通过 new 操作,可以将 string | number | Decimal 类型转转化为 Decimal 类型

下面列出其中声明的类,其中比较常用的应该就是 abs、ceil、floor、add、sub、div、mul等了,具体的也可以点进去看看,或者下载完库,直接去他的类里面试一试,函数名字不是乱起的,直接根据英文前缀基本都能拿出来

下面直接贴一下声明的 Decimal 参考吧

export declare class Decimal {
  readonly d: number[];
  readonly e: number;
  readonly s: number;

  constructor(n: Decimal.Value);

  absoluteValue(): Decimal;
  abs(): Decimal;

  ceil(): Decimal;
  
  clampedTo(min: Decimal.Value, max: Decimal.Value): Decimal;
  clamp(min: Decimal.Value, max: Decimal.Value): Decimal;

  comparedTo(n: Decimal.Value): number;
  cmp(n: Decimal.Value): number;

  cosine(): Decimal;
  cos(): Decimal;

  cubeRoot(): Decimal;
  cbrt(): Decimal;

  decimalPlaces(): number;
  dp(): number;

  dividedBy(n: Decimal.Value): Decimal;
  div(n: Decimal.Value): Decimal;

  dividedToIntegerBy(n: Decimal.Value): Decimal;
  divToInt(n: Decimal.Value): Decimal;

  equals(n: Decimal.Value): boolean;
  eq(n: Decimal.Value): boolean;

  floor(): Decimal;

  greaterThan(n: Decimal.Value): boolean;
  gt(n: Decimal.Value): boolean;

  greaterThanOrEqualTo(n: Decimal.Value): boolean;
  gte(n: Decimal.Value): boolean;

  hyperbolicCosine(): Decimal;
  cosh(): Decimal;

  hyperbolicSine(): Decimal;
  sinh(): Decimal;

  hyperbolicTangent(): Decimal;
  tanh(): Decimal;

  inverseCosine(): Decimal;
  acos(): Decimal;

  inverseHyperbolicCosine(): Decimal;
  acosh(): Decimal;

  inverseHyperbolicSine(): Decimal;
  asinh(): Decimal;

  inverseHyperbolicTangent(): Decimal;
  atanh(): Decimal;

  inverseSine(): Decimal;
  asin(): Decimal;

  inverseTangent(): Decimal;
  atan(): Decimal;

  isFinite(): boolean;

  isInteger(): boolean;
  isInt(): boolean;

  isNaN(): boolean;

  isNegative(): boolean;
  isNeg(): boolean;

  isPositive(): boolean;
  isPos(): boolean;

  isZero(): boolean;

  lessThan(n: Decimal.Value): boolean;
  lt(n: Decimal.Value): boolean;

  lessThanOrEqualTo(n: Decimal.Value): boolean;
  lte(n: Decimal.Value): boolean;

  logarithm(n?: Decimal.Value): Decimal;
  log(n?: Decimal.Value): Decimal;

  minus(n: Decimal.Value): Decimal;
  sub(n: Decimal.Value): Decimal;

  modulo(n: Decimal.Value): Decimal;
  mod(n: Decimal.Value): Decimal;

  naturalExponential(): Decimal;
  exp(): Decimal;

  naturalLogarithm(): Decimal;
  ln(): Decimal;

  negated(): Decimal;
  neg(): Decimal;

  plus(n: Decimal.Value): Decimal;
  add(n: Decimal.Value): Decimal;

  precision(includeZeros?: boolean): number;
  sd(includeZeros?: boolean): number;

  round(): Decimal;

  sine() : Decimal;
  sin() : Decimal;

  squareRoot(): Decimal;
  sqrt(): Decimal;

  tangent() : Decimal;
  tan() : Decimal;

  times(n: Decimal.Value): Decimal;
  mul(n: Decimal.Value) : Decimal;

  toBinary(significantDigits?: number): string;
  toBinary(significantDigits: number, rounding: Decimal.Rounding): string;

  toDecimalPlaces(decimalPlaces?: number): Decimal;
  toDecimalPlaces(decimalPlaces: number, rounding: Decimal.Rounding): Decimal;
  toDP(decimalPlaces?: number): Decimal;
  toDP(decimalPlaces: number, rounding: Decimal.Rounding): Decimal;

  toExponential(decimalPlaces?: number): string;
  toExponential(decimalPlaces: number, rounding: Decimal.Rounding): string;

  toFixed(decimalPlaces?: number): string;
  toFixed(decimalPlaces: number, rounding: Decimal.Rounding): string;

  toFraction(max_denominator?: Decimal.Value): Decimal[];

  toHexadecimal(significantDigits?: number): string;
  toHexadecimal(significantDigits: number, rounding: Decimal.Rounding): string;
  toHex(significantDigits?: number): string;
  toHex(significantDigits: number, rounding?: Decimal.Rounding): string;

  toJSON(): string;

  toNearest(n: Decimal.Value, rounding?: Decimal.Rounding): Decimal;

  toNumber(): number;

  toOctal(significantDigits?: number): string;
  toOctal(significantDigits: number, rounding: Decimal.Rounding): string;

  toPower(n: Decimal.Value): Decimal;
  pow(n: Decimal.Value): Decimal;

  toPrecision(significantDigits?: number): string;
  toPrecision(significantDigits: number, rounding: Decimal.Rounding): string;

  toSignificantDigits(significantDigits?: number): Decimal;
  toSignificantDigits(significantDigits: number, rounding: Decimal.Rounding): Decimal;
  toSD(significantDigits?: number): Decimal;
  toSD(significantDigits: number, rounding: Decimal.Rounding): Decimal;

  toString(): string;

  truncated(): Decimal;
  trunc(): Decimal;

  valueOf(): string;

  static abs(n: Decimal.Value): Decimal;
  static acos(n: Decimal.Value): Decimal;
  static acosh(n: Decimal.Value): Decimal;
  static add(x: Decimal.Value, y: Decimal.Value): Decimal;
  static asin(n: Decimal.Value): Decimal;
  static asinh(n: Decimal.Value): Decimal;
  static atan(n: Decimal.Value): Decimal;
  static atanh(n: Decimal.Value): Decimal;
  static atan2(y: Decimal.Value, x: Decimal.Value): Decimal;
  static cbrt(n: Decimal.Value): Decimal;
  static ceil(n: Decimal.Value): Decimal;
  static clamp(n: Decimal.Value, min: Decimal.Value, max: Decimal.Value): Decimal;
  static clone(object?: Decimal.Config): Decimal.Constructor;
  static config(object: Decimal.Config): Decimal.Constructor;
  static cos(n: Decimal.Value): Decimal;
  static cosh(n: Decimal.Value): Decimal;
  static div(x: Decimal.Value, y: Decimal.Value): Decimal;
  static exp(n: Decimal.Value): Decimal;
  static floor(n: Decimal.Value): Decimal;
  static hypot(...n: Decimal.Value[]): Decimal;
  static isDecimal(object: any): object is Decimal;
  static ln(n: Decimal.Value): Decimal;
  static log(n: Decimal.Value, base?: Decimal.Value): Decimal;
  static log2(n: Decimal.Value): Decimal;
  static log10(n: Decimal.Value): Decimal;
  static max(...n: Decimal.Value[]): Decimal;
  static min(...n: Decimal.Value[]): Decimal;
  static mod(x: Decimal.Value, y: Decimal.Value): Decimal;
  static mul(x: Decimal.Value, y: Decimal.Value): Decimal;
  static noConflict(): Decimal.Constructor;   // Browser only
  static pow(base: Decimal.Value, exponent: Decimal.Value): Decimal;
  static random(significantDigits?: number): Decimal;
  static round(n: Decimal.Value): Decimal;
  static set(object: Decimal.Config): Decimal.Constructor;
  static sign(n: Decimal.Value): number;
  static sin(n: Decimal.Value): Decimal;
  static sinh(n: Decimal.Value): Decimal;
  static sqrt(n: Decimal.Value): Decimal;
  static sub(x: Decimal.Value, y: Decimal.Value): Decimal;
  static sum(...n: Decimal.Value[]): Decimal;
  static tan(n: Decimal.Value): Decimal;
  static tanh(n: Decimal.Value): Decimal;
  static trunc(n: Decimal.Value): Decimal;

  static readonly default?: Decimal.Constructor;
  static readonly Decimal?: Decimal.Constructor;

  static readonly precision: number;
  static readonly rounding: Decimal.Rounding;
  static readonly toExpNeg: number;
  static readonly toExpPos: number;
  static readonly minE: number;
  static readonly maxE: number;
  static readonly crypto: boolean;
  static readonly modulo: Decimal.Modulo;

  static readonly ROUND_UP: 0;
  static readonly ROUND_DOWN: 1;
  static readonly ROUND_CEIL: 2;
  static readonly ROUND_FLOOR: 3;
  static readonly ROUND_HALF_UP: 4;
  static readonly ROUND_HALF_DOWN: 5;
  static readonly ROUND_HALF_EVEN: 6;
  static readonly ROUND_HALF_CEIL: 7;
  static readonly ROUND_HALF_FLOOR: 8;
  static readonly EUCLID: 9;
}