@keplr-wallet/unit 0.12.0-alpha.0 → 0.12.0-alpha.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/decimal.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  import bigInteger from "big-integer";
2
- import { Int } from "./int";
3
- import { CoinUtils } from "./coin-utils";
2
+ import { Uint, Int } from "./int";
4
3
  import {
5
4
  exponentDecStringToDecString,
6
5
  isExponentDecString,
7
6
  isValidDecimalString,
8
7
  } from "./etc";
8
+ import { integerStringToUSLocaleString } from "./utils";
9
9
 
10
10
  export class Dec {
11
11
  public static readonly precision = 18;
@@ -19,9 +19,10 @@ export class Dec {
19
19
  "133499189745056880149688856635597007162669032647290798121690100488888732861290034376435130433535"
20
20
  );
21
21
 
22
- protected static readonly precisionMultipliers: {
23
- [key: string]: bigInteger.BigInteger | undefined;
24
- } = {};
22
+ public static readonly precisionMultipliers: Map<
23
+ string,
24
+ bigInteger.BigInteger
25
+ > = new Map();
25
26
  protected static calcPrecisionMultiplier(
26
27
  prec: number
27
28
  ): bigInteger.BigInteger {
@@ -31,20 +32,22 @@ export class Dec {
31
32
  if (prec > Dec.precision) {
32
33
  throw new Error("Too much precision");
33
34
  }
34
- if (Dec.precisionMultipliers[prec.toString()]) {
35
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
36
- return Dec.precisionMultipliers[prec.toString()]!;
35
+ const key = prec.toString();
36
+ const cached = Dec.precisionMultipliers.get(key);
37
+ if (cached) {
38
+ return cached;
37
39
  }
38
40
 
39
41
  const zerosToAdd = Dec.precision - prec;
40
42
  const multiplier = bigInteger(10).pow(zerosToAdd);
41
- Dec.precisionMultipliers[prec.toString()] = multiplier;
43
+ Dec.precisionMultipliers.set(key, multiplier);
42
44
  return multiplier;
43
45
  }
44
46
 
45
- protected static reduceDecimalsFromString(
46
- str: string
47
- ): { res: string; isDownToZero: boolean } {
47
+ protected static reduceDecimalsFromString(str: string): {
48
+ res: string;
49
+ isDownToZero: boolean;
50
+ } {
48
51
  const decimalPointIndex = str.indexOf(".");
49
52
  if (decimalPointIndex < 0) {
50
53
  return {
@@ -68,6 +71,11 @@ export class Dec {
68
71
  };
69
72
  }
70
73
 
74
+ static readonly zero = new Dec(0);
75
+ /** Smallest `Dec` with current precision. */
76
+ static readonly smallestDec = new Dec("1", Dec.precision);
77
+ static readonly one = new Dec(1);
78
+
71
79
  protected int: bigInteger.BigInteger;
72
80
 
73
81
  /**
@@ -76,7 +84,7 @@ export class Dec {
76
84
  * If int is string and contains dot(.), prec is ignored and automatically calculated.
77
85
  * @param prec - Precision
78
86
  */
79
- constructor(int: bigInteger.BigNumber | Int, prec: number = 0) {
87
+ constructor(int: bigInteger.BigNumber | Int | Uint, prec: number = 0) {
80
88
  if (typeof int === "number") {
81
89
  int = int.toString();
82
90
  }
@@ -108,6 +116,8 @@ export class Dec {
108
116
  this.int = bigInteger(int);
109
117
  } else if (int instanceof Int) {
110
118
  this.int = bigInteger(int.toString());
119
+ } else if (int instanceof Uint) {
120
+ this.int = bigInteger(int.toString());
111
121
  } else if (typeof int === "bigint") {
112
122
  this.int = bigInteger(int);
113
123
  } else {
@@ -213,6 +223,39 @@ export class Dec {
213
223
  return base.mul(tmp);
214
224
  }
215
225
 
226
+ public approxSqrt(): Dec {
227
+ return this.approxRoot(2);
228
+ }
229
+
230
+ public approxRoot(root: number, maxIters = 300): Dec {
231
+ if (this.isNegative()) {
232
+ return this.neg().approxRoot(root).neg();
233
+ }
234
+
235
+ if (root === 1 || this.isZero() || this.equals(Dec.one)) {
236
+ return this;
237
+ }
238
+
239
+ if (root === 0) {
240
+ return Dec.one;
241
+ }
242
+
243
+ let [guess, delta] = [Dec.one, Dec.one];
244
+ for (let i = 0; delta.abs().gt(Dec.smallestDec) && i < maxIters; i++) {
245
+ let prev = guess.pow(new Int(root - 1));
246
+ if (prev.isZero()) {
247
+ prev = Dec.smallestDec;
248
+ }
249
+ delta = this.quo(prev);
250
+ delta = delta.sub(guess);
251
+ delta = delta.quoTruncate(new Dec(root));
252
+
253
+ guess = guess.add(delta);
254
+ }
255
+
256
+ return guess;
257
+ }
258
+
216
259
  public mul(d2: Dec): Dec {
217
260
  return new Dec(this.mulRaw(d2).chopPrecisionAndRound(), Dec.precision);
218
261
  }
@@ -221,6 +264,10 @@ export class Dec {
221
264
  return new Dec(this.mulRaw(d2).chopPrecisionAndTruncate(), Dec.precision);
222
265
  }
223
266
 
267
+ public mulRoundUp(d2: Dec): Dec {
268
+ return new Dec(this.mulRaw(d2).chopPrecisionAndRoundUp(), Dec.precision);
269
+ }
270
+
224
271
  protected mulRaw(d2: Dec): Dec {
225
272
  return new Dec(this.int.multiply(d2.int), Dec.precision);
226
273
  }
@@ -336,9 +383,7 @@ export class Dec {
336
383
  !(integer.eq(bigInteger(0)) && fractionStr.length === 0);
337
384
 
338
385
  const integerStr = locale
339
- ? // eslint-disable-next-line @typescript-eslint/ban-ts-comment
340
- // @ts-ignore
341
- CoinUtils.integerStringToUSLocaleString(integer.toString())
386
+ ? integerStringToUSLocaleString(integer.toString())
342
387
  : integer.toString();
343
388
 
344
389
  return `${isNegative ? "-" : ""}${integerStr}${
@@ -370,3 +415,11 @@ export class Dec {
370
415
  return new Dec(this.chopPrecisionAndTruncate(), 0);
371
416
  }
372
417
  }
418
+
419
+ Int.prototype.toDec = function (): Dec {
420
+ return new Dec(this);
421
+ };
422
+
423
+ Uint.prototype.toDec = function (): Dec {
424
+ return new Dec(this);
425
+ };
package/src/int.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import bigInteger from "big-integer";
2
- import { Dec } from "./decimal";
2
+ import type { Dec } from "./decimal";
3
3
  import {
4
4
  exponentDecStringToDecString,
5
5
  isExponentDecString,
@@ -14,6 +14,8 @@ export class Int {
14
14
 
15
15
  protected int: bigInteger.BigInteger;
16
16
 
17
+ declare toDec: () => Dec;
18
+
17
19
  /**
18
20
  * @param int - Parse a number | bigInteger | string into a bigInt.
19
21
  */
@@ -119,10 +121,6 @@ export class Int {
119
121
  return new Int(this.int.pow(i.toBigNumber()));
120
122
  }
121
123
 
122
- public toDec(): Dec {
123
- return new Dec(this);
124
- }
125
-
126
124
  public toBigNumber(): bigInteger.BigInteger {
127
125
  return this.int;
128
126
  }
@@ -131,6 +129,8 @@ export class Int {
131
129
  export class Uint {
132
130
  protected uint: bigInteger.BigInteger;
133
131
 
132
+ declare toDec: () => Dec;
133
+
134
134
  /**
135
135
  * @param uint - Parse a number | bigInteger | string into a bigUint.
136
136
  */
@@ -220,10 +220,6 @@ export class Uint {
220
220
  return new Uint(this.uint.pow(i.toBigNumber()));
221
221
  }
222
222
 
223
- public toDec(): Dec {
224
- return new Dec(new Int(this.toString()));
225
- }
226
-
227
223
  public toBigNumber(): bigInteger.BigInteger {
228
224
  return this.uint;
229
225
  }
package/src/utils.ts ADDED
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Change the non-locale integer string to locale string.
3
+ * Only support en-US format.
4
+ * This method uses the BigInt if the environment supports the BigInt.
5
+ * @param numberStr
6
+ */
7
+ export function integerStringToUSLocaleString(numberStr: string): string {
8
+ if (numberStr.indexOf(".") >= 0) {
9
+ throw new Error(`${numberStr} is not integer`);
10
+ }
11
+
12
+ if (typeof BigInt !== "undefined") {
13
+ return BigInt(numberStr).toLocaleString("en-US");
14
+ }
15
+
16
+ const integer = numberStr;
17
+
18
+ const chunks: string[] = [];
19
+ for (let i = integer.length; i > 0; i -= 3) {
20
+ chunks.push(integer.slice(Math.max(0, i - 3), i));
21
+ }
22
+
23
+ return chunks.reverse().join(",");
24
+ }