JavaScript 所有数字内部都是 float64 类型,所以数值的精度最多只能到 53 个二进制位,大于这个范围的整数是无法精确表示的。
| 1 | 2 ** 53; | 
在很多金融场景如果使用 JS 的话就得使用一些 BigNumber 库。其中以太坊 web3.js 使用的是最为流行的是 bignumber.js,并且包含 .d.ts 类型提示,推荐在生产环境使用。
因为这些库表示大数的方式是以 16 进制字符串表示的,通常在实践中还需要使用 Buffer.from() 转换成二进制对象,还是有很多不方便,需要写很多辅助函数。不过以后我们就可以使用官方标准库中的 BigInt 了。
目前(2018 年 5 月 1 日)BigInt 提案已经进入 TC39 stage 3,不过还是被 V8 引擎提前实现,本文所有代码示例基于 Chrome Canary 68.0.3415.0,如下图所示。
| 1 | typeof 123; | 
BigInt 表示没有精度和大小限制的整数,为了兼容性考虑,在数字后面添加后缀n 和普通数字类型区分,使用二进制八进制和十六进制也可以表示。
| 1 | 123n; | 
数字的字符串形式可以类似于 Number() 使用 BigInt() 直接转换为 BigInt,需要注意的是参数检查和 Number() 是一致的,是不能使用 123n 字符串形式的参数。
| 1 | 123n; | 
BitInt 除了不能和 number 类型直接运算之外,其它方面和普通的数值运算没有多少区别,除法运算始终返回整数形式。
| 1 | 5n / 2n; | 
BigInt 也存在隐式转换,在相等运算符==、不同类型运算以及强制类型转化函数,都还存在 JS 远古传统。
| 1 | 2n == 2; | 
更多内容可以参考 BigInt 提案