@obinexusmk2/hypernum 0.1.0
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 -0
- package/README.md +256 -0
- package/dist/index.cjs +3425 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +1449 -0
- package/dist/index.js +3284 -0
- package/dist/index.js.map +1 -0
- package/dist/index.umd.js +8 -0
- package/dist/index.umd.js.map +1 -0
- package/dist/types/config/config-loader.d.ts +56 -0
- package/dist/types/config/config-loader.d.ts.map +1 -0
- package/dist/types/config/config-parser.d.ts +28 -0
- package/dist/types/config/config-parser.d.ts.map +1 -0
- package/dist/types/config/config-resolver.d.ts +21 -0
- package/dist/types/config/config-resolver.d.ts.map +1 -0
- package/dist/types/config/config-source.d.ts +27 -0
- package/dist/types/config/config-source.d.ts.map +1 -0
- package/dist/types/config/index.d.ts +68 -0
- package/dist/types/config/index.d.ts.map +1 -0
- package/dist/types/core/common.d.ts +169 -0
- package/dist/types/core/common.d.ts.map +1 -0
- package/dist/types/core/config.d.ts +197 -0
- package/dist/types/core/config.d.ts.map +1 -0
- package/dist/types/core/constants.d.ts +88 -0
- package/dist/types/core/constants.d.ts.map +1 -0
- package/dist/types/core/errors.d.ts +97 -0
- package/dist/types/core/errors.d.ts.map +1 -0
- package/dist/types/core/hypernum.d.ts +60 -0
- package/dist/types/core/hypernum.d.ts.map +1 -0
- package/dist/types/core/index.d.ts +6 -0
- package/dist/types/core/index.d.ts.map +1 -0
- package/dist/types/index.d.ts +33 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/operations/arithmetic.d.ts +72 -0
- package/dist/types/operations/arithmetic.d.ts.map +1 -0
- package/dist/types/operations/bitwise.d.ts +98 -0
- package/dist/types/operations/bitwise.d.ts.map +1 -0
- package/dist/types/operations/comparison.d.ts +94 -0
- package/dist/types/operations/comparison.d.ts.map +1 -0
- package/dist/types/operations/conversion.d.ts +79 -0
- package/dist/types/operations/conversion.d.ts.map +1 -0
- package/dist/types/operations/factorial.d.ts +58 -0
- package/dist/types/operations/factorial.d.ts.map +1 -0
- package/dist/types/operations/index.d.ts +6 -0
- package/dist/types/operations/index.d.ts.map +1 -0
- package/dist/types/operations/power.d.ts +49 -0
- package/dist/types/operations/power.d.ts.map +1 -0
- package/dist/types/storage/Heap.d.ts +95 -0
- package/dist/types/storage/Heap.d.ts.map +1 -0
- package/dist/types/storage/index.d.ts +2 -0
- package/dist/types/storage/index.d.ts.map +1 -0
- package/dist/types/structures/ackermann.d.ts +74 -0
- package/dist/types/structures/ackermann.d.ts.map +1 -0
- package/dist/types/structures/big-array.d.ts +102 -0
- package/dist/types/structures/big-array.d.ts.map +1 -0
- package/dist/types/structures/index.d.ts +5 -0
- package/dist/types/structures/index.d.ts.map +1 -0
- package/dist/types/structures/number-tree.d.ts +114 -0
- package/dist/types/structures/number-tree.d.ts.map +1 -0
- package/dist/types/structures/power-tower.d.ts +74 -0
- package/dist/types/structures/power-tower.d.ts.map +1 -0
- package/dist/types/utils/formatting.d.ts +45 -0
- package/dist/types/utils/formatting.d.ts.map +1 -0
- package/dist/types/utils/index.d.ts +5 -0
- package/dist/types/utils/index.d.ts.map +1 -0
- package/dist/types/utils/parser.d.ts +39 -0
- package/dist/types/utils/parser.d.ts.map +1 -0
- package/dist/types/utils/precision.d.ts +57 -0
- package/dist/types/utils/precision.d.ts.map +1 -0
- package/dist/types/utils/validation.d.ts +28 -0
- package/dist/types/utils/validation.d.ts.map +1 -0
- package/package.json +164 -0
- package/rollup.config.js +162 -0
- package/src/config/config-loader.ts +226 -0
- package/src/config/config-parser.ts +161 -0
- package/src/config/config-resolver.ts +52 -0
- package/src/config/config-source.ts +32 -0
- package/src/config/index.ts +159 -0
- package/src/core/common.ts +185 -0
- package/src/core/config.ts +393 -0
- package/src/core/constants.ts +102 -0
- package/src/core/errors.ts +203 -0
- package/src/core/hypernum.ts +241 -0
- package/src/core/index.ts +5 -0
- package/src/index.ts +183 -0
- package/src/operations/arithmetic.ts +333 -0
- package/src/operations/bitwise.ts +367 -0
- package/src/operations/comparison.ts +272 -0
- package/src/operations/conversion.ts +400 -0
- package/src/operations/factorial.ts +279 -0
- package/src/operations/index.ts +5 -0
- package/src/operations/power.ts +316 -0
- package/src/storage/Heap.ts +238 -0
- package/src/storage/index.ts +1 -0
- package/src/structures/ackermann.ts +233 -0
- package/src/structures/big-array.ts +306 -0
- package/src/structures/index.ts +4 -0
- package/src/structures/number-tree.ts +404 -0
- package/src/structures/power-tower.ts +278 -0
- package/src/types/common.d.ts +357 -0
- package/src/types/core.d.ts +161 -0
- package/src/types/index.d.ts +2 -0
- package/src/utils/formatting.ts +246 -0
- package/src/utils/index.ts +4 -0
- package/src/utils/parser.ts +245 -0
- package/src/utils/precision.ts +217 -0
- package/src/utils/validation.ts +183 -0
- package/tsconfig.json +84 -0
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Factorial operations module for Hypernum library
|
|
3
|
+
* Provides efficient implementations for factorial and related computations
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
toBigInt,
|
|
8
|
+
ValidationError,
|
|
9
|
+
OverflowError,
|
|
10
|
+
validateNonNegative
|
|
11
|
+
} from '../utils/validation';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Options for factorial operations
|
|
15
|
+
*/
|
|
16
|
+
export interface FactorialOptions {
|
|
17
|
+
/** Maximum allowed computation value */
|
|
18
|
+
maxValue?: number;
|
|
19
|
+
/** Whether to check for overflow */
|
|
20
|
+
checkOverflow?: boolean;
|
|
21
|
+
/** Cache computed values */
|
|
22
|
+
useCache?: boolean;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const DEFAULT_OPTIONS: Required<FactorialOptions> = {
|
|
26
|
+
maxValue: 1000,
|
|
27
|
+
checkOverflow: true,
|
|
28
|
+
useCache: true
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
// Cache for factorial values
|
|
32
|
+
const factorialCache = new Map<bigint, bigint>();
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Calculates factorial of a number (n!)
|
|
36
|
+
*/
|
|
37
|
+
export function factorial(
|
|
38
|
+
value: bigint | string | number,
|
|
39
|
+
options: FactorialOptions = {}
|
|
40
|
+
): bigint {
|
|
41
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
42
|
+
const n = toBigInt(value);
|
|
43
|
+
|
|
44
|
+
validateNonNegative(n);
|
|
45
|
+
|
|
46
|
+
if (opts.checkOverflow && n > BigInt(opts.maxValue)) {
|
|
47
|
+
throw new OverflowError(`Factorial input too large: maximum allowed is ${opts.maxValue}`);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Handle base cases
|
|
51
|
+
if (n <= 1n) {
|
|
52
|
+
return 1n;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Check cache
|
|
56
|
+
if (opts.useCache && factorialCache.has(n)) {
|
|
57
|
+
return factorialCache.get(n)!;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Calculate factorial
|
|
61
|
+
let result = 1n;
|
|
62
|
+
for (let i = 2n; i <= n; i++) {
|
|
63
|
+
result *= i;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Cache result
|
|
67
|
+
if (opts.useCache) {
|
|
68
|
+
factorialCache.set(n, result);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return result;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Calculates binomial coefficient (n choose k)
|
|
76
|
+
*/
|
|
77
|
+
export function binomial(
|
|
78
|
+
n: bigint | string | number,
|
|
79
|
+
k: bigint | string | number,
|
|
80
|
+
options: FactorialOptions = {}
|
|
81
|
+
): bigint {
|
|
82
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
83
|
+
const bigN = toBigInt(n);
|
|
84
|
+
const bigK = toBigInt(k);
|
|
85
|
+
|
|
86
|
+
validateNonNegative(bigN);
|
|
87
|
+
validateNonNegative(bigK);
|
|
88
|
+
|
|
89
|
+
if (bigK > bigN) {
|
|
90
|
+
throw new ValidationError('K cannot be greater than N in binomial coefficient');
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Optimize for k > n/2 by using symmetry
|
|
94
|
+
if (bigK > bigN / 2n) {
|
|
95
|
+
return binomial(bigN, bigN - bigK, opts);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Use multiplicative formula instead of factorial for efficiency
|
|
99
|
+
let result = 1n;
|
|
100
|
+
for (let i = 0n; i < bigK; i++) {
|
|
101
|
+
result = (result * (bigN - i)) / (i + 1n);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return result;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Calculates subfactorial (derangement number)
|
|
109
|
+
* Number of permutations of n elements with no fixed points
|
|
110
|
+
*/
|
|
111
|
+
export function subfactorial(
|
|
112
|
+
value: bigint | string | number,
|
|
113
|
+
options: FactorialOptions = {}
|
|
114
|
+
): bigint {
|
|
115
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
116
|
+
const n = toBigInt(value);
|
|
117
|
+
|
|
118
|
+
validateNonNegative(n);
|
|
119
|
+
|
|
120
|
+
if (opts.checkOverflow && n > BigInt(opts.maxValue)) {
|
|
121
|
+
throw new OverflowError(`Subfactorial input too large: maximum allowed is ${opts.maxValue}`);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Handle base cases
|
|
125
|
+
if (n === 0n) return 1n;
|
|
126
|
+
if (n === 1n) return 0n;
|
|
127
|
+
|
|
128
|
+
// Use recursive formula !n = n * !(n-1) + (-1)^n
|
|
129
|
+
let result = 0n;
|
|
130
|
+
const nFact = factorial(n, opts);
|
|
131
|
+
|
|
132
|
+
for (let k = 0n; k <= n; k++) {
|
|
133
|
+
const term = factorial(n - k, opts) * (k % 2n === 0n ? 1n : -1n);
|
|
134
|
+
result += term;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return nFact - result;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Calculates rising factorial (Pochhammer symbol)
|
|
142
|
+
* x^(n) = x(x+1)(x+2)...(x+n-1)
|
|
143
|
+
*/
|
|
144
|
+
export function risingFactorial(
|
|
145
|
+
x: bigint | string | number,
|
|
146
|
+
n: bigint | string | number,
|
|
147
|
+
options: FactorialOptions = {}
|
|
148
|
+
): bigint {
|
|
149
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
150
|
+
const bigX = toBigInt(x);
|
|
151
|
+
const bigN = toBigInt(n);
|
|
152
|
+
|
|
153
|
+
validateNonNegative(bigN);
|
|
154
|
+
|
|
155
|
+
if (opts.checkOverflow && bigN > BigInt(opts.maxValue)) {
|
|
156
|
+
throw new OverflowError(`Rising factorial input too large: maximum allowed is ${opts.maxValue}`);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
let result = 1n;
|
|
160
|
+
for (let i = 0n; i < bigN; i++) {
|
|
161
|
+
result *= (bigX + i);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return result;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Calculates falling factorial
|
|
169
|
+
* x_(n) = x(x-1)(x-2)...(x-n+1)
|
|
170
|
+
*/
|
|
171
|
+
export function fallingFactorial(
|
|
172
|
+
x: bigint | string | number,
|
|
173
|
+
n: bigint | string | number,
|
|
174
|
+
options: FactorialOptions = {}
|
|
175
|
+
): bigint {
|
|
176
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
177
|
+
const bigX = toBigInt(x);
|
|
178
|
+
const bigN = toBigInt(n);
|
|
179
|
+
|
|
180
|
+
validateNonNegative(bigN);
|
|
181
|
+
|
|
182
|
+
if (opts.checkOverflow && bigN > BigInt(opts.maxValue)) {
|
|
183
|
+
throw new OverflowError(`Falling factorial input too large: maximum allowed is ${opts.maxValue}`);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
let result = 1n;
|
|
187
|
+
for (let i = 0n; i < bigN; i++) {
|
|
188
|
+
result *= (bigX - i);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return result;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Calculates multifactorial (n!!)
|
|
196
|
+
* Product of numbers from 1 to n that leave the same remainder as n when divided by k
|
|
197
|
+
*/
|
|
198
|
+
export function multiFactorial(
|
|
199
|
+
value: bigint | string | number,
|
|
200
|
+
k: bigint | string | number = 2n,
|
|
201
|
+
options: FactorialOptions = {}
|
|
202
|
+
): bigint {
|
|
203
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
204
|
+
const n = toBigInt(value);
|
|
205
|
+
const bigK = toBigInt(k);
|
|
206
|
+
|
|
207
|
+
validateNonNegative(n);
|
|
208
|
+
if (bigK <= 0n) {
|
|
209
|
+
throw new ValidationError('K must be positive in multifactorial');
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
if (opts.checkOverflow && n > BigInt(opts.maxValue)) {
|
|
213
|
+
throw new OverflowError(`Multifactorial input too large: maximum allowed is ${opts.maxValue}`);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
let result = 1n;
|
|
217
|
+
let current = n;
|
|
218
|
+
|
|
219
|
+
while (current > 0n) {
|
|
220
|
+
result *= current;
|
|
221
|
+
current -= bigK;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
return result;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Calculates primorial (product of primes up to n)
|
|
229
|
+
*/
|
|
230
|
+
export function primorial(
|
|
231
|
+
value: bigint | string | number,
|
|
232
|
+
options: FactorialOptions = {}
|
|
233
|
+
): bigint {
|
|
234
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
235
|
+
const n = toBigInt(value);
|
|
236
|
+
|
|
237
|
+
validateNonNegative(n);
|
|
238
|
+
|
|
239
|
+
if (opts.checkOverflow && n > BigInt(opts.maxValue)) {
|
|
240
|
+
throw new OverflowError(`Primorial input too large: maximum allowed is ${opts.maxValue}`);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
if (n <= 1n) return 1n;
|
|
244
|
+
|
|
245
|
+
// Generate primes up to n using Sieve of Eratosthenes
|
|
246
|
+
const num = Number(n);
|
|
247
|
+
const sieve = new Array(num + 1).fill(true);
|
|
248
|
+
sieve[0] = sieve[1] = false;
|
|
249
|
+
|
|
250
|
+
for (let i = 2; i * i <= num; i++) {
|
|
251
|
+
if (sieve[i]) {
|
|
252
|
+
for (let j = i * i; j <= num; j += i) {
|
|
253
|
+
sieve[j] = false;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Calculate product of all primes up to n
|
|
259
|
+
let result = 1n;
|
|
260
|
+
for (let i = 2; i <= num; i++) {
|
|
261
|
+
if (sieve[i]) {
|
|
262
|
+
result *= BigInt(i);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
return result;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
export default {
|
|
272
|
+
factorial,
|
|
273
|
+
binomial,
|
|
274
|
+
subfactorial,
|
|
275
|
+
risingFactorial,
|
|
276
|
+
fallingFactorial,
|
|
277
|
+
multiFactorial,
|
|
278
|
+
primorial
|
|
279
|
+
};
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Power operations module for Hypernum library
|
|
3
|
+
* Provides efficient implementations for exponentiation and related operations
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
toBigInt,
|
|
8
|
+
ValidationError,
|
|
9
|
+
OverflowError,
|
|
10
|
+
validateNonNegative,
|
|
11
|
+
checkPowerOverflow
|
|
12
|
+
} from '../utils/validation';
|
|
13
|
+
|
|
14
|
+
import {
|
|
15
|
+
RoundingMode,
|
|
16
|
+
round,
|
|
17
|
+
} from '../utils/precision';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Options for power operations
|
|
21
|
+
*/
|
|
22
|
+
export interface PowerOptions {
|
|
23
|
+
/** Precision for decimal operations */
|
|
24
|
+
precision?: number;
|
|
25
|
+
/** Rounding mode for decimal operations */
|
|
26
|
+
roundingMode?: RoundingMode;
|
|
27
|
+
/** Whether to check for overflow */
|
|
28
|
+
checkOverflow?: boolean;
|
|
29
|
+
/** Maximum allowed computation steps */
|
|
30
|
+
maxSteps?: number;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const DEFAULT_OPTIONS: Required<PowerOptions> = {
|
|
34
|
+
precision: 0,
|
|
35
|
+
roundingMode: RoundingMode.HALF_EVEN,
|
|
36
|
+
checkOverflow: true,
|
|
37
|
+
maxSteps: 1000
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Raises a number to an integer power using binary exponentiation
|
|
42
|
+
*/
|
|
43
|
+
export function power(
|
|
44
|
+
baseValue: bigint | string | number,
|
|
45
|
+
exponentValue: bigint | string | number,
|
|
46
|
+
options: PowerOptions = {}
|
|
47
|
+
): bigint {
|
|
48
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
49
|
+
const bigBase = toBigInt(baseValue);
|
|
50
|
+
const bigExponent = toBigInt(exponentValue);
|
|
51
|
+
|
|
52
|
+
// Handle special cases
|
|
53
|
+
if (bigExponent === 0n) {
|
|
54
|
+
return 1n;
|
|
55
|
+
}
|
|
56
|
+
if (bigExponent === 1n) {
|
|
57
|
+
return bigBase;
|
|
58
|
+
}
|
|
59
|
+
if (bigBase === 0n && bigExponent < 0n) {
|
|
60
|
+
throw new ValidationError('Zero cannot be raised to a negative power');
|
|
61
|
+
}
|
|
62
|
+
if (bigBase === 0n) {
|
|
63
|
+
return 0n;
|
|
64
|
+
}
|
|
65
|
+
if (bigBase === 1n) {
|
|
66
|
+
return 1n;
|
|
67
|
+
}
|
|
68
|
+
if (bigBase === -1n) {
|
|
69
|
+
return bigExponent % 2n === 0n ? 1n : -1n;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Validate inputs
|
|
73
|
+
if (bigExponent < 0n) {
|
|
74
|
+
throw new ValidationError('Negative exponents not supported for integer power');
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (opts.checkOverflow) {
|
|
78
|
+
checkPowerOverflow(bigBase, bigExponent);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Binary exponentiation algorithm
|
|
82
|
+
let result = 1n;
|
|
83
|
+
let base = bigBase;
|
|
84
|
+
let exponent = bigExponent;
|
|
85
|
+
let steps = 0;
|
|
86
|
+
|
|
87
|
+
while (exponent > 0n) {
|
|
88
|
+
if (steps++ > opts.maxSteps) {
|
|
89
|
+
throw new OverflowError('Power operation exceeded maximum computation steps');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (exponent & 1n) {
|
|
93
|
+
result *= base;
|
|
94
|
+
}
|
|
95
|
+
base *= base;
|
|
96
|
+
exponent >>= 1n;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (opts.precision > 0) {
|
|
100
|
+
return round(result, opts.precision, opts.roundingMode);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return result;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Calculates square root using Newton's method
|
|
108
|
+
*/
|
|
109
|
+
export function sqrt(
|
|
110
|
+
value: bigint | string | number,
|
|
111
|
+
options: PowerOptions = {}
|
|
112
|
+
): bigint {
|
|
113
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
114
|
+
const bigValue = toBigInt(value);
|
|
115
|
+
|
|
116
|
+
validateNonNegative(bigValue);
|
|
117
|
+
|
|
118
|
+
if (bigValue === 0n) {
|
|
119
|
+
return 0n;
|
|
120
|
+
}
|
|
121
|
+
if (bigValue === 1n) {
|
|
122
|
+
return 1n;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Newton's method for square root
|
|
126
|
+
let guess = bigValue >> 1n;
|
|
127
|
+
let lastGuess: bigint;
|
|
128
|
+
let steps = 0;
|
|
129
|
+
|
|
130
|
+
do {
|
|
131
|
+
if (steps++ > opts.maxSteps) {
|
|
132
|
+
throw new OverflowError('Square root operation exceeded maximum computation steps');
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
lastGuess = guess;
|
|
136
|
+
guess = (guess + bigValue / guess) >> 1n;
|
|
137
|
+
} while (guess < lastGuess);
|
|
138
|
+
|
|
139
|
+
if (opts.precision > 0) {
|
|
140
|
+
return round(lastGuess, opts.precision, opts.roundingMode);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return lastGuess;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Calculates nth root using Newton's method
|
|
148
|
+
*/
|
|
149
|
+
export function nthRoot(
|
|
150
|
+
value: bigint | string | number,
|
|
151
|
+
n: bigint | string | number,
|
|
152
|
+
options: PowerOptions = {}
|
|
153
|
+
): bigint {
|
|
154
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
155
|
+
const bigValue = toBigInt(value);
|
|
156
|
+
const bigN = toBigInt(n);
|
|
157
|
+
|
|
158
|
+
validateNonNegative(bigValue);
|
|
159
|
+
if (bigN <= 0n) {
|
|
160
|
+
throw new ValidationError('Root index must be positive');
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (bigValue === 0n) {
|
|
164
|
+
return 0n;
|
|
165
|
+
}
|
|
166
|
+
if (bigValue === 1n) {
|
|
167
|
+
return 1n;
|
|
168
|
+
}
|
|
169
|
+
if (bigN === 1n) {
|
|
170
|
+
return bigValue;
|
|
171
|
+
}
|
|
172
|
+
if (bigN === 2n) {
|
|
173
|
+
return sqrt(bigValue, opts);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Newton's method for nth root
|
|
177
|
+
let guess = bigValue >> 1n;
|
|
178
|
+
let lastGuess: bigint;
|
|
179
|
+
let steps = 0;
|
|
180
|
+
|
|
181
|
+
const nMinus1 = bigN - 1n;
|
|
182
|
+
|
|
183
|
+
do {
|
|
184
|
+
if (steps++ > opts.maxSteps) {
|
|
185
|
+
throw new OverflowError('Nth root operation exceeded maximum computation steps');
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
lastGuess = guess;
|
|
189
|
+
const powered = power(guess, nMinus1, opts);
|
|
190
|
+
guess = ((nMinus1 * guess) + (bigValue / powered)) / bigN;
|
|
191
|
+
} while (guess < lastGuess);
|
|
192
|
+
|
|
193
|
+
if (opts.precision > 0) {
|
|
194
|
+
return round(lastGuess, opts.precision, opts.roundingMode);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
return lastGuess;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Calculates tetration (repeated exponentiation)
|
|
202
|
+
* a↑↑n = a^(a^(a^...)) (n times)
|
|
203
|
+
*/
|
|
204
|
+
export function tetration(
|
|
205
|
+
base: bigint | string | number,
|
|
206
|
+
height: bigint | string | number,
|
|
207
|
+
options: PowerOptions = {}
|
|
208
|
+
): bigint {
|
|
209
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
210
|
+
const bigBase = toBigInt(base);
|
|
211
|
+
const bigHeight = toBigInt(height);
|
|
212
|
+
|
|
213
|
+
validateNonNegative(bigHeight);
|
|
214
|
+
|
|
215
|
+
if (bigHeight === 0n) {
|
|
216
|
+
return 1n;
|
|
217
|
+
}
|
|
218
|
+
if (bigHeight === 1n) {
|
|
219
|
+
return bigBase;
|
|
220
|
+
}
|
|
221
|
+
if (bigBase === 0n) {
|
|
222
|
+
return bigHeight % 2n === 0n ? 1n : 0n;
|
|
223
|
+
}
|
|
224
|
+
if (bigBase === 1n) {
|
|
225
|
+
return 1n;
|
|
226
|
+
}
|
|
227
|
+
if (bigBase === 2n && bigHeight > 4n) {
|
|
228
|
+
throw new OverflowError('Tetration would overflow for base 2 and height > 4');
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
let result = bigBase;
|
|
232
|
+
let steps = 0;
|
|
233
|
+
|
|
234
|
+
for (let i = 1n; i < bigHeight; i++) {
|
|
235
|
+
if (steps++ > opts.maxSteps) {
|
|
236
|
+
throw new OverflowError('Tetration operation exceeded maximum computation steps');
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
result = power(bigBase, result, opts);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if (opts.precision > 0) {
|
|
243
|
+
return round(result, opts.precision, opts.roundingMode);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
return result;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Calculates super-root (inverse tetration)
|
|
251
|
+
* Finds x where x↑↑n = value
|
|
252
|
+
*/
|
|
253
|
+
export function superRoot(
|
|
254
|
+
value: bigint | string | number,
|
|
255
|
+
height: bigint | string | number,
|
|
256
|
+
options: PowerOptions = {}
|
|
257
|
+
): bigint {
|
|
258
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
259
|
+
const bigValue = toBigInt(value);
|
|
260
|
+
const bigHeight = toBigInt(height);
|
|
261
|
+
|
|
262
|
+
validateNonNegative(bigHeight);
|
|
263
|
+
if (bigHeight === 0n) {
|
|
264
|
+
throw new ValidationError('Height cannot be zero for super-root');
|
|
265
|
+
}
|
|
266
|
+
if (bigValue < 1n) {
|
|
267
|
+
throw new ValidationError('Value must be at least 1 for super-root');
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
if (bigValue === 1n) {
|
|
271
|
+
return 1n;
|
|
272
|
+
}
|
|
273
|
+
if (bigHeight === 1n) {
|
|
274
|
+
return bigValue;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// Binary search for super-root
|
|
278
|
+
let left = 1n;
|
|
279
|
+
let right = bigValue;
|
|
280
|
+
let steps = 0;
|
|
281
|
+
|
|
282
|
+
while (left <= right) {
|
|
283
|
+
if (steps++ > opts.maxSteps) {
|
|
284
|
+
throw new OverflowError('Super-root operation exceeded maximum computation steps');
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
const mid = (left + right) >> 1n;
|
|
288
|
+
try {
|
|
289
|
+
const test = tetration(mid, bigHeight, opts);
|
|
290
|
+
if (test === bigValue) {
|
|
291
|
+
return mid;
|
|
292
|
+
}
|
|
293
|
+
if (test < bigValue) {
|
|
294
|
+
left = mid + 1n;
|
|
295
|
+
} else {
|
|
296
|
+
right = mid - 1n;
|
|
297
|
+
}
|
|
298
|
+
} catch (error) {
|
|
299
|
+
right = mid - 1n;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
if (opts.precision > 0) {
|
|
304
|
+
return round(right, opts.precision, opts.roundingMode);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
return right;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
export default {
|
|
311
|
+
power,
|
|
312
|
+
sqrt,
|
|
313
|
+
nthRoot,
|
|
314
|
+
tetration,
|
|
315
|
+
superRoot
|
|
316
|
+
};
|