Arbitrary-precision big-number math beyond JavaScript Number limits

Published: 2026-09-05

Why JavaScript Number loses digits above 2⁵³−1 and mishandles decimals like 0.1×0.2, and how arbitrary-precision libraries keep large integers and exact decimals accurate in the browser.

JavaScript’s built-in Number type is a 64-bit IEEE-754 float. That is fine for most UI math and everyday counters—but it is the wrong tool when you need every digit of a huge integer, or exact decimal arithmetic for values like 0.1 × 0.2. Past a hard limit, integers silently round; with fractions, familiar surprises like 0.1 + 0.2 !== 0.3 show up.

This guide explains those limits, what “arbitrary precision” means, and when to reach for a decimal library versus BigInt. For live add / multiply / divide / power / sqrt beyond Number limits—entirely in your browser—use the Big Number Calculator.

What Number can and cannot do

A JavaScript Number stores a sign, an exponent, and a 53-bit significand (including the implicit leading 1). Consequences that matter in practice:

Limit Value What breaks
Number.MAX_SAFE_INTEGER 2⁵³ − 1 = 9,007,199,254,740,991 Integers larger than this are not all representable; n + 1 may equal n
Number.MIN_SAFE_INTEGER −(2⁵³ − 1) Same loss of integer precision below this bound
Binary fractions e.g. 0.1, 0.2 Many decimal fractions have no exact binary encoding

Safe-integer trap (classic):

Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2; // true
9007199254740993 === 9007199254740992; // true — both collapse to the same float

Paste 9007199254740993 into a float-backed calculator and you may never see the last digit you typed. IDs, counters, and crypto-sized integers often live past this line.

Decimal trap (classic):

0.1 + 0.2; // 0.30000000000000004
0.1 * 0.2; // 0.020000000000000004

Neither 0.1 nor 0.2 is exact in binary floating point, so the product is not the decimal 0.02 you expect on paper. For money and “exact decimal” checks, float math needs explicit rounding—or a decimal library that stores digits in base 10.

For everyday percent and tip math where float-plus-round is enough, see Percent change, ratios, and tip/tax math. For base conversion of large integers (not decimal arithmetic), the Radix & Base Converter uses BigInt—a related but different tool.

Arbitrary precision in plain language

Arbitrary precision means the library grows digit storage as needed instead of packing everything into a fixed-width float. You trade a bit of speed and memory for:

  • Integers with hundreds or thousands of digits
  • Decimals with a controllable number of places after the point
  • Operations that stay consistent with schoolbook decimal arithmetic (within the library’s rounding rules)

LocalTools’ Big Number Calculator uses big.js in the browser: operands are parsed as decimal strings (commas, underscores, and spaces stripped; scientific notation like 1.5e+20 allowed), then evaluated with high working precision for division and square root.

Nothing is uploaded—useful when the figures are customer totals, inventory counts, or other sensitive quantities. See Why “local only” matters for developer tools.

BigInt vs decimal libraries

JavaScript also has BigInt for integers of unlimited size:

9007199254740993n + 1n; // 9007199254740994n — exact
BigInt Decimal library (e.g. big.js)
Integers beyond 2⁵³ Exact Exact
Fractions (0.1) Not supported (integers only) Supported
Math.sqrt, % on decimals Limited / different semantics Decimal ops with configurable precision
JSON / many APIs Often serialized as strings Same—treat as strings in transit

Rule of thumb: use BigInt (or a radix tool) when the domain is whole numbers and bit patterns; use a decimal big-number library when you need ÷, , or exact base-10 fractions. Mixing them carelessly (e.g. converting a BigInt through Number “just once”) reintroduces the float limit.

Operations that matter for large values

The Big Number Calculator exposes common ops with the same mental model as a desk calculator, but without Number cliffs:

Operation Notes
Add / subtract / multiply Exact for finite decimals within working precision
Divide Uses high intermediate precision (default 40 places) before optional display rounding
Modulo Remainder with a non-zero divisor
Power Exponent must be an integer (and fit a safe JS integer for the library call); fractional exponents are not supported
Square root Real numbers only—negative inputs are rejected
Absolute value / negate Unary ops on operand A

Example — past the safe integer:

  • A = 9007199254740993
  • Op = add, B = 1
  • Float Number may still show 9007199254740992 or collapse neighbors; big.js keeps 9007199254740994.

Example — exact-ish decimal product:

  • A = 0.1, B = 0.2, multiply
  • With full precision you get a clean decimal representation of the product under the library’s rules—not the binary float residue—then optionally round to 2 (or n) decimal places for display.

Optional round result to N decimal places is display/control rounding after the computation. Division and sqrt still compute with elevated working precision so long quotients do not collapse early.

When float is still fine

You do not need arbitrary precision for every number field:

  • Animation progress, layout sizes, and most charts
  • Approximate percentages where you round for the UI anyway
  • Values you already store and compare as strings (IDs) without doing arithmetic

Reach for big decimals when equality of digits matters: ledger checks, “does this product equal 0.02?”, counters past 2⁵³, or documentation that must show the full integer a protocol uses.

A practical local workflow

  1. Paste operand A (and B for binary ops). Grouping commas / underscores are ignored.
  2. Pick the operation; for power, keep B an integer.
  3. Leave full precision, or round to a fixed number of decimal places for money-like copy-out.
  4. Copy the exact result or scientific notation into the ticket, test fixture, or config.

All of that stays on your device in the Big Number Calculator.

Related tools and reading

All learn articles