Stage: 2
Champions:
- Richard Gibson (@gibson042)
Specification: http://tc39.es/proposal-bigint-from-exponential/
Exponential notation is useful for dealing with big integers, but unavailable for direct use in defining a bigint.
Use of _ separators helps, but isn't quite enough for sufficiently large values.
BigInt(…) is lossy above 253.
Manual conversion is possible (e.g., /^(?:(0|[1-9][0-9]*)(?:[.]([0-9]*))?|[.]([0-9]+))(?:[Ee]([+-]?[0-9]+))?$/ validates and matches the relevant whole-number/fraction/decimal-exponent parts), but cumbersome and tedious.
This was discovered in Amount, but also comes up in other contexts (GitHub reports 20.3e3 files matching pattern BigInt[(][^)a-z]*[0-9]e[0-9]):
- parsing JSON like
{ "scale": 1e6 }with source text access - working with currencies and/or financial values, particularly fine-grained cryptocurrencies (e.g., in algorand-js)
- working with high-resolution dates or times (e.g., in the ECMAScript Temporal polyfill, and WASI libraries)
Many use cases are static, where the exponential notation is part of the source text, while others are dynamic and therefore require a built-in function.
For static use cases, we propose syntactic support like 1e6n1.
For dynamic use cases, we propose expanding the behavior of StringToBigInt as suggested by tc39/ecma262#3857, supporting BigInt("1e6")/BigUint64Array.from(["1e6"])/etc.
Note that this also affects operator behavior (e.g., 1_000_000n == "1e6" and 1_000_000n <= "1e6" and 1_000_000n >= "1e6", just like the Number analogs 1_000_000 == "1e6" and 1_000_000 <= "1e6" and 1_000_000 >= "1e6") absent explicit changes to preserve backwards compatibility.
Alternatives like BigInt.parse("1e6") or BigInt.fromString("1e6") could also be considered.
Dynamic use cases technically cover the static ones, albeit with erosion of developer experience and implementer satisfaction.
Some npm packages already support parsing exponential-notation strings into arbitrary-precision integers (or analogous strings):
- big-integer:
bigInt("9.007199254740993e15") - json-bigint:
parse("9.007199254740993e15") - from-exponential:
fromExponential("9.007199254740993e15")
And there is an even larger population of arbitrary-precision decimal libraries that generalize such behavior beyond integers.
Across other programming languages, .NET BigInteger.Parse(str, options) supports AllowDecimalPoint and AllowExponent options, but that seems to be as far as it goes:
| Language/API | Leading +/- |
Wrapping whitespace | Radix prefixes (e.g. 0x) |
Separators (e.g. _) |
Decimal/exponent |
|---|---|---|---|---|---|
Go (new(big.Int)).SetString(str, 0) |
yes | no | yes | yes | no |
Java new BigInteger(str, radix) |
yes | no | n/a | no | no |
JavaScript BigInt(str) |
yes | yes | yes | no | no |
.NET BigInteger.Parse(str, options) |
optional | optional | no | optional | optional |
Python int(str, base=0) |
yes | yes | yes | yes | no |
Rust num_bigint from_str_radix(&str, radix) |
yes | no | n/a | yes | no |
And for context, ECMAScript is unusual in its strictness:
| Language/API | Floating-point → arbitrary-precision integer |
|---|---|
Go (*big.Float).Int(new(big.Int)) |
truncates toward zero |
Java bigDecimal.toBigInteger() |
truncates toward zero |
JavaScript BigInt(flt) |
rejects non-integer |
.NET new BigInteger(flt) |
truncates toward zero |
Python int(flt) |
truncates toward zero |
Rust num_bigint from_f64(flt) |
truncates toward zero |
- as normative PR #3857: May 2026 TC39 plenary (notes)
- converted to a Stage 1 proposal: July 2026 TC39 plenary (slides)
- for Stage 2: September 2026 TC39 plenary (slides)
None yet.
Check here after Stage 2.7.
Q: Should dynamic parsing also support _ separators?
A: Not through BigInt(string), but maybe through a different API.
Q: Should dynamic parsing be configurable?
A: Not without doing the same for numbers, which seems like a separate proposal.
Q: Are decimals allowed as in e.g. BigInt("86.4e12") === 86_400_000_000_000n?
A: Yes, and this is important for precision-preserving canonical forms (e.g., differentiating 1.000e3n from 1e3n).
Q: #8 Are negative exponents allowed as in e.g. 1230e-1n === 123n?
A: To be determined. Restricting support to non-negative exponents would not be difficult.
Q: #9 Is it web-compatible to change the behavior of 1_000_000n == "1e6" and 1_000_000n <= "1e6" and 1_000_000n >= "1e6"?
A: To be determined, but if not then it is still possible to carve out exceptions while still supporting the primary use cases.
Footnotes
-
This might be unprecedented in widespread programming languages (cf. https://github.com/tc39/ecma262/pull/3857#issuecomment-4960986324). ↩