@pioneer-platform/helpers 4.0.3 → 4.0.5
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/__tests__/test-module.js +25 -1
- package/lib/modules/assetValue.d.ts +9 -9
- package/lib/modules/assetValue.js +254 -211
- package/lib/modules/bigIntArithmetics.js +477 -204
- package/package.json +1 -1
- package/src/modules/assetValue.ts +273 -308
- package/src/modules/bigIntArithmetics.ts +495 -247
@@ -1,6 +1,8 @@
|
|
1
1
|
import { BaseDecimal } from '@coinmasters/types';
|
2
2
|
import type { SwapKitNumber } from './swapKitNumber';
|
3
3
|
|
4
|
+
const TAG = " | BigIntArithmetics | ";
|
5
|
+
|
4
6
|
type NumberPrimitivesType = {
|
5
7
|
bigint: bigint;
|
6
8
|
number: number;
|
@@ -15,30 +17,45 @@ type AllowedNumberTypes = 'bigint' | 'number' | 'string';
|
|
15
17
|
const DEFAULT_DECIMAL = 8;
|
16
18
|
|
17
19
|
const bigintPow = (base: bigint, exponent: number): bigint => {
|
18
|
-
let
|
19
|
-
|
20
|
-
|
21
|
-
|
20
|
+
let tag = TAG + " | bigintPow | ";
|
21
|
+
try {
|
22
|
+
let result = BigInt(1);
|
23
|
+
while (exponent > 0) {
|
24
|
+
if (exponent % 2 === 1) {
|
25
|
+
result *= base;
|
26
|
+
}
|
27
|
+
base *= base;
|
28
|
+
exponent = Math.floor(exponent / 2);
|
22
29
|
}
|
23
|
-
|
24
|
-
|
30
|
+
return result;
|
31
|
+
} catch (error) {
|
32
|
+
console.error(tag + 'Error in bigintPow:', error);
|
33
|
+
return BigInt(1);
|
25
34
|
}
|
26
|
-
return result;
|
27
35
|
};
|
28
36
|
|
29
37
|
const toMultiplier = (decimal: number): bigint => {
|
30
|
-
|
38
|
+
let tag = TAG + " | toMultiplier | ";
|
39
|
+
console.log(tag + 'input decimal:', decimal);
|
31
40
|
try {
|
32
41
|
const result = bigintPow(BigInt(10), decimal);
|
33
|
-
console.log('
|
42
|
+
console.log(tag + 'result:', result);
|
34
43
|
return result;
|
35
44
|
} catch (error) {
|
36
|
-
console.error('Error in toMultiplier:', error);
|
45
|
+
console.error(tag + 'Error in toMultiplier:', error);
|
37
46
|
return BigInt(10);
|
38
47
|
}
|
39
48
|
};
|
40
49
|
|
41
|
-
const decimalFromMultiplier = (multiplier: bigint): number =>
|
50
|
+
const decimalFromMultiplier = (multiplier: bigint): number => {
|
51
|
+
let tag = TAG + " | decimalFromMultiplier | ";
|
52
|
+
try {
|
53
|
+
return Math.log10(Number(multiplier));
|
54
|
+
} catch (error) {
|
55
|
+
console.error(tag + 'Error in decimalFromMultiplier:', error);
|
56
|
+
return 0;
|
57
|
+
}
|
58
|
+
};
|
42
59
|
|
43
60
|
export function formatBigIntToSafeValue({
|
44
61
|
value,
|
@@ -49,42 +66,107 @@ export function formatBigIntToSafeValue({
|
|
49
66
|
bigIntDecimal?: number;
|
50
67
|
decimal?: number;
|
51
68
|
}): string {
|
52
|
-
|
53
|
-
|
69
|
+
let tag = TAG + " | formatBigIntToSafeValue | ";
|
70
|
+
try {
|
71
|
+
console.log(tag, 'value:', value, 'bigIntDecimal:', bigIntDecimal, 'decimal:', decimal);
|
72
|
+
// Check if the value is negative and throw an error if true
|
73
|
+
if (value < BigInt(0)) {
|
74
|
+
throw new Error(tag + 'Negative value is not allowed');
|
75
|
+
}
|
54
76
|
|
55
|
-
|
77
|
+
// Convert bigint to string and handle potential negative sign
|
78
|
+
let valueString = value.toString();
|
56
79
|
|
57
|
-
|
58
|
-
|
59
|
-
}
|
80
|
+
// Calculate padding length required to match the specified decimal places
|
81
|
+
const padLength = decimal - (valueString.length - 1);
|
60
82
|
|
61
|
-
|
62
|
-
|
83
|
+
// Pad the value string with leading zeros if necessary
|
84
|
+
if (padLength > 0) {
|
85
|
+
valueString = '0'.repeat(padLength) + valueString;
|
86
|
+
}
|
63
87
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
88
|
+
// Determine the position of the decimal point
|
89
|
+
const decimalIndex = valueString.length - decimal;
|
90
|
+
|
91
|
+
// Extract the decimal part of the value
|
92
|
+
let decimalString = valueString.slice(-decimal);
|
93
|
+
|
94
|
+
// Trim the decimal string to match the specified bigIntDecimal length
|
95
|
+
if (decimalString.length > bigIntDecimal) {
|
96
|
+
decimalString = decimalString.substring(0, bigIntDecimal);
|
97
|
+
}
|
71
98
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
99
|
+
// Construct the final string with the integer and decimal parts
|
100
|
+
const formattedValue = `${valueString.slice(0, decimalIndex)}.${decimalString}`.replace(
|
101
|
+
/\.?0*$/,
|
102
|
+
'',
|
103
|
+
);
|
104
|
+
|
105
|
+
// Log the formatted value for debugging
|
106
|
+
console.log(tag + 'Formatted Value:', formattedValue);
|
107
|
+
|
108
|
+
return formattedValue;
|
109
|
+
} catch (error) {
|
110
|
+
// Log any errors encountered during the process
|
111
|
+
console.error(tag + 'Error in formatBigIntToSafeValue:', error);
|
112
|
+
return '';
|
113
|
+
}
|
76
114
|
}
|
77
115
|
|
116
|
+
// export function formatBigIntToSafeValue({
|
117
|
+
// value,
|
118
|
+
// bigIntDecimal = DEFAULT_DECIMAL,
|
119
|
+
// decimal = DEFAULT_DECIMAL,
|
120
|
+
// }: {
|
121
|
+
// value: bigint;
|
122
|
+
// bigIntDecimal?: number;
|
123
|
+
// decimal?: number;
|
124
|
+
// }): string {
|
125
|
+
// let tag = TAG + " | formatBigIntToSafeValue | ";
|
126
|
+
// try {
|
127
|
+
// const isNegative = value < BigInt(0);
|
128
|
+
// let valueString = value.toString().substring(isNegative ? 1 : 0);
|
129
|
+
//
|
130
|
+
// const padLength = decimal - (valueString.length - 1);
|
131
|
+
//
|
132
|
+
// if (padLength > 0) {
|
133
|
+
// valueString = '0'.repeat(padLength) + valueString;
|
134
|
+
// }
|
135
|
+
//
|
136
|
+
// const decimalIndex = valueString.length - decimal;
|
137
|
+
// let decimalString = valueString.slice(-decimal);
|
138
|
+
//
|
139
|
+
// if (decimalString.length > bigIntDecimal) {
|
140
|
+
// decimalString = decimalString.substring(0, bigIntDecimal);
|
141
|
+
// }
|
142
|
+
//
|
143
|
+
// return `${isNegative ? '-' : ''}${valueString.slice(0, decimalIndex)}.${decimalString}`.replace(
|
144
|
+
// /\.?0*$/,
|
145
|
+
// '',
|
146
|
+
// );
|
147
|
+
// } catch (error) {
|
148
|
+
// console.error(tag + 'Error in formatBigIntToSafeValue:', error);
|
149
|
+
// return '';
|
150
|
+
// }
|
151
|
+
// }
|
152
|
+
|
78
153
|
export class BigIntArithmetics {
|
79
|
-
private decimalMultiplier:
|
80
|
-
|
154
|
+
private decimalMultiplier: any;
|
155
|
+
//@ts-ignore
|
156
|
+
private bigIntValue: bigint;
|
81
157
|
private decimal?: number;
|
82
158
|
|
83
159
|
static fromBigInt(value: bigint, decimal?: number): BigIntArithmetics {
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
160
|
+
let tag = TAG + " | fromBigInt | ";
|
161
|
+
try {
|
162
|
+
return new BigIntArithmetics({
|
163
|
+
decimal,
|
164
|
+
value: formatBigIntToSafeValue({ value, bigIntDecimal: decimal, decimal }),
|
165
|
+
});
|
166
|
+
} catch (error) {
|
167
|
+
console.error(tag + 'Error in fromBigInt:', error);
|
168
|
+
return new BigIntArithmetics(0);
|
169
|
+
}
|
88
170
|
}
|
89
171
|
|
90
172
|
static shiftDecimals({
|
@@ -96,178 +178,292 @@ export class BigIntArithmetics {
|
|
96
178
|
from: number;
|
97
179
|
to: number;
|
98
180
|
}): BigIntArithmetics {
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
181
|
+
let tag = TAG + " | shiftDecimals | ";
|
182
|
+
try {
|
183
|
+
return this.fromBigInt(
|
184
|
+
(value.getBaseValue('bigint') * toMultiplier(to)) / toMultiplier(from),
|
185
|
+
to,
|
186
|
+
);
|
187
|
+
} catch (error) {
|
188
|
+
console.error(tag + 'Error in shiftDecimals:', error);
|
189
|
+
return new BigIntArithmetics(0);
|
190
|
+
}
|
103
191
|
}
|
104
192
|
|
193
|
+
|
194
|
+
|
105
195
|
constructor(params: SKBigIntParams) {
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
196
|
+
let tag = TAG + " | constructor | ";
|
197
|
+
try {
|
198
|
+
console.log(tag + 'Constructor Params:', params);
|
199
|
+
const value = getStringValue(params);
|
200
|
+
console.log(tag + 'String Value:', value);
|
201
|
+
const isComplex = typeof params === 'object' && params !== null;
|
202
|
+
this.decimal = isComplex ? (params as { decimal?: number }).decimal : undefined;
|
203
|
+
console.log(tag , 'Decimal:', this.decimal);
|
204
|
+
console.log(tag , 'isComplex:', isComplex);
|
205
|
+
if (isComplex) {
|
206
|
+
this.decimalMultiplier = this.decimal;
|
207
|
+
} else {
|
208
|
+
const maxDecimals = Math.max(getFloatDecimals(toSafeValue(value)), this.decimal || 0);
|
209
|
+
this.decimalMultiplier = toMultiplier(maxDecimals);
|
210
|
+
}
|
211
|
+
console.log(tag + 'Decimal Multiplier:', this.decimalMultiplier);
|
212
|
+
|
213
|
+
this.setValue(value);
|
214
|
+
//@ts-ignore
|
215
|
+
console.log(tag + 'BigInt Value:', this.bigIntValue);
|
216
|
+
} catch (error) {
|
217
|
+
console.error(tag + 'Error in constructor:', error);
|
218
|
+
this.decimalMultiplier = BigInt(1);
|
219
|
+
this.bigIntValue = BigInt(0);
|
118
220
|
}
|
119
|
-
console.log('Decimal Multiplier:', this.decimalMultiplier);
|
120
|
-
|
121
|
-
this.setValue(value);
|
122
|
-
console.log('BigInt Value:', this.bigIntValue);
|
123
221
|
}
|
124
222
|
|
125
223
|
set(value: SKBigIntParams): this {
|
126
|
-
|
127
|
-
|
224
|
+
let tag = TAG + " | set | ";
|
225
|
+
try {
|
226
|
+
// @ts-ignore
|
227
|
+
return new BigIntArithmetics({ decimal: this.decimal, value }) as this;
|
228
|
+
} catch (error) {
|
229
|
+
console.error(tag + 'Error in set:', error);
|
230
|
+
return this;
|
231
|
+
}
|
128
232
|
}
|
129
233
|
|
130
234
|
add(...args: InitialisationValueType[]): this {
|
131
|
-
|
235
|
+
let tag = TAG + " | add | ";
|
236
|
+
try {
|
237
|
+
return this.arithmetics('add', ...args);
|
238
|
+
} catch (error) {
|
239
|
+
console.error(tag + 'Error in add:', error);
|
240
|
+
return this;
|
241
|
+
}
|
132
242
|
}
|
133
243
|
|
134
244
|
sub(...args: InitialisationValueType[]): this {
|
135
|
-
|
245
|
+
let tag = TAG + " | sub | ";
|
246
|
+
try {
|
247
|
+
return this.arithmetics('sub', ...args);
|
248
|
+
} catch (error) {
|
249
|
+
console.error(tag + 'Error in sub:', error);
|
250
|
+
return this;
|
251
|
+
}
|
136
252
|
}
|
137
253
|
|
138
254
|
mul(...args: InitialisationValueType[]): this {
|
139
|
-
|
255
|
+
let tag = TAG + " | mul | ";
|
256
|
+
try {
|
257
|
+
return this.arithmetics('mul', ...args);
|
258
|
+
} catch (error) {
|
259
|
+
console.error(tag + 'Error in mul:', error);
|
260
|
+
return this;
|
261
|
+
}
|
140
262
|
}
|
141
263
|
|
142
264
|
div(...args: InitialisationValueType[]): this {
|
143
|
-
|
265
|
+
let tag = TAG + " | div | ";
|
266
|
+
try {
|
267
|
+
return this.arithmetics('div', ...args);
|
268
|
+
} catch (error) {
|
269
|
+
console.error(tag + 'Error in div:', error);
|
270
|
+
return this;
|
271
|
+
}
|
144
272
|
}
|
145
273
|
|
146
274
|
gt(value: InitialisationValueType): boolean {
|
147
|
-
|
275
|
+
let tag = TAG + " | gt | ";
|
276
|
+
try {
|
277
|
+
return this.comparison('gt', value);
|
278
|
+
} catch (error) {
|
279
|
+
console.error(tag + 'Error in gt:', error);
|
280
|
+
return false;
|
281
|
+
}
|
148
282
|
}
|
149
283
|
|
150
284
|
gte(value: InitialisationValueType): boolean {
|
151
|
-
|
285
|
+
let tag = TAG + " | gte | ";
|
286
|
+
try {
|
287
|
+
return this.comparison('gte', value);
|
288
|
+
} catch (error) {
|
289
|
+
console.error(tag + 'Error in gte:', error);
|
290
|
+
return false;
|
291
|
+
}
|
152
292
|
}
|
153
293
|
|
154
294
|
lt(value: InitialisationValueType): boolean {
|
155
|
-
|
295
|
+
let tag = TAG + " | lt | ";
|
296
|
+
try {
|
297
|
+
return this.comparison('lt', value);
|
298
|
+
} catch (error) {
|
299
|
+
console.error(tag + 'Error in lt:', error);
|
300
|
+
return false;
|
301
|
+
}
|
156
302
|
}
|
157
303
|
|
158
304
|
lte(value: InitialisationValueType): boolean {
|
159
|
-
|
305
|
+
let tag = TAG + " | lte | ";
|
306
|
+
try {
|
307
|
+
return this.comparison('lte', value);
|
308
|
+
} catch (error) {
|
309
|
+
console.error(tag + 'Error in lte:', error);
|
310
|
+
return false;
|
311
|
+
}
|
160
312
|
}
|
161
313
|
|
162
314
|
eqValue(value: InitialisationValueType): boolean {
|
163
|
-
|
315
|
+
let tag = TAG + " | eqValue | ";
|
316
|
+
try {
|
317
|
+
return this.comparison('eqValue', value);
|
318
|
+
} catch (error) {
|
319
|
+
console.error(tag + 'Error in eqValue:', error);
|
320
|
+
return false;
|
321
|
+
}
|
164
322
|
}
|
165
|
-
|
166
|
-
// @ts-ignore
|
323
|
+
//@ts-ignore
|
167
324
|
getValue<T extends AllowedNumberTypes>(type: T): NumberPrimitivesType[T] {
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
325
|
+
let tag = TAG + " | getValue | ";
|
326
|
+
try {
|
327
|
+
console.log(tag,'getValue type:', type);
|
328
|
+
console.log(tag,'decimalMultiplier: ', this.decimalMultiplier);
|
329
|
+
const value = formatBigIntToSafeValue({
|
330
|
+
value: this.bigIntValue,
|
331
|
+
bigIntDecimal: this.decimal || decimalFromMultiplier(this.decimalMultiplier),
|
332
|
+
decimal: this.decimalMultiplier,
|
333
|
+
});
|
334
|
+
console.log(tag,'value:', value);
|
335
|
+
switch (type) {
|
336
|
+
case 'number':
|
337
|
+
return Number(value) as NumberPrimitivesType[T];
|
338
|
+
case 'string':
|
339
|
+
return value as NumberPrimitivesType[T];
|
340
|
+
case 'bigint':
|
341
|
+
return ((this.bigIntValue * bigintPow(BigInt(10), this.decimal || 8)) /
|
342
|
+
this.decimalMultiplier) as NumberPrimitivesType[T];
|
343
|
+
}
|
344
|
+
} catch (error) {
|
345
|
+
console.error(tag + 'Error in getValue:', error);
|
346
|
+
return null as any;
|
181
347
|
}
|
182
348
|
}
|
183
349
|
|
184
350
|
// @ts-ignore
|
185
351
|
getBaseValue<T extends AllowedNumberTypes>(type: T): NumberPrimitivesType[T] {
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
352
|
+
let tag = TAG + " | getBaseValue | ";
|
353
|
+
try {
|
354
|
+
const divisor = this.decimalMultiplier / toMultiplier(this.decimal || BaseDecimal.THOR);
|
355
|
+
const baseValue = this.bigIntValue / divisor;
|
356
|
+
|
357
|
+
switch (type) {
|
358
|
+
case 'number':
|
359
|
+
return Number(baseValue) as NumberPrimitivesType[T];
|
360
|
+
case 'string':
|
361
|
+
return baseValue.toString() as NumberPrimitivesType[T];
|
362
|
+
case 'bigint':
|
363
|
+
return baseValue as NumberPrimitivesType[T];
|
364
|
+
}
|
365
|
+
} catch (error) {
|
366
|
+
console.error(tag + 'Error in getBaseValue:', error);
|
367
|
+
return null as any;
|
196
368
|
}
|
197
369
|
}
|
198
370
|
|
199
371
|
getBigIntValue(value: InitialisationValueType, decimal?: number): bigint {
|
200
|
-
|
201
|
-
|
372
|
+
let tag = TAG + " | getBigIntValue | ";
|
373
|
+
try {
|
374
|
+
if (!decimal && typeof value === 'object' && value !== null) {
|
375
|
+
return (value as BigIntArithmetics).bigIntValue;
|
376
|
+
}
|
377
|
+
|
378
|
+
const stringValue = getStringValue(value);
|
379
|
+
const safeValue = toSafeValue(stringValue);
|
380
|
+
|
381
|
+
if (safeValue === '0' || safeValue === 'undefined') return BigInt(0);
|
382
|
+
return this.toBigInt(safeValue, decimal);
|
383
|
+
} catch (error) {
|
384
|
+
console.error(tag + 'Error in getBigIntValue:', error);
|
385
|
+
return BigInt(0);
|
202
386
|
}
|
203
|
-
|
204
|
-
const stringValue = getStringValue(value);
|
205
|
-
const safeValue = toSafeValue(stringValue);
|
206
|
-
|
207
|
-
if (safeValue === '0' || safeValue === 'undefined') return BigInt(0);
|
208
|
-
return this.toBigInt(safeValue, decimal);
|
209
387
|
}
|
210
388
|
|
211
389
|
toSignificant(significantDigits: number = 6): string {
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
390
|
+
let tag = TAG + " | toSignificant | ";
|
391
|
+
try {
|
392
|
+
const [int, dec] = this.getValue('string').split('.');
|
393
|
+
const integer = int || '';
|
394
|
+
const decimal = dec || '';
|
395
|
+
const valueLength = parseInt(integer) ? integer.length + decimal.length : decimal.length;
|
396
|
+
|
397
|
+
if (valueLength <= significantDigits) {
|
398
|
+
return this.getValue('string');
|
399
|
+
}
|
400
|
+
|
401
|
+
if (integer.length >= significantDigits) {
|
402
|
+
return integer.slice(0, significantDigits).padEnd(integer.length, '0');
|
403
|
+
}
|
404
|
+
|
405
|
+
if (parseInt(integer)) {
|
406
|
+
return `${integer}.${decimal.slice(0, significantDigits - integer.length)}`.padEnd(
|
407
|
+
significantDigits - integer.length,
|
408
|
+
'0',
|
409
|
+
);
|
410
|
+
}
|
411
|
+
|
412
|
+
const trimmedDecimal = parseInt(decimal);
|
413
|
+
const slicedDecimal = `${trimmedDecimal}`.slice(0, significantDigits);
|
414
|
+
|
415
|
+
return `0.${slicedDecimal.padStart(
|
416
|
+
decimal.length - `${trimmedDecimal}`.length + slicedDecimal.length,
|
228
417
|
'0',
|
229
|
-
)
|
418
|
+
)}`;
|
419
|
+
} catch (error) {
|
420
|
+
console.error(tag + 'Error in toSignificant:', error);
|
421
|
+
return '';
|
230
422
|
}
|
231
|
-
|
232
|
-
const trimmedDecimal = parseInt(decimal);
|
233
|
-
const slicedDecimal = `${trimmedDecimal}`.slice(0, significantDigits);
|
234
|
-
|
235
|
-
return `0.${slicedDecimal.padStart(
|
236
|
-
decimal.length - `${trimmedDecimal}`.length + slicedDecimal.length,
|
237
|
-
'0',
|
238
|
-
)}`;
|
239
423
|
}
|
240
424
|
|
241
425
|
toFixed(fixedDigits: number = 6): string {
|
242
|
-
|
243
|
-
|
244
|
-
|
426
|
+
let tag = TAG + " | toFixed | ";
|
427
|
+
try {
|
428
|
+
const [int, dec] = this.getValue('string').split('.');
|
429
|
+
const integer = int || '';
|
430
|
+
const decimal = dec || '';
|
245
431
|
|
246
|
-
|
247
|
-
|
248
|
-
|
432
|
+
if (parseInt(integer)) {
|
433
|
+
return `${integer}.${decimal.slice(0, fixedDigits)}`.padEnd(fixedDigits, '0');
|
434
|
+
}
|
249
435
|
|
250
|
-
|
251
|
-
|
436
|
+
const trimmedDecimal = parseInt(decimal);
|
437
|
+
const slicedDecimal = `${trimmedDecimal}`.slice(0, fixedDigits);
|
252
438
|
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
439
|
+
return `0.${slicedDecimal.padStart(
|
440
|
+
decimal.length - `${trimmedDecimal}`.length + slicedDecimal.length,
|
441
|
+
'0',
|
442
|
+
)}`;
|
443
|
+
} catch (error) {
|
444
|
+
console.error(tag + 'Error in toFixed:', error);
|
445
|
+
return '';
|
446
|
+
}
|
257
447
|
}
|
258
448
|
|
259
449
|
toAbbreviation(digits = 2): string {
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
450
|
+
let tag = TAG + " | toAbbreviation | ";
|
451
|
+
try {
|
452
|
+
const value = this.getValue('number');
|
453
|
+
const abbreviations = ['', 'K', 'M', 'B', 'T', 'Q', 'Qi', 'S'];
|
454
|
+
const tier = Math.floor(Math.log10(Math.abs(value)) / 3);
|
455
|
+
const suffix = abbreviations[tier];
|
456
|
+
|
457
|
+
if (!suffix) return this.getValue('string');
|
458
|
+
|
459
|
+
const scale = 10 ** (tier * 3);
|
460
|
+
const scaled = value / scale;
|
461
|
+
|
462
|
+
return `${scaled.toFixed(digits)}${suffix}`;
|
463
|
+
} catch (error) {
|
464
|
+
console.error(tag + 'Error in toAbbreviation:', error);
|
465
|
+
return '';
|
466
|
+
}
|
271
467
|
}
|
272
468
|
|
273
469
|
toCurrency(
|
@@ -279,107 +475,141 @@ export class BigIntArithmetics {
|
|
279
475
|
thousandSeparator = ',',
|
280
476
|
} = {},
|
281
477
|
): string {
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
478
|
+
let tag = TAG + " | toCurrency | ";
|
479
|
+
try {
|
480
|
+
const value = this.getValue('number');
|
481
|
+
const [int, dec = ''] = value.toFixed(6).split('.');
|
482
|
+
const integer = int.replace(/\B(?=(\d{3})+(?!\d))/g, thousandSeparator);
|
483
|
+
|
484
|
+
const parsedValue =
|
485
|
+
!int && !dec
|
486
|
+
? '0.00'
|
487
|
+
: int === '0'
|
488
|
+
? `${parseFloat(`0.${dec}`)}`.replace('.', decimalSeparator)
|
489
|
+
: `${integer}${parseInt(dec) ? `${decimalSeparator}${dec.slice(0, decimal)}` : ''}`;
|
490
|
+
|
491
|
+
return `${currencyPosition === 'start' ? currency : ''}${parsedValue}${currencyPosition === 'end' ? currency : ''
|
492
|
+
}`;
|
493
|
+
} catch (error) {
|
494
|
+
console.error(tag + 'Error in toCurrency:', error);
|
495
|
+
return '';
|
496
|
+
}
|
296
497
|
}
|
297
498
|
|
298
499
|
private arithmetics(method: 'add' | 'sub' | 'mul' | 'div', ...args: InitialisationValueType[]): this {
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
500
|
+
let tag = TAG + " | arithmetics | ";
|
501
|
+
try {
|
502
|
+
const precisionDecimal = this.retrievePrecisionDecimal(this, ...args);
|
503
|
+
const decimal = Math.max(precisionDecimal, decimalFromMultiplier(this.decimalMultiplier));
|
504
|
+
const precisionDecimalMultiplier = toMultiplier(decimal);
|
505
|
+
|
506
|
+
const result = args.reduce(
|
507
|
+
(acc: bigint, arg) => {
|
508
|
+
const value = this.getBigIntValue(arg, decimal);
|
509
|
+
|
510
|
+
switch (method) {
|
511
|
+
case 'add':
|
512
|
+
return acc + value;
|
513
|
+
case 'sub':
|
514
|
+
return acc - value;
|
515
|
+
case 'mul':
|
516
|
+
return (acc * value) / precisionDecimalMultiplier;
|
517
|
+
case 'div': {
|
518
|
+
if (value === BigInt(0)) throw new RangeError('Division by zero');
|
519
|
+
return (acc * precisionDecimalMultiplier) / value;
|
520
|
+
}
|
521
|
+
default:
|
522
|
+
return acc;
|
317
523
|
}
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
},
|
322
|
-
(this.bigIntValue * precisionDecimalMultiplier) / this.decimalMultiplier,
|
323
|
-
);
|
324
|
-
|
325
|
-
const formattedValue = formatBigIntToSafeValue({
|
326
|
-
bigIntDecimal: decimal,
|
327
|
-
decimal,
|
328
|
-
value: result,
|
329
|
-
});
|
524
|
+
},
|
525
|
+
(this.bigIntValue * precisionDecimalMultiplier) / this.decimalMultiplier,
|
526
|
+
);
|
330
527
|
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
528
|
+
const formattedValue = formatBigIntToSafeValue({
|
529
|
+
bigIntDecimal: decimal,
|
530
|
+
decimal,
|
531
|
+
value: result,
|
532
|
+
});
|
533
|
+
|
534
|
+
return new BigIntArithmetics({
|
535
|
+
decimalMultiplier: toMultiplier(decimal),
|
536
|
+
decimal: this.decimal,
|
537
|
+
value: formattedValue,
|
538
|
+
}) as this;
|
539
|
+
} catch (error) {
|
540
|
+
console.error(tag + 'Error in arithmetics:', error);
|
541
|
+
return this;
|
542
|
+
}
|
336
543
|
}
|
337
544
|
|
338
545
|
private comparison(method: 'gt' | 'gte' | 'lt' | 'lte' | 'eqValue', ...args: InitialisationValueType[]): boolean {
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
546
|
+
let tag = TAG + " | comparison | ";
|
547
|
+
try {
|
548
|
+
const decimal = this.retrievePrecisionDecimal(this, ...args);
|
549
|
+
const value = this.getBigIntValue(args[0], decimal);
|
550
|
+
const compareToValue = this.getBigIntValue(this, decimal);
|
551
|
+
|
552
|
+
switch (method) {
|
553
|
+
case 'gt':
|
554
|
+
return compareToValue > value;
|
555
|
+
case 'gte':
|
556
|
+
return compareToValue >= value;
|
557
|
+
case 'lt':
|
558
|
+
return compareToValue < value;
|
559
|
+
case 'lte':
|
560
|
+
return compareToValue <= value;
|
561
|
+
case 'eqValue':
|
562
|
+
return compareToValue === value;
|
563
|
+
}
|
564
|
+
} catch (error) {
|
565
|
+
console.error(tag + 'Error in comparison:', error);
|
566
|
+
return false;
|
354
567
|
}
|
355
568
|
}
|
356
569
|
|
357
570
|
private setValue(value: InitialisationValueType): void {
|
358
|
-
|
359
|
-
|
571
|
+
let tag = TAG + " | setValue | ";
|
572
|
+
try {
|
573
|
+
const safeValue = toSafeValue(value) || '0';
|
574
|
+
this.bigIntValue = this.toBigInt(safeValue);
|
575
|
+
} catch (error) {
|
576
|
+
console.error(tag + 'Error in setValue:', error);
|
577
|
+
}
|
360
578
|
}
|
361
579
|
|
362
580
|
private retrievePrecisionDecimal(...args: InitialisationValueType[]): number {
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
581
|
+
let tag = TAG + " | retrievePrecisionDecimal | ";
|
582
|
+
try {
|
583
|
+
const decimals = args
|
584
|
+
.map((arg) => {
|
585
|
+
const isObject = typeof arg === 'object' && arg !== null;
|
586
|
+
const value = isObject
|
587
|
+
? (arg as any).decimal || decimalFromMultiplier((arg as any).decimalMultiplier)
|
588
|
+
: getFloatDecimals(toSafeValue(arg));
|
589
|
+
|
590
|
+
return value;
|
591
|
+
})
|
592
|
+
.filter(Boolean) as number[];
|
593
|
+
|
594
|
+
return Math.max(...decimals, DEFAULT_DECIMAL);
|
595
|
+
} catch (error) {
|
596
|
+
console.error(tag + 'Error in retrievePrecisionDecimal:', error);
|
597
|
+
return DEFAULT_DECIMAL;
|
598
|
+
}
|
375
599
|
}
|
376
600
|
|
377
601
|
private toBigInt(value: string, decimal?: number): bigint {
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
602
|
+
let tag = TAG + " | toBigInt | ";
|
603
|
+
try {
|
604
|
+
const multiplier = decimal ? toMultiplier(decimal) : this.decimalMultiplier;
|
605
|
+
const padDecimal = decimalFromMultiplier(multiplier);
|
606
|
+
const [integerPart = '', decimalPart = ''] = value.split('.');
|
607
|
+
|
608
|
+
return BigInt(`${integerPart}${decimalPart.padEnd(padDecimal, '0')}`);
|
609
|
+
} catch (error) {
|
610
|
+
console.error(tag + 'Error in toBigInt:', error);
|
611
|
+
return BigInt(0);
|
612
|
+
}
|
383
613
|
}
|
384
614
|
}
|
385
615
|
|
@@ -389,28 +619,46 @@ const numberFormatter = Intl.NumberFormat('fullwide', {
|
|
389
619
|
});
|
390
620
|
|
391
621
|
function toSafeValue(value: InitialisationValueType): string {
|
392
|
-
|
393
|
-
|
394
|
-
|
622
|
+
let tag = TAG + " | toSafeValue | ";
|
623
|
+
try {
|
624
|
+
const parsedValue =
|
625
|
+
typeof value === 'number' ? numberFormatter.format(value) : getStringValue(value);
|
626
|
+
const splitValue = `${parsedValue}`.replace(/,/g, '.').split('.');
|
395
627
|
|
396
|
-
|
397
|
-
|
398
|
-
|
628
|
+
return splitValue.length > 1
|
629
|
+
? `${splitValue.slice(0, -1).join('')}.${splitValue.at(-1)}`
|
630
|
+
: splitValue[0];
|
631
|
+
} catch (error) {
|
632
|
+
console.error(tag + 'Error in toSafeValue:', error);
|
633
|
+
return '0';
|
634
|
+
}
|
399
635
|
}
|
400
636
|
|
401
637
|
function getFloatDecimals(value: string): number {
|
402
|
-
let
|
403
|
-
|
404
|
-
|
405
|
-
|
638
|
+
let tag = TAG + " | getFloatDecimals | ";
|
639
|
+
try {
|
640
|
+
let decimals = 0;
|
641
|
+
const parts = value.split('.');
|
642
|
+
if (parts.length > 1 && parts[1].length > 0) {
|
643
|
+
decimals = parts[1].length;
|
644
|
+
}
|
645
|
+
return Math.max(decimals, DEFAULT_DECIMAL);
|
646
|
+
} catch (error) {
|
647
|
+
console.error(tag + 'Error in getFloatDecimals:', error);
|
648
|
+
return DEFAULT_DECIMAL;
|
406
649
|
}
|
407
|
-
return Math.max(decimals, DEFAULT_DECIMAL);
|
408
650
|
}
|
409
651
|
|
410
652
|
function getStringValue(param: SKBigIntParams): string {
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
653
|
+
let tag = TAG + " | getStringValue | ";
|
654
|
+
try {
|
655
|
+
return typeof param === 'object' && param !== null
|
656
|
+
? 'getValue' in param
|
657
|
+
? (param as SwapKitNumber).getValue('string')
|
658
|
+
: (param as any).value
|
659
|
+
: (param as string);
|
660
|
+
} catch (error) {
|
661
|
+
console.error(tag + 'Error in getStringValue:', error);
|
662
|
+
return '';
|
663
|
+
}
|
416
664
|
}
|