Bigint from exponential S2
中文标题:从指数表示法构造 BigInt
- 阶段: Stage 2
- 状态: 进行中
- ECMAScript 版本: —
- 同步时间: 2026年10月11日
- English original · 官方仓库
指数表示法在处理大整数时很有用,但无法直接用于定义 BigInt,且 BigInt(…) 在 2^53 以上会有损。该提案为静态用例提供 1e6n 这样的语法支持,并扩展 StringToBigInt,使 BigInt("1e6")、BigUint64Array.from(\["1e6"\]) 等动态用例能够解析指数表示法字符串。除非为保持向后兼容性作出明确更改,否则这一扩展也会影响运算符行为。还考虑了 BigInt.parse("1e6") 或 BigInt.fromString("1e6") 等替代方案。
以下 README 来自上游仓库,其中的阶段或状态标注可能滞后;当前信息以提案概览为准。
从指数表示法构造 BigInt
状态
阶段:2
负责人:
- Richard Gibson (@gibson042)
规范:http://tc39.es/proposal-bigint-from-exponential/
动机
指数表示法在处理大整数时很有用,但在定义 bigint 时无法直接使用。
使用 _ 分隔符有所帮助,但对于足够大的值来说仍不够。
BigInt(…) 在大于 253 时有损。
手动转换是可能的(例如,/^(?:(0|[1-9][0-9]*)(?:[.]([0-9]*))?|[.]([0-9]+))(?:[Ee]([+-]?[0-9]+))?$/ 会验证并匹配相关的整数/小数/十进制指数部分),但繁琐且乏味。
用例
这一点是在 Amount 中发现的,但也会出现在其他场景中(GitHub 报告有 20.3e3 个文件匹配模式 BigInt[(][^)a-z]*[0-9]e[0-9]):
- 在可访问源文本的情况下解析像
{ "scale": 1e6 }这样的 JSON - 处理货币和/或金融值,尤其是细粒度的加密货币(例如,在 algorand-js 中)
- 处理高分辨率日期或时间(例如,在 ECMAScript Temporal polyfill 和 WASI libraries 中)
许多用例是静态的,其中指数表示法是源文本的一部分,而另一些用例是动态的,因此需要内置函数。
描述
对于静态用例,我们提议像 1e6n1 这样的语法支持。
对于动态用例,我们提议按照 https://github.com/tc39/ecma262/pull/3857 的建议扩展 StringToBigInt 的行为,支持 BigInt("1e6")/BigUint64Array.from(["1e6"])/等。
注意,在没有为保持向后兼容性而作出明确更改时,这也会影响运算符行为(例如,1_000_000n == "1e6" 和 1_000_000n <= "1e6" 和 1_000_000n >= "1e6",就像 Number 的对应形式 1_000_000 == "1e6" 和 1_000_000 <= "1e6" 和 1_000_000 >= "1e6" 一样)。
也可以考虑 BigInt.parse("1e6") 或 BigInt.fromString("1e6") 这样的替代方案。
动态用例在技术上覆盖了静态用例,尽管会损害开发者体验和实现者满意度。
现有技术
一些 npm 包已经支持将指数表示法字符串解析为任意精度整数(或类似字符串):
- big-integer:
bigInt("9.007199254740993e15") - json-bigint:
parse("9.007199254740993e15") - from-exponential:
fromExponential("9.007199254740993e15")
还有更多任意精度十进制库将这种行为推广到整数之外。
在其他编程语言中,.NET BigInteger.Parse(str, options) 支持 AllowDecimalPoint 和 AllowExponent 选项,但似乎仅止于此:
作为背景,ECMAScript 在严格性方面很不寻常:
陈述历史
- 作为规范性 PR #3857:2026 年 5 月 TC39 全体会议(会议记录)
- 转为 Stage 1 提案:2026 年 7 月 TC39 全体会议(幻灯片)
- 进入 Stage 2:2026 年 9 月 TC39 全体会议(幻灯片)
实现
Polyfill/转译器实现
暂无。
原生实现
在 Stage 2.7 后查看此处。
常见问题
问:动态解析是否也应支持 _ 分隔符?
答:不通过 BigInt(string),但也许可通过其他 API。
问:动态解析是否应可配置?
答:除非对数字也这样做,否则不应可配置,而那似乎是一个单独的提案。
问:是否允许小数,例如 BigInt("86.4e12") === 86_400_000_000_000n?
答:允许,这对于保持精度的规范形式很重要(例如,区分 1.000e3n 和 1e3n)。
问:#8 是否允许负指数,例如 1230e-1n === 123n?
答:待定。将支持限制为非负指数并不困难。
问:#9 改变 1_000_000n == "1e6" 和 1_000_000n <= "1e6" 和 1_000_000n >= "1e6" 的行为是否与 Web 兼容?
答:待定,但如果不是,那么在仍支持主要用例的同时,仍有可能划出例外。
Footnotes
-
这在广泛使用的编程语言中可能是前所未有的(参见 https://github.com/tc39/ecma262/pull/3857#issuecomment-4960986324)。 ↩