@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,367 +1,367 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Bitwise operations module for Hypernum library
|
|
3
|
-
* Provides functions for bit-level manipulations of large numbers
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import {
|
|
7
|
-
toBigInt,
|
|
8
|
-
ValidationError,
|
|
9
|
-
validateNonNegative
|
|
10
|
-
} from '../utils/validation';
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Options for bitwise operations
|
|
14
|
-
*/
|
|
15
|
-
export interface BitwiseOptions {
|
|
16
|
-
/** Maximum bits to consider in operations */
|
|
17
|
-
maxBits?: number;
|
|
18
|
-
/** Whether to throw on overflow */
|
|
19
|
-
strict?: boolean;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const DEFAULT_OPTIONS: Required<BitwiseOptions> = {
|
|
23
|
-
maxBits: 1024,
|
|
24
|
-
strict: true
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Validates shift amount is within reasonable bounds
|
|
29
|
-
*/
|
|
30
|
-
function validateShift(shift: bigint, options: Required<BitwiseOptions>): void {
|
|
31
|
-
if (shift < 0n) {
|
|
32
|
-
throw new ValidationError('Shift amount cannot be negative');
|
|
33
|
-
}
|
|
34
|
-
if (options.strict && shift >= BigInt(options.maxBits)) {
|
|
35
|
-
throw new ValidationError(`Shift amount exceeds maximum of ${options.maxBits} bits`);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Performs bitwise AND operation
|
|
41
|
-
*/
|
|
42
|
-
export function and(
|
|
43
|
-
a: bigint | string | number,
|
|
44
|
-
b: bigint | string | number
|
|
45
|
-
): bigint {
|
|
46
|
-
const bigA = toBigInt(a);
|
|
47
|
-
const bigB = toBigInt(b);
|
|
48
|
-
|
|
49
|
-
return bigA & bigB;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Performs bitwise OR operation
|
|
54
|
-
*/
|
|
55
|
-
export function or(
|
|
56
|
-
a: bigint | string | number,
|
|
57
|
-
b: bigint | string | number
|
|
58
|
-
): bigint {
|
|
59
|
-
const bigA = toBigInt(a);
|
|
60
|
-
const bigB = toBigInt(b);
|
|
61
|
-
|
|
62
|
-
return bigA | bigB;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Performs bitwise XOR operation
|
|
67
|
-
*/
|
|
68
|
-
export function xor(
|
|
69
|
-
a: bigint | string | number,
|
|
70
|
-
b: bigint | string | number
|
|
71
|
-
): bigint {
|
|
72
|
-
const bigA = toBigInt(a);
|
|
73
|
-
const bigB = toBigInt(b);
|
|
74
|
-
|
|
75
|
-
return bigA ^ bigB;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Performs bitwise NOT operation
|
|
80
|
-
*/
|
|
81
|
-
export function not(
|
|
82
|
-
value: bigint | string | number
|
|
83
|
-
): bigint {
|
|
84
|
-
const bigValue = toBigInt(value);
|
|
85
|
-
|
|
86
|
-
return ~bigValue;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Performs left shift operation
|
|
91
|
-
*/
|
|
92
|
-
export function leftShift(
|
|
93
|
-
value: bigint | string | number,
|
|
94
|
-
shift: bigint | string | number,
|
|
95
|
-
options: BitwiseOptions = {}
|
|
96
|
-
): bigint {
|
|
97
|
-
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
98
|
-
const bigValue = toBigInt(value);
|
|
99
|
-
const bigShift = toBigInt(shift);
|
|
100
|
-
|
|
101
|
-
validateShift(bigShift, opts);
|
|
102
|
-
return bigValue << bigShift;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Performs right shift operation
|
|
107
|
-
*/
|
|
108
|
-
export function rightShift(
|
|
109
|
-
value: bigint | string | number,
|
|
110
|
-
shift: bigint | string | number,
|
|
111
|
-
options: BitwiseOptions = {}
|
|
112
|
-
): bigint {
|
|
113
|
-
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
114
|
-
const bigValue = toBigInt(value);
|
|
115
|
-
const bigShift = toBigInt(shift);
|
|
116
|
-
|
|
117
|
-
validateShift(bigShift, opts);
|
|
118
|
-
return bigValue >> bigShift;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Performs unsigned right shift operation
|
|
123
|
-
* Note: BigInt doesn't have >>> operator, so we implement it manually
|
|
124
|
-
*/
|
|
125
|
-
export function unsignedRightShift(
|
|
126
|
-
value: bigint | string | number,
|
|
127
|
-
shift: bigint | string | number,
|
|
128
|
-
options: BitwiseOptions = {}
|
|
129
|
-
): bigint {
|
|
130
|
-
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
131
|
-
const bigValue = toBigInt(value);
|
|
132
|
-
const bigShift = toBigInt(shift);
|
|
133
|
-
|
|
134
|
-
validateShift(bigShift, opts);
|
|
135
|
-
|
|
136
|
-
if (bigValue >= 0n) {
|
|
137
|
-
return bigValue >> bigShift;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// Handle negative numbers by first converting to positive
|
|
141
|
-
const mask = (1n << BigInt(opts.maxBits)) - 1n;
|
|
142
|
-
return (bigValue & mask) >> bigShift;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Rotates bits left by specified amount
|
|
147
|
-
*/
|
|
148
|
-
export function rotateLeft(
|
|
149
|
-
value: bigint | string | number,
|
|
150
|
-
rotation: bigint | string | number,
|
|
151
|
-
options: BitwiseOptions = {}
|
|
152
|
-
): bigint {
|
|
153
|
-
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
154
|
-
const bigValue = toBigInt(value);
|
|
155
|
-
let bigRotation = toBigInt(rotation);
|
|
156
|
-
|
|
157
|
-
validateNonNegative(bigRotation);
|
|
158
|
-
|
|
159
|
-
// Normalize rotation to be within maxBits
|
|
160
|
-
if (bigRotation >= BigInt(opts.maxBits)) {
|
|
161
|
-
bigRotation = bigRotation % BigInt(opts.maxBits);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
if (bigRotation === 0n) {
|
|
165
|
-
return bigValue;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
const leftPart = leftShift(bigValue, bigRotation, opts);
|
|
169
|
-
const rightPart = unsignedRightShift(bigValue, BigInt(opts.maxBits) - bigRotation, opts);
|
|
170
|
-
|
|
171
|
-
return leftPart | rightPart;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* Rotates bits right by specified amount
|
|
176
|
-
*/
|
|
177
|
-
export function rotateRight(
|
|
178
|
-
value: bigint | string | number,
|
|
179
|
-
rotation: bigint | string | number,
|
|
180
|
-
options: BitwiseOptions = {}
|
|
181
|
-
): bigint {
|
|
182
|
-
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
183
|
-
const bigValue = toBigInt(value);
|
|
184
|
-
let bigRotation = toBigInt(rotation);
|
|
185
|
-
|
|
186
|
-
validateNonNegative(bigRotation);
|
|
187
|
-
|
|
188
|
-
// Normalize rotation to be within maxBits
|
|
189
|
-
if (bigRotation >= BigInt(opts.maxBits)) {
|
|
190
|
-
bigRotation = bigRotation % BigInt(opts.maxBits);
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
if (bigRotation === 0n) {
|
|
194
|
-
return bigValue;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
const rightPart = unsignedRightShift(bigValue, bigRotation, opts);
|
|
198
|
-
const leftPart = leftShift(bigValue, BigInt(opts.maxBits) - bigRotation, opts);
|
|
199
|
-
|
|
200
|
-
return leftPart | rightPart;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
/**
|
|
204
|
-
* Counts number of set bits (1s)
|
|
205
|
-
*/
|
|
206
|
-
export function popCount(
|
|
207
|
-
value: bigint | string | number,
|
|
208
|
-
options: BitwiseOptions = {}
|
|
209
|
-
): bigint {
|
|
210
|
-
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
211
|
-
let bigValue = toBigInt(value);
|
|
212
|
-
|
|
213
|
-
let count = 0n;
|
|
214
|
-
while (bigValue !== 0n) {
|
|
215
|
-
count += bigValue & 1n;
|
|
216
|
-
bigValue = unsignedRightShift(bigValue, 1n, opts);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
return count;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
/**
|
|
223
|
-
* Returns number of trailing zero bits
|
|
224
|
-
*/
|
|
225
|
-
export function trailingZeros(
|
|
226
|
-
value: bigint | string | number,
|
|
227
|
-
options: BitwiseOptions = {}
|
|
228
|
-
): bigint {
|
|
229
|
-
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
230
|
-
let bigValue = toBigInt(value);
|
|
231
|
-
|
|
232
|
-
if (bigValue === 0n) {
|
|
233
|
-
return BigInt(opts.maxBits);
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
let count = 0n;
|
|
237
|
-
while ((bigValue & 1n) === 0n) {
|
|
238
|
-
count++;
|
|
239
|
-
bigValue = unsignedRightShift(bigValue, 1n, opts);
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
return count;
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
/**
|
|
246
|
-
* Returns number of leading zero bits
|
|
247
|
-
*/
|
|
248
|
-
export function leadingZeros(
|
|
249
|
-
value: bigint | string | number,
|
|
250
|
-
options: BitwiseOptions = {}
|
|
251
|
-
): bigint {
|
|
252
|
-
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
253
|
-
let bigValue = toBigInt(value);
|
|
254
|
-
|
|
255
|
-
if (bigValue === 0n) {
|
|
256
|
-
return BigInt(opts.maxBits);
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
let count = 0n;
|
|
260
|
-
const msb = 1n << BigInt(opts.maxBits - 1);
|
|
261
|
-
|
|
262
|
-
while ((bigValue & msb) === 0n && count < BigInt(opts.maxBits)) {
|
|
263
|
-
count++;
|
|
264
|
-
bigValue = leftShift(bigValue, 1n, opts);
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
return count;
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
/**
|
|
271
|
-
* Returns bit at specified position
|
|
272
|
-
*/
|
|
273
|
-
export function getBit(
|
|
274
|
-
value: bigint | string | number,
|
|
275
|
-
position: bigint | string | number,
|
|
276
|
-
options: BitwiseOptions = {}
|
|
277
|
-
): boolean {
|
|
278
|
-
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
279
|
-
const bigValue = toBigInt(value);
|
|
280
|
-
const bigPosition = toBigInt(position);
|
|
281
|
-
|
|
282
|
-
validateNonNegative(bigPosition);
|
|
283
|
-
if (opts.strict && bigPosition >= BigInt(opts.maxBits)) {
|
|
284
|
-
throw new ValidationError(`Bit position exceeds maximum of ${opts.maxBits} bits`);
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
return (bigValue & (1n << bigPosition)) !== 0n;
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
/**
|
|
291
|
-
* Sets bit at specified position
|
|
292
|
-
*/
|
|
293
|
-
export function setBit(
|
|
294
|
-
value: bigint | string | number,
|
|
295
|
-
position: bigint | string | number,
|
|
296
|
-
options: BitwiseOptions = {}
|
|
297
|
-
): bigint {
|
|
298
|
-
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
299
|
-
const bigValue = toBigInt(value);
|
|
300
|
-
const bigPosition = toBigInt(position);
|
|
301
|
-
|
|
302
|
-
validateNonNegative(bigPosition);
|
|
303
|
-
if (opts.strict && bigPosition >= BigInt(opts.maxBits)) {
|
|
304
|
-
throw new ValidationError(`Bit position exceeds maximum of ${opts.maxBits} bits`);
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
return bigValue | (1n << bigPosition);
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
/**
|
|
311
|
-
* Clears bit at specified position
|
|
312
|
-
*/
|
|
313
|
-
export function clearBit(
|
|
314
|
-
value: bigint | string | number,
|
|
315
|
-
position: bigint | string | number,
|
|
316
|
-
options: BitwiseOptions = {}
|
|
317
|
-
): bigint {
|
|
318
|
-
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
319
|
-
const bigValue = toBigInt(value);
|
|
320
|
-
const bigPosition = toBigInt(position);
|
|
321
|
-
|
|
322
|
-
validateNonNegative(bigPosition);
|
|
323
|
-
if (opts.strict && bigPosition >= BigInt(opts.maxBits)) {
|
|
324
|
-
throw new ValidationError(`Bit position exceeds maximum of ${opts.maxBits} bits`);
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
return bigValue & ~(1n << bigPosition);
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
/**
|
|
331
|
-
* Toggles bit at specified position
|
|
332
|
-
*/
|
|
333
|
-
export function toggleBit(
|
|
334
|
-
value: bigint | string | number,
|
|
335
|
-
position: bigint | string | number,
|
|
336
|
-
options: BitwiseOptions = {}
|
|
337
|
-
): bigint {
|
|
338
|
-
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
339
|
-
const bigValue = toBigInt(value);
|
|
340
|
-
const bigPosition = toBigInt(position);
|
|
341
|
-
|
|
342
|
-
validateNonNegative(bigPosition);
|
|
343
|
-
if (opts.strict && bigPosition >= BigInt(opts.maxBits)) {
|
|
344
|
-
throw new ValidationError(`Bit position exceeds maximum of ${opts.maxBits} bits`);
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
return bigValue ^ (1n << bigPosition);
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
export default {
|
|
351
|
-
and,
|
|
352
|
-
or,
|
|
353
|
-
xor,
|
|
354
|
-
not,
|
|
355
|
-
leftShift,
|
|
356
|
-
rightShift,
|
|
357
|
-
unsignedRightShift,
|
|
358
|
-
rotateLeft,
|
|
359
|
-
rotateRight,
|
|
360
|
-
popCount,
|
|
361
|
-
trailingZeros,
|
|
362
|
-
leadingZeros,
|
|
363
|
-
getBit,
|
|
364
|
-
setBit,
|
|
365
|
-
clearBit,
|
|
366
|
-
toggleBit
|
|
1
|
+
/**
|
|
2
|
+
* Bitwise operations module for Hypernum library
|
|
3
|
+
* Provides functions for bit-level manipulations of large numbers
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
toBigInt,
|
|
8
|
+
ValidationError,
|
|
9
|
+
validateNonNegative
|
|
10
|
+
} from '../utils/validation';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Options for bitwise operations
|
|
14
|
+
*/
|
|
15
|
+
export interface BitwiseOptions {
|
|
16
|
+
/** Maximum bits to consider in operations */
|
|
17
|
+
maxBits?: number;
|
|
18
|
+
/** Whether to throw on overflow */
|
|
19
|
+
strict?: boolean;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const DEFAULT_OPTIONS: Required<BitwiseOptions> = {
|
|
23
|
+
maxBits: 1024,
|
|
24
|
+
strict: true
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Validates shift amount is within reasonable bounds
|
|
29
|
+
*/
|
|
30
|
+
function validateShift(shift: bigint, options: Required<BitwiseOptions>): void {
|
|
31
|
+
if (shift < 0n) {
|
|
32
|
+
throw new ValidationError('Shift amount cannot be negative');
|
|
33
|
+
}
|
|
34
|
+
if (options.strict && shift >= BigInt(options.maxBits)) {
|
|
35
|
+
throw new ValidationError(`Shift amount exceeds maximum of ${options.maxBits} bits`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Performs bitwise AND operation
|
|
41
|
+
*/
|
|
42
|
+
export function and(
|
|
43
|
+
a: bigint | string | number,
|
|
44
|
+
b: bigint | string | number
|
|
45
|
+
): bigint {
|
|
46
|
+
const bigA = toBigInt(a);
|
|
47
|
+
const bigB = toBigInt(b);
|
|
48
|
+
|
|
49
|
+
return bigA & bigB;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Performs bitwise OR operation
|
|
54
|
+
*/
|
|
55
|
+
export function or(
|
|
56
|
+
a: bigint | string | number,
|
|
57
|
+
b: bigint | string | number
|
|
58
|
+
): bigint {
|
|
59
|
+
const bigA = toBigInt(a);
|
|
60
|
+
const bigB = toBigInt(b);
|
|
61
|
+
|
|
62
|
+
return bigA | bigB;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Performs bitwise XOR operation
|
|
67
|
+
*/
|
|
68
|
+
export function xor(
|
|
69
|
+
a: bigint | string | number,
|
|
70
|
+
b: bigint | string | number
|
|
71
|
+
): bigint {
|
|
72
|
+
const bigA = toBigInt(a);
|
|
73
|
+
const bigB = toBigInt(b);
|
|
74
|
+
|
|
75
|
+
return bigA ^ bigB;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Performs bitwise NOT operation
|
|
80
|
+
*/
|
|
81
|
+
export function not(
|
|
82
|
+
value: bigint | string | number
|
|
83
|
+
): bigint {
|
|
84
|
+
const bigValue = toBigInt(value);
|
|
85
|
+
|
|
86
|
+
return ~bigValue;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Performs left shift operation
|
|
91
|
+
*/
|
|
92
|
+
export function leftShift(
|
|
93
|
+
value: bigint | string | number,
|
|
94
|
+
shift: bigint | string | number,
|
|
95
|
+
options: BitwiseOptions = {}
|
|
96
|
+
): bigint {
|
|
97
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
98
|
+
const bigValue = toBigInt(value);
|
|
99
|
+
const bigShift = toBigInt(shift);
|
|
100
|
+
|
|
101
|
+
validateShift(bigShift, opts);
|
|
102
|
+
return bigValue << bigShift;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Performs right shift operation
|
|
107
|
+
*/
|
|
108
|
+
export function rightShift(
|
|
109
|
+
value: bigint | string | number,
|
|
110
|
+
shift: bigint | string | number,
|
|
111
|
+
options: BitwiseOptions = {}
|
|
112
|
+
): bigint {
|
|
113
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
114
|
+
const bigValue = toBigInt(value);
|
|
115
|
+
const bigShift = toBigInt(shift);
|
|
116
|
+
|
|
117
|
+
validateShift(bigShift, opts);
|
|
118
|
+
return bigValue >> bigShift;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Performs unsigned right shift operation
|
|
123
|
+
* Note: BigInt doesn't have >>> operator, so we implement it manually
|
|
124
|
+
*/
|
|
125
|
+
export function unsignedRightShift(
|
|
126
|
+
value: bigint | string | number,
|
|
127
|
+
shift: bigint | string | number,
|
|
128
|
+
options: BitwiseOptions = {}
|
|
129
|
+
): bigint {
|
|
130
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
131
|
+
const bigValue = toBigInt(value);
|
|
132
|
+
const bigShift = toBigInt(shift);
|
|
133
|
+
|
|
134
|
+
validateShift(bigShift, opts);
|
|
135
|
+
|
|
136
|
+
if (bigValue >= 0n) {
|
|
137
|
+
return bigValue >> bigShift;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Handle negative numbers by first converting to positive
|
|
141
|
+
const mask = (1n << BigInt(opts.maxBits)) - 1n;
|
|
142
|
+
return (bigValue & mask) >> bigShift;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Rotates bits left by specified amount
|
|
147
|
+
*/
|
|
148
|
+
export function rotateLeft(
|
|
149
|
+
value: bigint | string | number,
|
|
150
|
+
rotation: bigint | string | number,
|
|
151
|
+
options: BitwiseOptions = {}
|
|
152
|
+
): bigint {
|
|
153
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
154
|
+
const bigValue = toBigInt(value);
|
|
155
|
+
let bigRotation = toBigInt(rotation);
|
|
156
|
+
|
|
157
|
+
validateNonNegative(bigRotation);
|
|
158
|
+
|
|
159
|
+
// Normalize rotation to be within maxBits
|
|
160
|
+
if (bigRotation >= BigInt(opts.maxBits)) {
|
|
161
|
+
bigRotation = bigRotation % BigInt(opts.maxBits);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (bigRotation === 0n) {
|
|
165
|
+
return bigValue;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const leftPart = leftShift(bigValue, bigRotation, opts);
|
|
169
|
+
const rightPart = unsignedRightShift(bigValue, BigInt(opts.maxBits) - bigRotation, opts);
|
|
170
|
+
|
|
171
|
+
return leftPart | rightPart;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Rotates bits right by specified amount
|
|
176
|
+
*/
|
|
177
|
+
export function rotateRight(
|
|
178
|
+
value: bigint | string | number,
|
|
179
|
+
rotation: bigint | string | number,
|
|
180
|
+
options: BitwiseOptions = {}
|
|
181
|
+
): bigint {
|
|
182
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
183
|
+
const bigValue = toBigInt(value);
|
|
184
|
+
let bigRotation = toBigInt(rotation);
|
|
185
|
+
|
|
186
|
+
validateNonNegative(bigRotation);
|
|
187
|
+
|
|
188
|
+
// Normalize rotation to be within maxBits
|
|
189
|
+
if (bigRotation >= BigInt(opts.maxBits)) {
|
|
190
|
+
bigRotation = bigRotation % BigInt(opts.maxBits);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (bigRotation === 0n) {
|
|
194
|
+
return bigValue;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const rightPart = unsignedRightShift(bigValue, bigRotation, opts);
|
|
198
|
+
const leftPart = leftShift(bigValue, BigInt(opts.maxBits) - bigRotation, opts);
|
|
199
|
+
|
|
200
|
+
return leftPart | rightPart;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Counts number of set bits (1s)
|
|
205
|
+
*/
|
|
206
|
+
export function popCount(
|
|
207
|
+
value: bigint | string | number,
|
|
208
|
+
options: BitwiseOptions = {}
|
|
209
|
+
): bigint {
|
|
210
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
211
|
+
let bigValue = toBigInt(value);
|
|
212
|
+
|
|
213
|
+
let count = 0n;
|
|
214
|
+
while (bigValue !== 0n) {
|
|
215
|
+
count += bigValue & 1n;
|
|
216
|
+
bigValue = unsignedRightShift(bigValue, 1n, opts);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
return count;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Returns number of trailing zero bits
|
|
224
|
+
*/
|
|
225
|
+
export function trailingZeros(
|
|
226
|
+
value: bigint | string | number,
|
|
227
|
+
options: BitwiseOptions = {}
|
|
228
|
+
): bigint {
|
|
229
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
230
|
+
let bigValue = toBigInt(value);
|
|
231
|
+
|
|
232
|
+
if (bigValue === 0n) {
|
|
233
|
+
return BigInt(opts.maxBits);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
let count = 0n;
|
|
237
|
+
while ((bigValue & 1n) === 0n) {
|
|
238
|
+
count++;
|
|
239
|
+
bigValue = unsignedRightShift(bigValue, 1n, opts);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
return count;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Returns number of leading zero bits
|
|
247
|
+
*/
|
|
248
|
+
export function leadingZeros(
|
|
249
|
+
value: bigint | string | number,
|
|
250
|
+
options: BitwiseOptions = {}
|
|
251
|
+
): bigint {
|
|
252
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
253
|
+
let bigValue = toBigInt(value);
|
|
254
|
+
|
|
255
|
+
if (bigValue === 0n) {
|
|
256
|
+
return BigInt(opts.maxBits);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
let count = 0n;
|
|
260
|
+
const msb = 1n << BigInt(opts.maxBits - 1);
|
|
261
|
+
|
|
262
|
+
while ((bigValue & msb) === 0n && count < BigInt(opts.maxBits)) {
|
|
263
|
+
count++;
|
|
264
|
+
bigValue = leftShift(bigValue, 1n, opts);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
return count;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Returns bit at specified position
|
|
272
|
+
*/
|
|
273
|
+
export function getBit(
|
|
274
|
+
value: bigint | string | number,
|
|
275
|
+
position: bigint | string | number,
|
|
276
|
+
options: BitwiseOptions = {}
|
|
277
|
+
): boolean {
|
|
278
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
279
|
+
const bigValue = toBigInt(value);
|
|
280
|
+
const bigPosition = toBigInt(position);
|
|
281
|
+
|
|
282
|
+
validateNonNegative(bigPosition);
|
|
283
|
+
if (opts.strict && bigPosition >= BigInt(opts.maxBits)) {
|
|
284
|
+
throw new ValidationError(`Bit position exceeds maximum of ${opts.maxBits} bits`);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
return (bigValue & (1n << bigPosition)) !== 0n;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Sets bit at specified position
|
|
292
|
+
*/
|
|
293
|
+
export function setBit(
|
|
294
|
+
value: bigint | string | number,
|
|
295
|
+
position: bigint | string | number,
|
|
296
|
+
options: BitwiseOptions = {}
|
|
297
|
+
): bigint {
|
|
298
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
299
|
+
const bigValue = toBigInt(value);
|
|
300
|
+
const bigPosition = toBigInt(position);
|
|
301
|
+
|
|
302
|
+
validateNonNegative(bigPosition);
|
|
303
|
+
if (opts.strict && bigPosition >= BigInt(opts.maxBits)) {
|
|
304
|
+
throw new ValidationError(`Bit position exceeds maximum of ${opts.maxBits} bits`);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
return bigValue | (1n << bigPosition);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Clears bit at specified position
|
|
312
|
+
*/
|
|
313
|
+
export function clearBit(
|
|
314
|
+
value: bigint | string | number,
|
|
315
|
+
position: bigint | string | number,
|
|
316
|
+
options: BitwiseOptions = {}
|
|
317
|
+
): bigint {
|
|
318
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
319
|
+
const bigValue = toBigInt(value);
|
|
320
|
+
const bigPosition = toBigInt(position);
|
|
321
|
+
|
|
322
|
+
validateNonNegative(bigPosition);
|
|
323
|
+
if (opts.strict && bigPosition >= BigInt(opts.maxBits)) {
|
|
324
|
+
throw new ValidationError(`Bit position exceeds maximum of ${opts.maxBits} bits`);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
return bigValue & ~(1n << bigPosition);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Toggles bit at specified position
|
|
332
|
+
*/
|
|
333
|
+
export function toggleBit(
|
|
334
|
+
value: bigint | string | number,
|
|
335
|
+
position: bigint | string | number,
|
|
336
|
+
options: BitwiseOptions = {}
|
|
337
|
+
): bigint {
|
|
338
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
339
|
+
const bigValue = toBigInt(value);
|
|
340
|
+
const bigPosition = toBigInt(position);
|
|
341
|
+
|
|
342
|
+
validateNonNegative(bigPosition);
|
|
343
|
+
if (opts.strict && bigPosition >= BigInt(opts.maxBits)) {
|
|
344
|
+
throw new ValidationError(`Bit position exceeds maximum of ${opts.maxBits} bits`);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
return bigValue ^ (1n << bigPosition);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
export default {
|
|
351
|
+
and,
|
|
352
|
+
or,
|
|
353
|
+
xor,
|
|
354
|
+
not,
|
|
355
|
+
leftShift,
|
|
356
|
+
rightShift,
|
|
357
|
+
unsignedRightShift,
|
|
358
|
+
rotateLeft,
|
|
359
|
+
rotateRight,
|
|
360
|
+
popCount,
|
|
361
|
+
trailingZeros,
|
|
362
|
+
leadingZeros,
|
|
363
|
+
getBit,
|
|
364
|
+
setBit,
|
|
365
|
+
clearBit,
|
|
366
|
+
toggleBit
|
|
367
367
|
};
|