Pure-JavaScript implementation of ECMAScript BigInt for arbitrary-precision integer arithmetic.
npx @tessl/cli install tessl/npm-jsbi@4.3.00
# JSBI
1
2
JSBI is a pure-JavaScript implementation of the ECMAScript BigInt proposal, providing arbitrary-precision integer arithmetic that behaves exactly like native BigInts. It enables BigInt functionality in environments that don't support native BigInts and can be mechanically transpiled to native BigInt code when available.
3
4
## Package Information
5
6
- **Package Name**: jsbi
7
- **Package Type**: npm
8
- **Language**: TypeScript
9
- **Installation**: `npm install jsbi`
10
11
## Core Imports
12
13
```typescript
14
import JSBI from "jsbi";
15
```
16
17
For CommonJS:
18
19
```javascript
20
const JSBI = require("jsbi");
21
```
22
23
For ES modules (browser):
24
25
```javascript
26
import JSBI from "./jsbi.mjs";
27
```
28
29
## Basic Usage
30
31
```typescript
32
import JSBI from "jsbi";
33
34
// Create BigInt-like values from various types
35
const max = JSBI.BigInt(Number.MAX_SAFE_INTEGER);
36
const fromString = JSBI.BigInt("123456789012345678901234567890");
37
const two = JSBI.BigInt(2);
38
39
// Perform arithmetic operations
40
const sum = JSBI.add(max, two);
41
const product = JSBI.multiply(fromString, two);
42
const quotient = JSBI.divide(fromString, two);
43
44
// Convert back to string/number
45
console.log(sum.toString()); // "9007199254740993"
46
console.log(JSBI.toNumber(two)); // 2
47
48
// Comparisons
49
const isLess = JSBI.lessThan(two, max); // true
50
const areEqual = JSBI.equal(two, JSBI.BigInt(2)); // true
51
52
// Bitwise operations
53
const shifted = JSBI.leftShift(two, JSBI.BigInt(3)); // 16
54
const anded = JSBI.bitwiseAnd(fromString, JSBI.BigInt(255));
55
```
56
57
## Architecture
58
59
JSBI is implemented as a single class extending Array that provides all BigInt operations through static methods:
60
61
- **Immutable Operations**: All methods return new JSBI instances without modifying existing ones
62
- **Static Method API**: All operations are accessed as `JSBI.methodName()`
63
- **Type Compatibility**: Designed for mechanical transpilation to native BigInt syntax
64
- **Cross-Platform**: Works in all JavaScript environments (browsers, Node.js)
65
- **Performance Focus**: Optimized implementation competitive with native BigInt
66
67
## Capabilities
68
69
### Creation and Conversion
70
71
Create JSBI instances from various input types and convert back to JavaScript primitives.
72
73
```typescript { .api }
74
/**
75
* Creates a JSBI instance from number, string, boolean, or object
76
* @param arg - Input value to convert to BigInt
77
* @returns JSBI instance representing the BigInt value
78
* @throws RangeError for non-integer numbers or numbers outside safe range
79
* @throws SyntaxError for invalid string inputs
80
* @throws TypeError for unconvertible object inputs
81
*/
82
static BigInt(arg: number | string | boolean | object): JSBI;
83
84
/**
85
* Converts JSBI instance to JavaScript number (may lose precision)
86
* @param x - JSBI instance to convert
87
* @returns JavaScript number representation
88
*/
89
static toNumber(x: JSBI): number;
90
91
/**
92
* Converts JSBI to string representation in specified radix
93
* @param radix - Base for string conversion (2-36), defaults to 10
94
* @returns String representation of the BigInt value
95
* @throws RangeError if radix is outside valid range
96
*/
97
toString(radix?: number): string;
98
99
/**
100
* Returns debug representation showing internal digit structure
101
* @returns Debug string with internal representation
102
*/
103
toDebugString(): string;
104
105
/**
106
* Intentionally throws error to prevent accidental coercion
107
* @throws Error with guidance to use toNumber() instead
108
*/
109
valueOf(): void;
110
```
111
112
### Arithmetic Operations
113
114
Fundamental arithmetic operations for BigInt values.
115
116
```typescript { .api }
117
/**
118
* Returns the negation of x (-x)
119
* @param x - JSBI instance to negate
120
* @returns New JSBI instance with opposite sign
121
*/
122
static unaryMinus(x: JSBI): JSBI;
123
124
/**
125
* Returns sum of x and y (x + y)
126
* @param x - First operand
127
* @param y - Second operand
128
* @returns New JSBI instance with the sum
129
*/
130
static add(x: JSBI, y: JSBI): JSBI;
131
132
/**
133
* Returns difference of x and y (x - y)
134
* @param x - Minuend
135
* @param y - Subtrahend
136
* @returns New JSBI instance with the difference
137
*/
138
static subtract(x: JSBI, y: JSBI): JSBI;
139
140
/**
141
* Returns product of x and y (x * y)
142
* @param x - Multiplicand
143
* @param y - Multiplier
144
* @returns New JSBI instance with the product
145
*/
146
static multiply(x: JSBI, y: JSBI): JSBI;
147
148
/**
149
* Returns quotient of x divided by y (x / y)
150
* @param x - Dividend
151
* @param y - Divisor
152
* @returns New JSBI instance with the quotient
153
* @throws RangeError if y is zero
154
*/
155
static divide(x: JSBI, y: JSBI): JSBI;
156
157
/**
158
* Returns remainder of x divided by y (x % y)
159
* @param x - Dividend
160
* @param y - Divisor
161
* @returns New JSBI instance with the remainder
162
* @throws RangeError if y is zero
163
*/
164
static remainder(x: JSBI, y: JSBI): JSBI;
165
166
/**
167
* Returns x raised to the power of y (x ** y)
168
* @param x - Base
169
* @param y - Exponent (must be non-negative)
170
* @returns New JSBI instance with the result
171
* @throws RangeError if y is negative or result would be too large
172
*/
173
static exponentiate(x: JSBI, y: JSBI): JSBI;
174
```
175
176
### Bitwise Operations
177
178
Bitwise manipulation operations following BigInt semantics.
179
180
```typescript { .api }
181
/**
182
* Returns bitwise NOT of x (~x)
183
* @param x - JSBI instance to invert
184
* @returns New JSBI instance with all bits flipped
185
*/
186
static bitwiseNot(x: JSBI): JSBI;
187
188
/**
189
* Returns bitwise AND of x and y (x & y)
190
* @param x - First operand
191
* @param y - Second operand
192
* @returns New JSBI instance with bitwise AND result
193
*/
194
static bitwiseAnd(x: JSBI, y: JSBI): JSBI;
195
196
/**
197
* Returns bitwise OR of x and y (x | y)
198
* @param x - First operand
199
* @param y - Second operand
200
* @returns New JSBI instance with bitwise OR result
201
*/
202
static bitwiseOr(x: JSBI, y: JSBI): JSBI;
203
204
/**
205
* Returns bitwise XOR of x and y (x ^ y)
206
* @param x - First operand
207
* @param y - Second operand
208
* @returns New JSBI instance with bitwise XOR result
209
*/
210
static bitwiseXor(x: JSBI, y: JSBI): JSBI;
211
212
/**
213
* Returns x left-shifted by y bits (x << y)
214
* @param x - Value to shift
215
* @param y - Number of bit positions to shift (negative shifts right)
216
* @returns New JSBI instance with shifted value
217
* @throws RangeError if shift amount is too large
218
*/
219
static leftShift(x: JSBI, y: JSBI): JSBI;
220
221
/**
222
* Returns x right-shifted by y bits with sign extension (x >> y)
223
* @param x - Value to shift
224
* @param y - Number of bit positions to shift (negative shifts left)
225
* @returns New JSBI instance with shifted value
226
* @throws RangeError if shift amount is too large
227
*/
228
static signedRightShift(x: JSBI, y: JSBI): JSBI;
229
230
/**
231
* Intentionally throws error as BigInt has no unsigned right shift
232
* @throws TypeError indicating BigInts don't support unsigned right shift
233
*/
234
static unsignedRightShift(): void;
235
```
236
237
### Comparison Operations
238
239
Comparison operations returning boolean results.
240
241
```typescript { .api }
242
/**
243
* Returns true if x < y
244
* @param x - First operand
245
* @param y - Second operand
246
* @returns Boolean result of comparison
247
*/
248
static lessThan(x: JSBI, y: JSBI): boolean;
249
250
/**
251
* Returns true if x <= y
252
* @param x - First operand
253
* @param y - Second operand
254
* @returns Boolean result of comparison
255
*/
256
static lessThanOrEqual(x: JSBI, y: JSBI): boolean;
257
258
/**
259
* Returns true if x > y
260
* @param x - First operand
261
* @param y - Second operand
262
* @returns Boolean result of comparison
263
*/
264
static greaterThan(x: JSBI, y: JSBI): boolean;
265
266
/**
267
* Returns true if x >= y
268
* @param x - First operand
269
* @param y - Second operand
270
* @returns Boolean result of comparison
271
*/
272
static greaterThanOrEqual(x: JSBI, y: JSBI): boolean;
273
274
/**
275
* Returns true if x equals y
276
* @param x - First operand
277
* @param y - Second operand
278
* @returns Boolean result of equality comparison
279
*/
280
static equal(x: JSBI, y: JSBI): boolean;
281
282
/**
283
* Returns true if x does not equal y
284
* @param x - First operand
285
* @param y - Second operand
286
* @returns Boolean result of inequality comparison
287
*/
288
static notEqual(x: JSBI, y: JSBI): boolean;
289
```
290
291
### Bit Manipulation
292
293
Operations for precise bit-level control and two's complement representation.
294
295
```typescript { .api }
296
/**
297
* Returns x wrapped to n-bit signed integer representation
298
* @param n - Number of bits for signed representation
299
* @param x - JSBI instance to wrap
300
* @returns New JSBI instance wrapped to n-bit signed range
301
* @throws RangeError if n is negative or not a safe integer
302
*/
303
static asIntN(n: number, x: JSBI): JSBI;
304
305
/**
306
* Returns x wrapped to n-bit unsigned integer representation
307
* @param n - Number of bits for unsigned representation
308
* @param x - JSBI instance to wrap
309
* @returns New JSBI instance wrapped to n-bit unsigned range
310
* @throws RangeError if n is negative, not a safe integer, or result too large
311
*/
312
static asUintN(n: number, x: JSBI): JSBI;
313
```
314
315
### Mixed-Type Operations
316
317
Type-aware operations that handle mixed JavaScript types with proper coercion.
318
319
```typescript { .api }
320
/**
321
* Performs type-aware addition with JavaScript type coercion
322
* @param x - First operand (any type)
323
* @param y - Second operand (any type)
324
* @returns String for string concatenation, number for numeric addition, or JSBI for BigInt addition
325
* @throws TypeError for incompatible type mixing
326
*/
327
static ADD(x: any, y: any): string | number | JSBI;
328
329
/**
330
* Type-aware less-than comparison
331
* @param x - First operand (any type)
332
* @param y - Second operand (any type)
333
* @returns Boolean result of comparison
334
*/
335
static LT(x: any, y: any): boolean;
336
337
/**
338
* Type-aware less-than-or-equal comparison
339
* @param x - First operand (any type)
340
* @param y - Second operand (any type)
341
* @returns Boolean result of comparison
342
*/
343
static LE(x: any, y: any): boolean;
344
345
/**
346
* Type-aware greater-than comparison
347
* @param x - First operand (any type)
348
* @param y - Second operand (any type)
349
* @returns Boolean result of comparison
350
*/
351
static GT(x: any, y: any): boolean;
352
353
/**
354
* Type-aware greater-than-or-equal comparison
355
* @param x - First operand (any type)
356
* @param y - Second operand (any type)
357
* @returns Boolean result of comparison
358
*/
359
static GE(x: any, y: any): boolean;
360
361
/**
362
* Type-aware equality comparison
363
* @param x - First operand (any type)
364
* @param y - Second operand (any type)
365
* @returns Boolean result of equality comparison
366
*/
367
static EQ(x: any, y: any): boolean;
368
369
/**
370
* Type-aware not-equal comparison
371
* @param x - First operand (any type)
372
* @param y - Second operand (any type)
373
* @returns Boolean result of inequality comparison
374
*/
375
static NE(x: any, y: any): boolean;
376
```
377
378
### DataView Integration
379
380
Methods for reading and writing BigInt values from/to DataView objects for binary data handling.
381
382
```typescript { .api }
383
/**
384
* Reads signed 64-bit integer from DataView as JSBI
385
* @param dataview - DataView to read from
386
* @param byteOffset - Byte offset within the DataView
387
* @param littleEndian - Whether to use little-endian byte order, defaults to false
388
* @returns JSBI instance representing the 64-bit signed integer
389
*/
390
static DataViewGetBigInt64(dataview: DataView, byteOffset: number, littleEndian?: boolean): JSBI;
391
392
/**
393
* Reads unsigned 64-bit integer from DataView as JSBI
394
* @param dataview - DataView to read from
395
* @param byteOffset - Byte offset within the DataView
396
* @param littleEndian - Whether to use little-endian byte order, defaults to false
397
* @returns JSBI instance representing the 64-bit unsigned integer
398
*/
399
static DataViewGetBigUint64(dataview: DataView, byteOffset: number, littleEndian?: boolean): JSBI;
400
401
/**
402
* Writes signed 64-bit JSBI value to DataView
403
* @param dataview - DataView to write to
404
* @param byteOffset - Byte offset within the DataView
405
* @param value - JSBI instance to write
406
* @param littleEndian - Whether to use little-endian byte order, defaults to false
407
*/
408
static DataViewSetBigInt64(dataview: DataView, byteOffset: number, value: JSBI, littleEndian?: boolean): void;
409
410
/**
411
* Writes unsigned 64-bit JSBI value to DataView
412
* @param dataview - DataView to write to
413
* @param byteOffset - Byte offset within the DataView
414
* @param value - JSBI instance to write (wrapped to unsigned 64-bit)
415
* @param littleEndian - Whether to use little-endian byte order, defaults to false
416
*/
417
static DataViewSetBigUint64(dataview: DataView, byteOffset: number, value: JSBI, littleEndian?: boolean): void;
418
```
419
420
## Types
421
422
The main JSBI class extends Array to store BigInt digits internally.
423
424
```typescript { .api }
425
declare class JSBI extends Array {
426
/**
427
* Private constructor - use JSBI.BigInt() to create instances
428
*/
429
private constructor();
430
431
/**
432
* Internal sign bit - true for negative numbers
433
*/
434
private sign: boolean;
435
436
/**
437
* Converts JSBI to string representation
438
* @param radix - Base for conversion (2-36), defaults to 10
439
* @returns String representation
440
*/
441
toString(radix?: number): string;
442
443
/**
444
* Returns debug string showing internal structure
445
* @returns Debug representation
446
*/
447
toDebugString(): string;
448
449
/**
450
* Intentionally throws to prevent accidental coercion
451
* @throws Error directing to use toNumber()
452
*/
453
valueOf(): void;
454
}
455
```
456
457
## Error Handling
458
459
JSBI follows native BigInt error handling patterns:
460
461
- **RangeError**: Division by zero, invalid bit counts, values outside representable range
462
- **SyntaxError**: Invalid string formats passed to `BigInt()`
463
- **TypeError**: Invalid type conversions, mixing BigInt with other types inappropriately
464
- **Error**: Accidental coercion attempts via `valueOf()`
465
466
## Common Patterns
467
468
**Creating from different types:**
469
```typescript
470
const fromNumber = JSBI.BigInt(42);
471
const fromString = JSBI.BigInt("12345678901234567890");
472
const fromHex = JSBI.BigInt("0x1a2b3c4d5e6f");
473
const fromBinary = JSBI.BigInt("0b1010101010");
474
const fromBoolean = JSBI.BigInt(true); // 1n
475
```
476
477
**String conversion for output:**
478
```typescript
479
const big = JSBI.BigInt("123456789");
480
console.log(big.toString()); // "123456789"
481
console.log(big.toString(16)); // "75bcd15" (hexadecimal)
482
console.log(String(big)); // "123456789"
483
484
// Explicit conversion needed for console.log
485
console.log(big); // Shows internal object structure
486
```
487
488
**Chaining operations:**
489
```typescript
490
const result = JSBI.add(
491
JSBI.multiply(JSBI.BigInt("100"), JSBI.BigInt("200")),
492
JSBI.BigInt("300")
493
); // (100 * 200) + 300 = 20300
494
```
495
496
**Working with native transpilation:**
497
```typescript
498
// JSBI code that can be mechanically converted to native BigInt:
499
const a = JSBI.BigInt(42);
500
const b = JSBI.add(a, JSBI.BigInt(8));
501
502
// Transpiles to:
503
// const a = BigInt(42);
504
// const b = a + BigInt(8);
505
```