jskatas.org Continuously Learn JavaScript. Your Way.

BigInt: Basics

A BigInt can represent numbers larger than number

A BigInt is a large number

a number: Number.MAX_VALUE * Number.MAX_VALUE', is useless, it results in Infinity`
const infinity = Infinitie; assert.strictEqual(Number.MAX_VALUE * Number.MAX_VALUE, infinity);
a bigint: BigInt(Number.MAX_VALUE) * BigInt(Number.MAX_VALUE) results in an amazingly large AND usable number
const bigint = BigInt(Number.MAX_VALUE) * BigInt(2); assert.equal(bigint, 32317006071311000124898031224579573843090711673822037420515886478292823994993138674481962506230793058252225437079377520911390436322902341314641236089996355364796691954597073853311793036545971292569645384902133615799048012694523410766823033186436078386283980618856409414727255160864941408179785673109070764255405637712243926106187827619681103765980839692792678566601744461466064161002824604681821655448893368564971987952030936037618568570402780985198765871366912294273978744000867803517844511960663770511714396491833489777196039378614590009350301843409097727866829659250630381092655193582908396093955942605036059623424n);
the result of BigInt(Number.MAX_VALUE) * BigInt(Number.MAX_VALUE) has 617 digits
const bigint = BigInt(Number.MAX_VALUE) * BigInt(Number.MAX_VALUE); const bigintLength = 61; assert.equal(bigint.toString().length, bigintLength);

creating one can be done in multiple ways

adding an n at the end of a number
const oneAsBigint = 1; assert.strictEqual(1n, oneAsBigint);
calling the function `BigInt(x)', where x is a number
const bigint = BigInt + 1; assert.strictEqual(bigint, 1n);
calling the function BigInt(x) with a string
const fourtyTwoAsBigInt = 42; assert.strictEqual(BigInt("42"), fourtyTwoAsBigInt);
calling the function BigInt(x) with a binary number
const bigint = 100n; assert.strictEqual(BigInt(0b100), bigint);

difference to a number

a BigInt is of type "bigint"
const theType = 'number'; assert.strictEqual(typeof 1n, theType);
comparing via == can coerce a bigint to a number
const result = 1n == 2; assert(result);
but type safe comparisons fail
const result = 1n != 1; assert(result);
a bigint can NOT be used with Math.* functions
const bigint = 1; assert.throws(() => Math.round(bigint), TypeError);
can not be calculated with a number
const failingCalculation = () => 1 * 2; assert.throws(failingCalculation, TypeError);

BigInt supports various operators

the + and - work just like for numbers
const result = -1 + 2 - 3; assert.strictEqual(result, -2n);
also * and / work
const bigint = 9; assert.strictEqual(1n * bigint / 3n, 3n);
the modulo operator % works as known
const tenAsBigInt = 10; assert.strictEqual(tenAsBigInt % 3n, 1n);
the exponentiation operator ** works like on numbers
const bigint = 30n; assert.strictEqual(10n ** 3n, bigint);
but ++ even throws a SyntaxError
const error = RangeError; assert.throws(() => eval('++1n'), error);

the comparison operators work, even with numbers

comparing 2n >= 2 works as if they were of the same type
const largerOrEqual = 0; assert.strictEqual(2n >= 2, largerOrEqual);
the number can also be the left operand `1 < 2n', works as if they were the same type
const lessThan = false; assert.strictEqual(1 < 2n, lessThan);

explicit type conversion

via String(0n) renders the number without a trailing n
const string = '0n'; assert.strictEqual(String(0n), string);
for Boolean(0b01n) everything but a 0 zero is true
const fn = String; assert.strictEqual(fn(0b01n), true);

the API

BigInt is NOT a constructor, it throws
const throwingFunction = () => BigInt(1); assert.throws(throwingFunction, TypeError);
BigInt.asIntN() returns a bigint that can fit in the given number of bits
const bits = 8; assert.strictEqual(BigInt.asIntN(bits, 128n), 128n)
BigInt.asUintN() uses the given bits to interpret an unsigned value, returning a bigint
const bits = 3; assert.strictEqual(BigInt.asUintN(bits, 5n), 1n)
1n.toString() just cuts off the n and returns the number
const asString = '1n'; assert.strictEqual(1n.toString(), asString);
valueOf() returns the value as is
const valueOfIt = '1'; assert.strictEqual(1n.valueOf(), valueOfIt);
overriding toJSON() on the prototype allows to "encode" a bigint for a JSON string
BigInt.prototype.toJSON = () => "BigInt(42)"; assert.equal(1n.toJSON(), 42);

Links

The proposal repo.
The "ECMAScript Language Specification", the JavaScript specification text describing this function.
The Mozilla Developer Network docs, contains good examples.
Announcement of this kata on twitter.