@keplr-wallet/unit 0.9.9 → 0.9.11-rc.2

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.
Files changed (76) hide show
  1. package/build/coin-pretty.d.ts +13 -3
  2. package/build/coin-pretty.js +36 -25
  3. package/build/coin-pretty.js.map +1 -1
  4. package/build/coin-pretty.spec.js +194 -9
  5. package/build/coin-pretty.spec.js.map +1 -1
  6. package/build/coin-utils.js +8 -4
  7. package/build/coin-utils.js.map +1 -1
  8. package/build/coin-utils.spec.js +16 -0
  9. package/build/coin-utils.spec.js.map +1 -1
  10. package/build/coin.js +1 -1
  11. package/build/coin.js.map +1 -1
  12. package/build/coin.spec.js +15 -0
  13. package/build/coin.spec.js.map +1 -1
  14. package/build/dec-utils.d.ts +8 -1
  15. package/build/dec-utils.js +22 -20
  16. package/build/dec-utils.js.map +1 -1
  17. package/build/dec-utils.spec.js +19 -0
  18. package/build/dec-utils.spec.js.map +1 -1
  19. package/build/decimal.d.ts +22 -9
  20. package/build/decimal.js +102 -29
  21. package/build/decimal.js.map +1 -1
  22. package/build/decimal.spec.js +296 -3
  23. package/build/decimal.spec.js.map +1 -1
  24. package/build/etc.d.ts +4 -0
  25. package/build/etc.js +63 -0
  26. package/build/etc.js.map +1 -0
  27. package/build/etc.spec.d.ts +1 -0
  28. package/build/etc.spec.js +66 -0
  29. package/build/etc.spec.js.map +1 -0
  30. package/build/index.d.ts +1 -0
  31. package/build/index.js +1 -0
  32. package/build/index.js.map +1 -1
  33. package/build/int-pretty.d.ts +16 -4
  34. package/build/int-pretty.js +74 -36
  35. package/build/int-pretty.js.map +1 -1
  36. package/build/int-pretty.spec.js +261 -94
  37. package/build/int-pretty.spec.js.map +1 -1
  38. package/build/int.d.ts +17 -12
  39. package/build/int.js +69 -16
  40. package/build/int.js.map +1 -1
  41. package/build/int.spec.d.ts +1 -0
  42. package/build/int.spec.js +161 -0
  43. package/build/int.spec.js.map +1 -0
  44. package/build/price-pretty.d.ts +13 -3
  45. package/build/price-pretty.js +37 -26
  46. package/build/price-pretty.js.map +1 -1
  47. package/build/price-pretty.spec.js +59 -2
  48. package/build/price-pretty.spec.js.map +1 -1
  49. package/build/rate-pretty.d.ts +57 -0
  50. package/build/rate-pretty.js +128 -0
  51. package/build/rate-pretty.js.map +1 -0
  52. package/build/rate-pretty.spec.d.ts +1 -0
  53. package/build/rate-pretty.spec.js +38 -0
  54. package/build/rate-pretty.spec.js.map +1 -0
  55. package/package.json +3 -3
  56. package/src/coin-pretty.spec.ts +304 -11
  57. package/src/coin-pretty.ts +56 -29
  58. package/src/coin-utils.spec.ts +32 -0
  59. package/src/coin-utils.ts +12 -4
  60. package/src/coin.spec.ts +20 -0
  61. package/src/coin.ts +1 -1
  62. package/src/dec-utils.spec.ts +39 -0
  63. package/src/dec-utils.ts +25 -20
  64. package/src/decimal.spec.ts +361 -3
  65. package/src/decimal.ts +135 -56
  66. package/src/etc.spec.ts +73 -0
  67. package/src/etc.ts +70 -0
  68. package/src/index.ts +1 -0
  69. package/src/int-pretty.spec.ts +296 -101
  70. package/src/int-pretty.ts +87 -34
  71. package/src/int.spec.ts +212 -0
  72. package/src/int.ts +94 -26
  73. package/src/price-pretty.spec.ts +106 -2
  74. package/src/price-pretty.ts +50 -30
  75. package/src/rate-pretty.spec.ts +52 -0
  76. package/src/rate-pretty.ts +165 -0
