@obinexusmk2/hypernum 0.1.0 → 0.1.1
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/LICENSE +21 -21
- package/README.md +355 -256
- package/dist/index.cjs +4 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +4 -7
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +2 -2
- package/dist/index.umd.js.map +1 -1
- package/dist/types/{config → src/config}/config-loader.d.ts +0 -0
- package/dist/types/src/config/config-loader.d.ts.map +1 -0
- package/dist/types/{config → src/config}/config-parser.d.ts +0 -0
- package/dist/types/src/config/config-parser.d.ts.map +1 -0
- package/dist/types/{config → src/config}/config-resolver.d.ts +0 -0
- package/dist/types/src/config/config-resolver.d.ts.map +1 -0
- package/dist/types/{config → src/config}/config-source.d.ts +0 -0
- package/dist/types/src/config/config-source.d.ts.map +1 -0
- package/dist/types/{config → src/config}/index.d.ts +0 -0
- package/dist/types/src/config/index.d.ts.map +1 -0
- package/dist/types/{core → src/core}/common.d.ts +0 -0
- package/dist/types/src/core/common.d.ts.map +1 -0
- package/dist/types/{core → src/core}/config.d.ts +0 -0
- package/dist/types/src/core/config.d.ts.map +1 -0
- package/dist/types/{core → src/core}/constants.d.ts +0 -0
- package/dist/types/src/core/constants.d.ts.map +1 -0
- package/dist/types/{core → src/core}/errors.d.ts +0 -0
- package/dist/types/src/core/errors.d.ts.map +1 -0
- package/dist/types/{core → src/core}/hypernum.d.ts +0 -0
- package/dist/types/src/core/hypernum.d.ts.map +1 -0
- package/dist/types/{core → src/core}/index.d.ts +0 -0
- package/dist/types/src/core/index.d.ts.map +1 -0
- package/dist/types/{index.d.ts → src/index.d.ts} +1 -1
- package/dist/types/src/index.d.ts.map +1 -0
- package/dist/types/{operations → src/operations}/arithmetic.d.ts +0 -0
- package/dist/types/src/operations/arithmetic.d.ts.map +1 -0
- package/dist/types/{operations → src/operations}/bitwise.d.ts +0 -0
- package/dist/types/src/operations/bitwise.d.ts.map +1 -0
- package/dist/types/{operations → src/operations}/comparison.d.ts +0 -0
- package/dist/types/src/operations/comparison.d.ts.map +1 -0
- package/dist/types/{operations → src/operations}/conversion.d.ts +0 -0
- package/dist/types/src/operations/conversion.d.ts.map +1 -0
- package/dist/types/{operations → src/operations}/factorial.d.ts +0 -0
- package/dist/types/src/operations/factorial.d.ts.map +1 -0
- package/dist/types/{operations → src/operations}/index.d.ts +0 -0
- package/dist/types/src/operations/index.d.ts.map +1 -0
- package/dist/types/{operations → src/operations}/power.d.ts +0 -0
- package/dist/types/src/operations/power.d.ts.map +1 -0
- package/dist/types/{storage → src/storage}/Heap.d.ts +0 -0
- package/dist/types/src/storage/Heap.d.ts.map +1 -0
- package/dist/types/{storage → src/storage}/index.d.ts +0 -0
- package/dist/types/src/storage/index.d.ts.map +1 -0
- package/dist/types/{structures → src/structures}/ackermann.d.ts +0 -0
- package/dist/types/src/structures/ackermann.d.ts.map +1 -0
- package/dist/types/{structures → src/structures}/big-array.d.ts +0 -0
- package/dist/types/src/structures/big-array.d.ts.map +1 -0
- package/dist/types/{structures → src/structures}/index.d.ts +0 -0
- package/dist/types/src/structures/index.d.ts.map +1 -0
- package/dist/types/{structures → src/structures}/number-tree.d.ts +0 -0
- package/dist/types/src/structures/number-tree.d.ts.map +1 -0
- package/dist/types/{structures → src/structures}/power-tower.d.ts +0 -0
- package/dist/types/src/structures/power-tower.d.ts.map +1 -0
- package/dist/types/{utils → src/utils}/formatting.d.ts +0 -0
- package/dist/types/src/utils/formatting.d.ts.map +1 -0
- package/dist/types/{utils → src/utils}/index.d.ts +0 -0
- package/dist/types/src/utils/index.d.ts.map +1 -0
- package/dist/types/{utils → src/utils}/parser.d.ts +0 -0
- package/dist/types/src/utils/parser.d.ts.map +1 -0
- package/dist/types/{utils → src/utils}/precision.d.ts +0 -0
- package/dist/types/src/utils/precision.d.ts.map +1 -0
- package/dist/types/{utils → src/utils}/validation.d.ts +0 -0
- package/dist/types/src/utils/validation.d.ts.map +1 -0
- package/package.json +169 -164
- package/rollup.config.js +163 -161
- package/src/cli/hypernum.js +272 -0
- package/src/config/config-loader.ts +0 -0
- package/src/config/config-parser.ts +160 -160
- package/src/config/config-resolver.ts +0 -0
- package/src/config/config-source.ts +0 -0
- package/src/config/index.ts +0 -0
- package/src/core/common.ts +184 -184
- package/src/core/config.ts +392 -392
- package/src/core/constants.ts +101 -101
- package/src/core/errors.ts +202 -202
- package/src/core/hypernum.ts +240 -240
- package/src/core/index.ts +4 -4
- package/src/index.ts +179 -182
- package/src/operations/arithmetic.ts +332 -332
- package/src/operations/bitwise.ts +366 -366
- package/src/operations/comparison.ts +271 -271
- package/src/operations/conversion.ts +399 -399
- package/src/operations/factorial.ts +278 -278
- package/src/operations/index.ts +4 -4
- package/src/operations/power.ts +315 -315
- package/src/storage/Heap.ts +237 -237
- package/src/storage/index.ts +0 -0
- package/src/structures/ackermann.ts +232 -232
- package/src/structures/big-array.ts +305 -305
- package/src/structures/index.ts +3 -3
- package/src/structures/number-tree.ts +403 -403
- package/src/structures/power-tower.ts +277 -277
- package/src/types/common.d.ts +356 -356
- package/src/types/core.d.ts +160 -160
- package/src/types/index.d.ts +1 -1
- package/src/utils/formatting.ts +245 -245
- package/src/utils/index.ts +4 -4
- package/src/utils/parser.ts +244 -244
- package/src/utils/precision.ts +216 -216
- package/src/utils/validation.ts +182 -182
- package/tsconfig.json +83 -83
- package/dist/types/config/config-loader.d.ts.map +0 -1
- package/dist/types/config/config-parser.d.ts.map +0 -1
- package/dist/types/config/config-resolver.d.ts.map +0 -1
- package/dist/types/config/config-source.d.ts.map +0 -1
- package/dist/types/config/index.d.ts.map +0 -1
- package/dist/types/core/common.d.ts.map +0 -1
- package/dist/types/core/config.d.ts.map +0 -1
- package/dist/types/core/constants.d.ts.map +0 -1
- package/dist/types/core/errors.d.ts.map +0 -1
- package/dist/types/core/hypernum.d.ts.map +0 -1
- package/dist/types/core/index.d.ts.map +0 -1
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/operations/arithmetic.d.ts.map +0 -1
- package/dist/types/operations/bitwise.d.ts.map +0 -1
- package/dist/types/operations/comparison.d.ts.map +0 -1
- package/dist/types/operations/conversion.d.ts.map +0 -1
- package/dist/types/operations/factorial.d.ts.map +0 -1
- package/dist/types/operations/index.d.ts.map +0 -1
- package/dist/types/operations/power.d.ts.map +0 -1
- package/dist/types/storage/Heap.d.ts.map +0 -1
- package/dist/types/storage/index.d.ts.map +0 -1
- package/dist/types/structures/ackermann.d.ts.map +0 -1
- package/dist/types/structures/big-array.d.ts.map +0 -1
- package/dist/types/structures/index.d.ts.map +0 -1
- package/dist/types/structures/number-tree.d.ts.map +0 -1
- package/dist/types/structures/power-tower.d.ts.map +0 -1
- package/dist/types/utils/formatting.d.ts.map +0 -1
- package/dist/types/utils/index.d.ts.map +0 -1
- package/dist/types/utils/parser.d.ts.map +0 -1
- package/dist/types/utils/precision.d.ts.map +0 -1
- package/dist/types/utils/validation.d.ts.map +0 -1
|
@@ -1,333 +1,333 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Arithmetic operations module for Hypernum library
|
|
3
|
-
* Provides high-precision arithmetic operations with BigInt support
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import {
|
|
7
|
-
validateNonNegative,
|
|
8
|
-
toBigInt,
|
|
9
|
-
checkAdditionOverflow,
|
|
10
|
-
checkMultiplicationOverflow,
|
|
11
|
-
checkPowerOverflow,
|
|
12
|
-
ValidationError,
|
|
13
|
-
} from '../utils/validation';
|
|
14
|
-
|
|
15
|
-
import {
|
|
16
|
-
RoundingMode,
|
|
17
|
-
round,
|
|
18
|
-
scaledDivision,
|
|
19
|
-
normalizePrecision,
|
|
20
|
-
} from '../utils/precision';
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Options for arithmetic operations
|
|
24
|
-
*/
|
|
25
|
-
export interface ArithmeticOptions {
|
|
26
|
-
precision?: number;
|
|
27
|
-
roundingMode?: RoundingMode;
|
|
28
|
-
checkOverflow?: boolean;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const DEFAULT_OPTIONS: Required<ArithmeticOptions> = {
|
|
32
|
-
precision: 0,
|
|
33
|
-
roundingMode: RoundingMode.HALF_EVEN,
|
|
34
|
-
checkOverflow: true
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Adds two numbers with optional precision and overflow checking
|
|
39
|
-
*/
|
|
40
|
-
export function add(
|
|
41
|
-
a: bigint | string | number,
|
|
42
|
-
b: bigint | string | number,
|
|
43
|
-
options: ArithmeticOptions = {}
|
|
44
|
-
): bigint {
|
|
45
|
-
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
46
|
-
const bigA = toBigInt(a);
|
|
47
|
-
const bigB = toBigInt(b);
|
|
48
|
-
|
|
49
|
-
if (opts.checkOverflow) {
|
|
50
|
-
checkAdditionOverflow(bigA, bigB);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
if (opts.precision === 0) {
|
|
54
|
-
return bigA + bigB;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const [scaledA, scaledB] = normalizePrecision(bigA, bigB, opts.precision, opts.precision);
|
|
58
|
-
const result = scaledA + scaledB;
|
|
59
|
-
|
|
60
|
-
return round(result, opts.precision, opts.roundingMode);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Subtracts two numbers with optional precision and overflow checking
|
|
65
|
-
*/
|
|
66
|
-
export function subtract(
|
|
67
|
-
a: bigint | string | number,
|
|
68
|
-
b: bigint | string | number,
|
|
69
|
-
options: ArithmeticOptions = {}
|
|
70
|
-
): bigint {
|
|
71
|
-
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
72
|
-
const bigA = toBigInt(a);
|
|
73
|
-
const bigB = toBigInt(b);
|
|
74
|
-
|
|
75
|
-
if (opts.checkOverflow) {
|
|
76
|
-
checkAdditionOverflow(bigA, -bigB);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
if (opts.precision === 0) {
|
|
80
|
-
return bigA - bigB;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const [scaledA, scaledB] = normalizePrecision(bigA, bigB, opts.precision, opts.precision);
|
|
84
|
-
const result = scaledA - scaledB;
|
|
85
|
-
|
|
86
|
-
return round(result, opts.precision, opts.roundingMode);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Multiplies two numbers with optional precision and overflow checking
|
|
91
|
-
*/
|
|
92
|
-
export function multiply(
|
|
93
|
-
a: bigint | string | number,
|
|
94
|
-
b: bigint | string | number,
|
|
95
|
-
options: ArithmeticOptions = {}
|
|
96
|
-
): bigint {
|
|
97
|
-
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
98
|
-
const bigA = toBigInt(a);
|
|
99
|
-
const bigB = toBigInt(b);
|
|
100
|
-
|
|
101
|
-
if (opts.checkOverflow) {
|
|
102
|
-
checkMultiplicationOverflow(bigA, bigB);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
const result = bigA * bigB;
|
|
106
|
-
if (opts.precision === 0) {
|
|
107
|
-
return result;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
return round(result, opts.precision, opts.roundingMode);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Divides two numbers with specified precision and rounding
|
|
115
|
-
*/
|
|
116
|
-
export function divide(
|
|
117
|
-
numerator: bigint | string | number,
|
|
118
|
-
denominator: bigint | string | number,
|
|
119
|
-
options: ArithmeticOptions = {}
|
|
120
|
-
): bigint {
|
|
121
|
-
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
122
|
-
const bigNumerator = toBigInt(numerator);
|
|
123
|
-
const bigDenominator = toBigInt(denominator);
|
|
124
|
-
|
|
125
|
-
if (bigDenominator === BigInt(0)) {
|
|
126
|
-
throw new ValidationError('Division by zero');
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
return scaledDivision(
|
|
130
|
-
bigNumerator,
|
|
131
|
-
bigDenominator,
|
|
132
|
-
opts.precision,
|
|
133
|
-
opts.roundingMode
|
|
134
|
-
);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* Calculates remainder with optional precision
|
|
139
|
-
*/
|
|
140
|
-
export function remainder(
|
|
141
|
-
a: bigint | string | number,
|
|
142
|
-
b: bigint | string | number,
|
|
143
|
-
options: ArithmeticOptions = {}
|
|
144
|
-
): bigint {
|
|
145
|
-
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
146
|
-
const bigA = toBigInt(a);
|
|
147
|
-
const bigB = toBigInt(b);
|
|
148
|
-
|
|
149
|
-
if (bigB === BigInt(0)) {
|
|
150
|
-
throw new ValidationError('Division by zero in remainder operation');
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
if (opts.precision === 0) {
|
|
154
|
-
return bigA % bigB;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
const [scaledA, scaledB] = normalizePrecision(bigA, bigB, opts.precision, opts.precision);
|
|
158
|
-
const result = scaledA % scaledB;
|
|
159
|
-
|
|
160
|
-
return round(result, opts.precision, opts.roundingMode);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* Raises a number to a power with optional precision
|
|
165
|
-
*/
|
|
166
|
-
export function power(
|
|
167
|
-
base: bigint | string | number,
|
|
168
|
-
exponent: bigint | string | number,
|
|
169
|
-
options: ArithmeticOptions = {}
|
|
170
|
-
): bigint {
|
|
171
|
-
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
172
|
-
const bigBase = toBigInt(base);
|
|
173
|
-
const bigExponent = toBigInt(exponent);
|
|
174
|
-
|
|
175
|
-
if (opts.checkOverflow) {
|
|
176
|
-
checkPowerOverflow(bigBase, bigExponent);
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
validateNonNegative(bigExponent);
|
|
180
|
-
|
|
181
|
-
if (bigExponent === BigInt(0)) {
|
|
182
|
-
return BigInt(1);
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
if (bigExponent === BigInt(1)) {
|
|
186
|
-
return bigBase;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
let result = bigBase;
|
|
190
|
-
let remaining = bigExponent - BigInt(1);
|
|
191
|
-
|
|
192
|
-
while (remaining > BigInt(0)) {
|
|
193
|
-
if (opts.checkOverflow) {
|
|
194
|
-
checkMultiplicationOverflow(result, bigBase);
|
|
195
|
-
}
|
|
196
|
-
result *= bigBase;
|
|
197
|
-
remaining--;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
if (opts.precision > 0) {
|
|
201
|
-
return round(result, opts.precision, opts.roundingMode);
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
return result;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
/**
|
|
208
|
-
* Calculates the square root with specified precision
|
|
209
|
-
*/
|
|
210
|
-
export function sqrt(
|
|
211
|
-
value: bigint | string | number,
|
|
212
|
-
options: ArithmeticOptions = {}
|
|
213
|
-
): bigint {
|
|
214
|
-
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
215
|
-
const bigValue = toBigInt(value);
|
|
216
|
-
validateNonNegative(bigValue);
|
|
217
|
-
|
|
218
|
-
if (bigValue === BigInt(0)) {
|
|
219
|
-
return BigInt(0);
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
// Scale up for precision
|
|
223
|
-
const scaleFactor = BigInt(10) ** BigInt(opts.precision * 2);
|
|
224
|
-
const scaled = bigValue * scaleFactor;
|
|
225
|
-
|
|
226
|
-
// Newton's method for square root
|
|
227
|
-
let x = scaled;
|
|
228
|
-
let y = (x + scaled / x) >> BigInt(1);
|
|
229
|
-
|
|
230
|
-
while (y < x) {
|
|
231
|
-
x = y;
|
|
232
|
-
y = (x + scaled / x) >> BigInt(1);
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
return round(x, opts.precision, opts.roundingMode);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
/**
|
|
239
|
-
* Calculates the absolute value
|
|
240
|
-
*/
|
|
241
|
-
export function abs(value: bigint | string | number): bigint {
|
|
242
|
-
const bigValue = toBigInt(value);
|
|
243
|
-
return bigValue < BigInt(0) ? -bigValue : bigValue;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
/**
|
|
247
|
-
* Returns the sign of a number (-1, 0, or 1)
|
|
248
|
-
*/
|
|
249
|
-
export function sign(value: bigint | string | number): bigint {
|
|
250
|
-
const bigValue = toBigInt(value);
|
|
251
|
-
if (bigValue < BigInt(0)) return BigInt(-1);
|
|
252
|
-
if (bigValue > BigInt(0)) return BigInt(1);
|
|
253
|
-
return BigInt(0);
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
/**
|
|
257
|
-
* Calculates the greatest common divisor of two numbers
|
|
258
|
-
*/
|
|
259
|
-
export function gcd(
|
|
260
|
-
a: bigint | string | number,
|
|
261
|
-
b: bigint | string | number
|
|
262
|
-
): bigint {
|
|
263
|
-
let bigA = abs(toBigInt(a));
|
|
264
|
-
let bigB = abs(toBigInt(b));
|
|
265
|
-
|
|
266
|
-
while (bigB !== BigInt(0)) {
|
|
267
|
-
const temp = bigB;
|
|
268
|
-
bigB = bigA % bigB;
|
|
269
|
-
bigA = temp;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
return bigA;
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
/**
|
|
276
|
-
* Calculates the least common multiple of two numbers
|
|
277
|
-
*/
|
|
278
|
-
export function lcm(
|
|
279
|
-
a: bigint | string | number,
|
|
280
|
-
b: bigint | string | number
|
|
281
|
-
): bigint {
|
|
282
|
-
const bigA = abs(toBigInt(a));
|
|
283
|
-
const bigB = abs(toBigInt(b));
|
|
284
|
-
|
|
285
|
-
if (bigA === BigInt(0) || bigB === BigInt(0)) {
|
|
286
|
-
return BigInt(0);
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
return abs(bigA * bigB) / gcd(bigA, bigB);
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
// /**
|
|
293
|
-
// * Calculates factorial of a number
|
|
294
|
-
// */
|
|
295
|
-
// export function factorial(value: bigint | string | number): bigint {
|
|
296
|
-
// const bigValue = toBigInt(value);
|
|
297
|
-
// validateNonNegative(bigValue);
|
|
298
|
-
|
|
299
|
-
// if (bigValue > BigInt(1000)) {
|
|
300
|
-
// throw new OverflowError('Factorial input too large');
|
|
301
|
-
// }
|
|
302
|
-
|
|
303
|
-
// if (bigValue <= BigInt(1)) {
|
|
304
|
-
// return BigInt(1);
|
|
305
|
-
// }
|
|
306
|
-
|
|
307
|
-
// let result = BigInt(1);
|
|
308
|
-
// let current = BigInt(2);
|
|
309
|
-
|
|
310
|
-
// while (current <= bigValue) {
|
|
311
|
-
// result *= current;
|
|
312
|
-
// current++;
|
|
313
|
-
// }
|
|
314
|
-
|
|
315
|
-
// return result;
|
|
316
|
-
// }
|
|
317
|
-
|
|
318
|
-
export default {
|
|
319
|
-
add,
|
|
320
|
-
subtract,
|
|
321
|
-
multiply,
|
|
322
|
-
divide,
|
|
323
|
-
remainder,
|
|
324
|
-
power,
|
|
325
|
-
sqrt,
|
|
326
|
-
abs,
|
|
327
|
-
sign,
|
|
328
|
-
gcd,
|
|
329
|
-
lcm,
|
|
330
|
-
// factorial
|
|
331
|
-
};
|
|
332
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Arithmetic operations module for Hypernum library
|
|
3
|
+
* Provides high-precision arithmetic operations with BigInt support
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
validateNonNegative,
|
|
8
|
+
toBigInt,
|
|
9
|
+
checkAdditionOverflow,
|
|
10
|
+
checkMultiplicationOverflow,
|
|
11
|
+
checkPowerOverflow,
|
|
12
|
+
ValidationError,
|
|
13
|
+
} from '../utils/validation';
|
|
14
|
+
|
|
15
|
+
import {
|
|
16
|
+
RoundingMode,
|
|
17
|
+
round,
|
|
18
|
+
scaledDivision,
|
|
19
|
+
normalizePrecision,
|
|
20
|
+
} from '../utils/precision';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Options for arithmetic operations
|
|
24
|
+
*/
|
|
25
|
+
export interface ArithmeticOptions {
|
|
26
|
+
precision?: number;
|
|
27
|
+
roundingMode?: RoundingMode;
|
|
28
|
+
checkOverflow?: boolean;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const DEFAULT_OPTIONS: Required<ArithmeticOptions> = {
|
|
32
|
+
precision: 0,
|
|
33
|
+
roundingMode: RoundingMode.HALF_EVEN,
|
|
34
|
+
checkOverflow: true
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Adds two numbers with optional precision and overflow checking
|
|
39
|
+
*/
|
|
40
|
+
export function add(
|
|
41
|
+
a: bigint | string | number,
|
|
42
|
+
b: bigint | string | number,
|
|
43
|
+
options: ArithmeticOptions = {}
|
|
44
|
+
): bigint {
|
|
45
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
46
|
+
const bigA = toBigInt(a);
|
|
47
|
+
const bigB = toBigInt(b);
|
|
48
|
+
|
|
49
|
+
if (opts.checkOverflow) {
|
|
50
|
+
checkAdditionOverflow(bigA, bigB);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (opts.precision === 0) {
|
|
54
|
+
return bigA + bigB;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const [scaledA, scaledB] = normalizePrecision(bigA, bigB, opts.precision, opts.precision);
|
|
58
|
+
const result = scaledA + scaledB;
|
|
59
|
+
|
|
60
|
+
return round(result, opts.precision, opts.roundingMode);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Subtracts two numbers with optional precision and overflow checking
|
|
65
|
+
*/
|
|
66
|
+
export function subtract(
|
|
67
|
+
a: bigint | string | number,
|
|
68
|
+
b: bigint | string | number,
|
|
69
|
+
options: ArithmeticOptions = {}
|
|
70
|
+
): bigint {
|
|
71
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
72
|
+
const bigA = toBigInt(a);
|
|
73
|
+
const bigB = toBigInt(b);
|
|
74
|
+
|
|
75
|
+
if (opts.checkOverflow) {
|
|
76
|
+
checkAdditionOverflow(bigA, -bigB);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (opts.precision === 0) {
|
|
80
|
+
return bigA - bigB;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const [scaledA, scaledB] = normalizePrecision(bigA, bigB, opts.precision, opts.precision);
|
|
84
|
+
const result = scaledA - scaledB;
|
|
85
|
+
|
|
86
|
+
return round(result, opts.precision, opts.roundingMode);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Multiplies two numbers with optional precision and overflow checking
|
|
91
|
+
*/
|
|
92
|
+
export function multiply(
|
|
93
|
+
a: bigint | string | number,
|
|
94
|
+
b: bigint | string | number,
|
|
95
|
+
options: ArithmeticOptions = {}
|
|
96
|
+
): bigint {
|
|
97
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
98
|
+
const bigA = toBigInt(a);
|
|
99
|
+
const bigB = toBigInt(b);
|
|
100
|
+
|
|
101
|
+
if (opts.checkOverflow) {
|
|
102
|
+
checkMultiplicationOverflow(bigA, bigB);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const result = bigA * bigB;
|
|
106
|
+
if (opts.precision === 0) {
|
|
107
|
+
return result;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return round(result, opts.precision, opts.roundingMode);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Divides two numbers with specified precision and rounding
|
|
115
|
+
*/
|
|
116
|
+
export function divide(
|
|
117
|
+
numerator: bigint | string | number,
|
|
118
|
+
denominator: bigint | string | number,
|
|
119
|
+
options: ArithmeticOptions = {}
|
|
120
|
+
): bigint {
|
|
121
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
122
|
+
const bigNumerator = toBigInt(numerator);
|
|
123
|
+
const bigDenominator = toBigInt(denominator);
|
|
124
|
+
|
|
125
|
+
if (bigDenominator === BigInt(0)) {
|
|
126
|
+
throw new ValidationError('Division by zero');
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return scaledDivision(
|
|
130
|
+
bigNumerator,
|
|
131
|
+
bigDenominator,
|
|
132
|
+
opts.precision,
|
|
133
|
+
opts.roundingMode
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Calculates remainder with optional precision
|
|
139
|
+
*/
|
|
140
|
+
export function remainder(
|
|
141
|
+
a: bigint | string | number,
|
|
142
|
+
b: bigint | string | number,
|
|
143
|
+
options: ArithmeticOptions = {}
|
|
144
|
+
): bigint {
|
|
145
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
146
|
+
const bigA = toBigInt(a);
|
|
147
|
+
const bigB = toBigInt(b);
|
|
148
|
+
|
|
149
|
+
if (bigB === BigInt(0)) {
|
|
150
|
+
throw new ValidationError('Division by zero in remainder operation');
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (opts.precision === 0) {
|
|
154
|
+
return bigA % bigB;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const [scaledA, scaledB] = normalizePrecision(bigA, bigB, opts.precision, opts.precision);
|
|
158
|
+
const result = scaledA % scaledB;
|
|
159
|
+
|
|
160
|
+
return round(result, opts.precision, opts.roundingMode);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Raises a number to a power with optional precision
|
|
165
|
+
*/
|
|
166
|
+
export function power(
|
|
167
|
+
base: bigint | string | number,
|
|
168
|
+
exponent: bigint | string | number,
|
|
169
|
+
options: ArithmeticOptions = {}
|
|
170
|
+
): bigint {
|
|
171
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
172
|
+
const bigBase = toBigInt(base);
|
|
173
|
+
const bigExponent = toBigInt(exponent);
|
|
174
|
+
|
|
175
|
+
if (opts.checkOverflow) {
|
|
176
|
+
checkPowerOverflow(bigBase, bigExponent);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
validateNonNegative(bigExponent);
|
|
180
|
+
|
|
181
|
+
if (bigExponent === BigInt(0)) {
|
|
182
|
+
return BigInt(1);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (bigExponent === BigInt(1)) {
|
|
186
|
+
return bigBase;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
let result = bigBase;
|
|
190
|
+
let remaining = bigExponent - BigInt(1);
|
|
191
|
+
|
|
192
|
+
while (remaining > BigInt(0)) {
|
|
193
|
+
if (opts.checkOverflow) {
|
|
194
|
+
checkMultiplicationOverflow(result, bigBase);
|
|
195
|
+
}
|
|
196
|
+
result *= bigBase;
|
|
197
|
+
remaining--;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (opts.precision > 0) {
|
|
201
|
+
return round(result, opts.precision, opts.roundingMode);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return result;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Calculates the square root with specified precision
|
|
209
|
+
*/
|
|
210
|
+
export function sqrt(
|
|
211
|
+
value: bigint | string | number,
|
|
212
|
+
options: ArithmeticOptions = {}
|
|
213
|
+
): bigint {
|
|
214
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
215
|
+
const bigValue = toBigInt(value);
|
|
216
|
+
validateNonNegative(bigValue);
|
|
217
|
+
|
|
218
|
+
if (bigValue === BigInt(0)) {
|
|
219
|
+
return BigInt(0);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Scale up for precision
|
|
223
|
+
const scaleFactor = BigInt(10) ** BigInt(opts.precision * 2);
|
|
224
|
+
const scaled = bigValue * scaleFactor;
|
|
225
|
+
|
|
226
|
+
// Newton's method for square root
|
|
227
|
+
let x = scaled;
|
|
228
|
+
let y = (x + scaled / x) >> BigInt(1);
|
|
229
|
+
|
|
230
|
+
while (y < x) {
|
|
231
|
+
x = y;
|
|
232
|
+
y = (x + scaled / x) >> BigInt(1);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
return round(x, opts.precision, opts.roundingMode);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Calculates the absolute value
|
|
240
|
+
*/
|
|
241
|
+
export function abs(value: bigint | string | number): bigint {
|
|
242
|
+
const bigValue = toBigInt(value);
|
|
243
|
+
return bigValue < BigInt(0) ? -bigValue : bigValue;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Returns the sign of a number (-1, 0, or 1)
|
|
248
|
+
*/
|
|
249
|
+
export function sign(value: bigint | string | number): bigint {
|
|
250
|
+
const bigValue = toBigInt(value);
|
|
251
|
+
if (bigValue < BigInt(0)) return BigInt(-1);
|
|
252
|
+
if (bigValue > BigInt(0)) return BigInt(1);
|
|
253
|
+
return BigInt(0);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Calculates the greatest common divisor of two numbers
|
|
258
|
+
*/
|
|
259
|
+
export function gcd(
|
|
260
|
+
a: bigint | string | number,
|
|
261
|
+
b: bigint | string | number
|
|
262
|
+
): bigint {
|
|
263
|
+
let bigA = abs(toBigInt(a));
|
|
264
|
+
let bigB = abs(toBigInt(b));
|
|
265
|
+
|
|
266
|
+
while (bigB !== BigInt(0)) {
|
|
267
|
+
const temp = bigB;
|
|
268
|
+
bigB = bigA % bigB;
|
|
269
|
+
bigA = temp;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
return bigA;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Calculates the least common multiple of two numbers
|
|
277
|
+
*/
|
|
278
|
+
export function lcm(
|
|
279
|
+
a: bigint | string | number,
|
|
280
|
+
b: bigint | string | number
|
|
281
|
+
): bigint {
|
|
282
|
+
const bigA = abs(toBigInt(a));
|
|
283
|
+
const bigB = abs(toBigInt(b));
|
|
284
|
+
|
|
285
|
+
if (bigA === BigInt(0) || bigB === BigInt(0)) {
|
|
286
|
+
return BigInt(0);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
return abs(bigA * bigB) / gcd(bigA, bigB);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// /**
|
|
293
|
+
// * Calculates factorial of a number
|
|
294
|
+
// */
|
|
295
|
+
// export function factorial(value: bigint | string | number): bigint {
|
|
296
|
+
// const bigValue = toBigInt(value);
|
|
297
|
+
// validateNonNegative(bigValue);
|
|
298
|
+
|
|
299
|
+
// if (bigValue > BigInt(1000)) {
|
|
300
|
+
// throw new OverflowError('Factorial input too large');
|
|
301
|
+
// }
|
|
302
|
+
|
|
303
|
+
// if (bigValue <= BigInt(1)) {
|
|
304
|
+
// return BigInt(1);
|
|
305
|
+
// }
|
|
306
|
+
|
|
307
|
+
// let result = BigInt(1);
|
|
308
|
+
// let current = BigInt(2);
|
|
309
|
+
|
|
310
|
+
// while (current <= bigValue) {
|
|
311
|
+
// result *= current;
|
|
312
|
+
// current++;
|
|
313
|
+
// }
|
|
314
|
+
|
|
315
|
+
// return result;
|
|
316
|
+
// }
|
|
317
|
+
|
|
318
|
+
export default {
|
|
319
|
+
add,
|
|
320
|
+
subtract,
|
|
321
|
+
multiply,
|
|
322
|
+
divide,
|
|
323
|
+
remainder,
|
|
324
|
+
power,
|
|
325
|
+
sqrt,
|
|
326
|
+
abs,
|
|
327
|
+
sign,
|
|
328
|
+
gcd,
|
|
329
|
+
lcm,
|
|
330
|
+
// factorial
|
|
331
|
+
};
|
|
332
|
+
|
|
333
333
|
|