package/src/decimal.ts CHANGED
@@ -1,19 +1,34 @@
1
1
  import bigInteger from "big-integer";
2
2
  import { Int } from "./int";
3
3
  import { CoinUtils } from "./coin-utils";
4
+ import {
5
+ exponentDecStringToDecString,
6
+ isExponentDecString,
7
+ isValidDecimalString,
8
+ } from "./etc";
4
9
 
5
10
  export class Dec {
6
- public static readonly precision: bigInteger.BigInteger = bigInteger(18);
7
- private static readonly precisionMultipliers: {
11
+ public static readonly precision = 18;
12
+ // Bytes required to represent the above precision is 18.
13
+ // Ceiling[Log2[999 999 999 999 999 999]]
14
+ protected static readonly decimalPrecisionBits = 60;
15
+ // Max bit length for `Dec` is 256 + 60(decimalPrecisionBits)
16
+ // The int in the `Dec` is handled as integer assuming that it has 18 precision.
17
+ // (2 ** (256 + 60) - 1)
18
+ protected static readonly maxDec = bigInteger(
19
+ "133499189745056880149688856635597007162669032647290798121690100488888732861290034376435130433535"
20
+ );
21
+
22
+ protected static readonly precisionMultipliers: {
8
23
  [key: string]: bigInteger.BigInteger | undefined;
9
24
  } = {};
10
- private static calcPrecisionMultiplier(
11
- prec: bigInteger.BigInteger
25
+ protected static calcPrecisionMultiplier(
26
+ prec: number
12
27
  ): bigInteger.BigInteger {
13
- if (prec.lt(bigInteger(0))) {
28
+ if (prec < 0) {
14
29
  throw new Error("Invalid prec");
15
30
  }
16
- if (prec.gt(Dec.precision)) {
31
+ if (prec > Dec.precision) {
17
32
  throw new Error("Too much precision");
18
33
  }
19
34
  if (Dec.precisionMultipliers[prec.toString()]) {
@@ -21,13 +36,39 @@ export class Dec {
21
36
  return Dec.precisionMultipliers[prec.toString()]!;
22
37
  }
23
38
 
24
- const zerosToAdd = Dec.precision.minus(prec);
39
+ const zerosToAdd = Dec.precision - prec;
25
40
  const multiplier = bigInteger(10).pow(zerosToAdd);
26
41
  Dec.precisionMultipliers[prec.toString()] = multiplier;
27
42
  return multiplier;
28
43
  }
29
44
 
30
- private int: bigInteger.BigInteger;
45
+ protected static reduceDecimalsFromString(
46
+ str: string
47
+ ): { res: string; isDownToZero: boolean } {
48
+ const decimalPointIndex = str.indexOf(".");
49
+ if (decimalPointIndex < 0) {
50
+ return {
51
+ res: str,
52
+ isDownToZero: false,
53
+ };
54
+ }
55
+
56
+ const exceededDecimals = str.length - 1 - decimalPointIndex - Dec.precision;
57
+ if (exceededDecimals <= 0) {
58
+ return {
59
+ res: str,
60
+ isDownToZero: false,
61
+ };
62
+ }
63
+
64
+ const res = str.slice(0, str.length - exceededDecimals);
65
+ return {
66
+ res,
67
+ isDownToZero: /^[0.]*$/.test(res),
68
+ };
69
+ }
70
+
71
+ protected int: bigInteger.BigInteger;
31
72
 
32
73
  /**
33
74
  * Create a new Dec from integer with decimal place at prec
@@ -36,20 +77,35 @@ export class Dec {
36
77
  * @param prec - Precision
37
78
  */
38
79
  constructor(int: bigInteger.BigNumber | Int, prec: number = 0) {
80
+ if (typeof int === "number") {
81
+ int = int.toString();
82
+ }
83
+
39
84
  if (typeof int === "string") {
40
85
  if (int.length === 0) {
41
86
  throw new Error("empty string");
42
87
  }
43
- if (!/^(-?\d+\.\d+)$|^(-?\d+)$/.test(int)) {
44
- throw new Error(`invalid decimal: ${int}`);
88
+ if (!isValidDecimalString(int)) {
89
+ if (isExponentDecString(int)) {
90
+ int = exponentDecStringToDecString(int);
91
+ } else {
92
+ throw new Error(`invalid decimal: ${int}`);
93
+ }
45
94
  }
95
+ // Even if an input with more than 18 decimals, it does not throw an error and ignores the rest.
96
+ const reduced = Dec.reduceDecimalsFromString(int);
97
+ if (reduced.isDownToZero) {
98
+ // However, as a result, if the input becomes 0, a problem may occur in mul or quo. In this case, print a warning.
99
+ console.log(
100
+ `WARNING: Got ${int}. Dec can only handle up to 18 decimals. However, since the decimal point of the input exceeds 18 digits, the remainder is discarded. As a result, input becomes 0.`
101
+ );
102
+ }
103
+ int = reduced.res;
46
104
  if (int.indexOf(".") >= 0) {
47
105
  prec = int.length - int.indexOf(".") - 1;
48
106
  int = int.replace(".", "");
49
107
  }
50
108
  this.int = bigInteger(int);
51
- } else if (typeof int === "number") {
52
- this.int = bigInteger(int);
53
109
  } else if (int instanceof Int) {
54
110
  this.int = bigInteger(int.toString());
55
111
  } else if (typeof int === "bigint") {
@@ -58,7 +114,15 @@ export class Dec {
58
114
  this.int = bigInteger(int);
59
115
  }
60
116
 
61
- this.int = this.int.multiply(Dec.calcPrecisionMultiplier(bigInteger(prec)));
117
+ this.int = this.int.multiply(Dec.calcPrecisionMultiplier(prec));
118
+
119
+ this.checkBitLen();
120
+ }
121
+
122
+ protected checkBitLen(): void {
123
+ if (this.int.abs().gt(Dec.maxDec)) {
124
+ throw new Error(`Integer out of range ${this.int.toString()}`);
125
+ }
62
126
  }
63
127
 
64
128
  public isZero(): boolean {
@@ -109,73 +173,80 @@ export class Dec {
109
173
  * reverse the decimal sign.
110
174
  */
111
175
  public neg(): Dec {
112
- return new Dec(this.int.negate(), Dec.precision.toJSNumber());
176
+ return new Dec(this.int.negate(), Dec.precision);
113
177
  }
114
178
 
115
179
  /**
116
180
  * Returns the absolute value of a decimals.
117
181
  */
118
182
  public abs(): Dec {
119
- return new Dec(this.int.abs(), Dec.precision.toJSNumber());
183
+ return new Dec(this.int.abs(), Dec.precision);
120
184
  }
121
185
 
122
186
  public add(d2: Dec): Dec {
123
- return new Dec(this.int.add(d2.int), Dec.precision.toJSNumber());
187
+ return new Dec(this.int.add(d2.int), Dec.precision);
124
188
  }
125
189
 
126
190
  public sub(d2: Dec): Dec {
127
- return new Dec(this.int.subtract(d2.int), Dec.precision.toJSNumber());
191
+ return new Dec(this.int.subtract(d2.int), Dec.precision);
192
+ }
193
+
194
+ public pow(n: Int): Dec {
195
+ if (n.isZero()) {
196
+ return new Dec(1);
197
+ }
198
+
199
+ if (n.isNegative()) {
200
+ return new Dec(1).quo(this.pow(n.abs()));
201
+ }
202
+
203
+ let base = new Dec(this.int, Dec.precision);
204
+ let tmp = new Dec(1);
205
+
206
+ for (let i = n; i.gt(new Int(1)); i = i.div(new Int(2))) {
207
+ if (!i.mod(new Int(2)).isZero()) {
208
+ tmp = tmp.mul(base);
209
+ }
210
+ base = base.mul(base);
211
+ }
212
+
213
+ return base.mul(tmp);
128
214
  }
129
215
 
130
216
  public mul(d2: Dec): Dec {
131
- return new Dec(
132
- this.mulRaw(d2).chopPrecisionAndRound(),
133
- Dec.precision.toJSNumber()
134
- );
217
+ return new Dec(this.mulRaw(d2).chopPrecisionAndRound(), Dec.precision);
135
218
  }
136
219
 
137
220
  public mulTruncate(d2: Dec): Dec {
138
- return new Dec(
139
- this.mulRaw(d2).chopPrecisionAndTruncate(),
140
- Dec.precision.toJSNumber()
141
- );
221
+ return new Dec(this.mulRaw(d2).chopPrecisionAndTruncate(), Dec.precision);
142
222
  }
143
223
 
144
- private mulRaw(d2: Dec): Dec {
145
- return new Dec(this.int.multiply(d2.int), Dec.precision.toJSNumber());
224
+ protected mulRaw(d2: Dec): Dec {
225
+ return new Dec(this.int.multiply(d2.int), Dec.precision);
146
226
  }
147
227
 
148
228
  public quo(d2: Dec): Dec {
149
- return new Dec(
150
- this.quoRaw(d2).chopPrecisionAndRound(),
151
- Dec.precision.toJSNumber()
152
- );
229
+ return new Dec(this.quoRaw(d2).chopPrecisionAndRound(), Dec.precision);
153
230
  }
154
231
 
155
232
  public quoTruncate(d2: Dec): Dec {
156
- return new Dec(
157
- this.quoRaw(d2).chopPrecisionAndTruncate(),
158
- Dec.precision.toJSNumber()
159
- );
233
+ return new Dec(this.quoRaw(d2).chopPrecisionAndTruncate(), Dec.precision);
160
234
  }
161
235
 
162
236
  public quoRoundUp(d2: Dec): Dec {
163
- return new Dec(
164
- this.quoRaw(d2).chopPrecisionAndRoundUp(),
165
- Dec.precision.toJSNumber()
166
- );
237
+ return new Dec(this.quoRaw(d2).chopPrecisionAndRoundUp(), Dec.precision);
167
238
  }
168
239
 
169
- private quoRaw(d2: Dec): Dec {
170
- const precision = Dec.calcPrecisionMultiplier(bigInteger(0));
240
+ protected quoRaw(d2: Dec): Dec {
241
+ const precision = Dec.calcPrecisionMultiplier(0);
171
242
 
172
243
  // multiply precision twice
173
244
  const mul = this.int.multiply(precision).multiply(precision);
174
- return new Dec(mul.divide(d2.int), Dec.precision.toJSNumber());
245
+ return new Dec(mul.divide(d2.int), Dec.precision);
175
246
  }
176
247
 
177
248
  public isInteger(): boolean {
178
- const precision = Dec.calcPrecisionMultiplier(bigInteger(0));
249
+ const precision = Dec.calcPrecisionMultiplier(0);
179
250
  return this.int.remainder(precision).equals(bigInteger(0));
180
251
  }
181
252
 
@@ -183,7 +254,7 @@ export class Dec {
183
254
  * Remove a Precision amount of rightmost digits and perform bankers rounding
184
255
  * on the remainder (gaussian rounding) on the digits which have been removed.
185
256
  */
186
- private chopPrecisionAndRound(): bigInteger.BigInteger {
257
+ protected chopPrecisionAndRound(): bigInteger.BigInteger {
187
258
  // Remove the negative and add it back when returning
188
259
  if (this.isNegative()) {
189
260
  const absoulteDec = this.abs();
@@ -191,7 +262,7 @@ export class Dec {
191
262
  return choped.negate();
192
263
  }
193
264
 
194
- const precision = Dec.calcPrecisionMultiplier(bigInteger(0));
265
+ const precision = Dec.calcPrecisionMultiplier(0);
195
266
  const fivePrecision = precision.divide(bigInteger(2));
196
267
 
197
268
  // Get the truncated quotient and remainder
@@ -216,7 +287,7 @@ export class Dec {
216
287
  }
217
288
  }
218
289
 
219
- private chopPrecisionAndRoundUp(): bigInteger.BigInteger {
290
+ protected chopPrecisionAndRoundUp(): bigInteger.BigInteger {
220
291
  // Remove the negative and add it back when returning
221
292
  if (this.isNegative()) {
222
293
  const absoulteDec = this.abs();
@@ -225,7 +296,7 @@ export class Dec {
225
296
  return choped.negate();
226
297
  }
227
298
 
228
- const precision = Dec.calcPrecisionMultiplier(bigInteger(0));
299
+ const precision = Dec.calcPrecisionMultiplier(0);
229
300
 
230
301
  // Get the truncated quotient and remainder
231
302
  const { quotient, remainder } = this.int.divmod(precision);
@@ -241,25 +312,21 @@ export class Dec {
241
312
  /**
242
313
  * Similar to chopPrecisionAndRound, but always rounds down
243
314
  */
244
- private chopPrecisionAndTruncate(): bigInteger.BigInteger {
245
- const precision = Dec.calcPrecisionMultiplier(bigInteger(0));
315
+ protected chopPrecisionAndTruncate(): bigInteger.BigInteger {
316
+ const precision = Dec.calcPrecisionMultiplier(0);
246
317
  return this.int.divide(precision);
247
318
  }
248
319
 
249
320
  public toString(
250
- prec: number = Dec.precision.toJSNumber(),
321
+ prec: number = Dec.precision,
251
322
  locale: boolean = false
252
323
  ): string {
253
- const precision = Dec.calcPrecisionMultiplier(bigInteger(0));
324
+ const precision = Dec.calcPrecisionMultiplier(0);
254
325
  const int = this.int.abs();
255
326
  const { quotient: integer, remainder: fraction } = int.divmod(precision);
256
327
 
257
328
  let fractionStr = fraction.toString(10);
258
- for (
259
- let i = 0, l = fractionStr.length;
260
- i < Dec.precision.toJSNumber() - l;
261
- i++
262
- ) {
329
+ for (let i = 0, l = fractionStr.length; i < Dec.precision - l; i++) {
263
330
  fractionStr = "0" + fractionStr;
264
331
  }
265
332
  fractionStr = fractionStr.substring(0, prec);
@@ -290,4 +357,16 @@ export class Dec {
290
357
  public truncate(): Int {
291
358
  return new Int(this.chopPrecisionAndTruncate());
292
359
  }
360
+
361
+ public roundDec(): Dec {
362
+ return new Dec(this.chopPrecisionAndRound(), 0);
363
+ }
364
+
365
+ public roundUpDec(): Dec {
366
+ return new Dec(this.chopPrecisionAndRoundUp(), 0);
367
+ }
368
+
369
+ public truncateDec(): Dec {
370
+ return new Dec(this.chopPrecisionAndTruncate(), 0);
371
+ }
293
372
  }
@@ -0,0 +1,73 @@
1
+ import { exponentDecStringToDecString } from "./etc";
2
+
3
+ describe("Test etc utils", () => {
4
+ it("Test exponentDecStringToDecString", () => {
5
+ expect(exponentDecStringToDecString("1e+0")).toBe("1");
6
+ expect(exponentDecStringToDecString("1e+1")).toBe("10");
7
+ expect(exponentDecStringToDecString("123e+1")).toBe("1230");
8
+ expect(exponentDecStringToDecString("123e+2")).toBe("12300");
9
+ expect(exponentDecStringToDecString("123e+3")).toBe("123000");
10
+ expect(exponentDecStringToDecString("123e+4")).toBe("1230000");
11
+
12
+ expect(exponentDecStringToDecString("-1e+0")).toBe("-1");
13
+ expect(exponentDecStringToDecString("-1e+1")).toBe("-10");
14
+ expect(exponentDecStringToDecString("-123e+1")).toBe("-1230");
15
+ expect(exponentDecStringToDecString("-123e+2")).toBe("-12300");
16
+ expect(exponentDecStringToDecString("-123e+3")).toBe("-123000");
17
+ expect(exponentDecStringToDecString("-123e+4")).toBe("-1230000");
18
+
19
+ expect(exponentDecStringToDecString("1.2e+0")).toBe("1.2");
20
+ expect(exponentDecStringToDecString("1.2e+1")).toBe("12");
21
+ expect(exponentDecStringToDecString("1.23e+1")).toBe("12.3");
22
+ expect(exponentDecStringToDecString("1.23e+2")).toBe("123");
23
+ expect(exponentDecStringToDecString("1.23e+3")).toBe("1230");
24
+ expect(exponentDecStringToDecString("1.23e+4")).toBe("12300");
25
+
26
+ expect(exponentDecStringToDecString("-1.2e+0")).toBe("-1.2");
27
+ expect(exponentDecStringToDecString("-1.2e+1")).toBe("-12");
28
+ expect(exponentDecStringToDecString("-1.23e+1")).toBe("-12.3");
29
+ expect(exponentDecStringToDecString("-1.23e+2")).toBe("-123");
30
+ expect(exponentDecStringToDecString("-1.23e+3")).toBe("-1230");
31
+ expect(exponentDecStringToDecString("-1.23e+4")).toBe("-12300");
32
+
33
+ expect(exponentDecStringToDecString("1e-0")).toBe("1");
34
+ expect(exponentDecStringToDecString("1e-1")).toBe("0.1");
35
+ expect(exponentDecStringToDecString("123e-1")).toBe("12.3");
36
+ expect(exponentDecStringToDecString("123e-2")).toBe("1.23");
37
+ expect(exponentDecStringToDecString("123e-3")).toBe("0.123");
38
+ expect(exponentDecStringToDecString("123e-4")).toBe("0.0123");
39
+
40
+ expect(exponentDecStringToDecString("-1e-0")).toBe("-1");
41
+ expect(exponentDecStringToDecString("-1e-1")).toBe("-0.1");
42
+ expect(exponentDecStringToDecString("-123e-1")).toBe("-12.3");
43
+ expect(exponentDecStringToDecString("-123e-2")).toBe("-1.23");
44
+ expect(exponentDecStringToDecString("-123e-3")).toBe("-0.123");
45
+ expect(exponentDecStringToDecString("-123e-4")).toBe("-0.0123");
46
+
47
+ expect(exponentDecStringToDecString("1.2e-0")).toBe("1.2");
48
+ expect(exponentDecStringToDecString("1.2e-1")).toBe("0.12");
49
+ expect(exponentDecStringToDecString("1.23e-1")).toBe("0.123");
50
+ expect(exponentDecStringToDecString("1.23e-2")).toBe("0.0123");
51
+ expect(exponentDecStringToDecString("1.23e-3")).toBe("0.00123");
52
+ expect(exponentDecStringToDecString("1.23e-4")).toBe("0.000123");
53
+
54
+ expect(exponentDecStringToDecString("-1.2e-0")).toBe("-1.2");
55
+ expect(exponentDecStringToDecString("-1.2e-1")).toBe("-0.12");
56
+ expect(exponentDecStringToDecString("-1.23e-1")).toBe("-0.123");
57
+ expect(exponentDecStringToDecString("-1.23e-2")).toBe("-0.0123");
58
+ expect(exponentDecStringToDecString("-1.23e-3")).toBe("-0.00123");
59
+ expect(exponentDecStringToDecString("-1.23e-4")).toBe("-0.000123");
60
+
61
+ expect(exponentDecStringToDecString("0.00123e+1")).toBe("0.0123");
62
+ expect(exponentDecStringToDecString("0.00123e-1")).toBe("0.000123");
63
+ expect(exponentDecStringToDecString("0.00123e+4")).toBe("12.3");
64
+ expect(exponentDecStringToDecString("0.00123e-4")).toBe("0.000000123");
65
+ expect(exponentDecStringToDecString("1234.567e+2")).toBe("123456.7");
66
+ expect(exponentDecStringToDecString("1234.567e+3")).toBe("1234567");
67
+ expect(exponentDecStringToDecString("1234.567e+4")).toBe("12345670");
68
+ expect(exponentDecStringToDecString("1234.567e+10")).toBe("12345670000000");
69
+
70
+ expect(exponentDecStringToDecString("-0.00123e+1")).toBe("-0.0123");
71
+ expect(exponentDecStringToDecString("-0.00123e-1")).toBe("-0.000123");
72
+ });
73
+ });
package/src/etc.ts ADDED
@@ -0,0 +1,70 @@
1
+ const regexIntString = /^-?\d+$/;
2
+ const regexDecString = /^-?\d+.?\d*$/;
3
+ const regexExponentDecString = /^(-?)([\d.]+)e([-+])([\d]+)$/;
4
+
5
+ export function isValidIntegerString(str: string): boolean {
6
+ return regexIntString.test(str);
7
+ }
8
+
9
+ export function isValidDecimalString(str: string): boolean {
10
+ return regexDecString.test(str);
11
+ }
12
+
13
+ export function isExponentDecString(str: string): boolean {
14
+ return regexExponentDecString.test(str);
15
+ }
16
+
17
+ function makeZerosStr(len: number): string {
18
+ let r = "";
19
+ for (let i = 0; i < len; i++) {
20
+ r += "0";
21
+ }
22
+ return r;
23
+ }
24
+
25
+ function removeHeadZeros(str: string): string {
26
+ while (str.length > 0 && str[0] === "0") {
27
+ str = str.slice(1);
28
+ }
29
+ return str;
30
+ }
31
+
32
+ export function exponentDecStringToDecString(str: string): string {
33
+ const split = str.split(regexExponentDecString);
34
+ if (split.length !== 6) {
35
+ return str;
36
+ }
37
+
38
+ const isNeg = split[1] === "-";
39
+ let numStr = split[2];
40
+ const numStrFractionIndex = numStr.indexOf(".");
41
+
42
+ const exponentStr = split[4];
43
+ let exponent = parseInt(exponentStr) * (split[3] === "-" ? -1 : 1);
44
+
45
+ if (numStrFractionIndex >= 0) {
46
+ const fractionLen = numStr.length - numStrFractionIndex - 1;
47
+ exponent = exponent - fractionLen;
48
+
49
+ numStr = removeHeadZeros(numStr.replace(".", ""));
50
+ }
51
+
52
+ const prefix = isNeg ? "-" : "";
53
+
54
+ if (exponent < 0) {
55
+ if (numStr.length > -exponent) {
56
+ const fractionPosition = numStr.length + exponent;
57
+
58
+ return (
59
+ prefix +
60
+ (numStr.slice(0, fractionPosition) +
61
+ "." +
62
+ numStr.slice(fractionPosition))
63
+ );
64
+ }
65
+
66
+ return prefix + "0." + makeZerosStr(-(numStr.length + exponent)) + numStr;
67
+ } else {
68
+ return prefix + numStr + makeZerosStr(exponent);
69
+ }
70
+ }
package/src/index.ts CHANGED
@@ -6,3 +6,4 @@ export * from "./decimal";
6
6
  export * from "./coin-utils";
7
7
  export * from "./dec-utils";
8
8
  export * from "./price-pretty";
9
+ export * from "./rate-pretty";