lxq.link
postscategoriestoolsabout

JavaScript 最大安全值

JS 最大安全值可以通过 Number.MAX_SAFE_INTEGER 来查看

chrome_qW08jScsGy.png

chrome_JJohOsJHJp.png

这个数值等于 2 ** 53 - 1

chrome_duB6PyODkK.png

chrome_PKFRboqXx5.png

为什么叫最大安全值呢,因为超过这个数值之后就会变得不安全

。。

比如

chrome_r9HvkXq30T.png

再比如

chrome_RxeSZEnU3p.png


出现这样问题是因为 JS 按照IEEE 754-2008标准的定义,所有数字都以双精度64位浮点格式表示。

这也是为什么 JS 中 0.1 + 0.2 !== 0.3 (而是0.30000000000000004)


双精度64位浮点格式会带来精度问题,在项目中往往会带来意向不到的Bug。在计算密集场景,需要使用更严谨的 Math.js 来作为补充。

直接看一下官网实例

console.log('round-off errors with numbers')
print(math.add(0.1, 0.2)) // number, 0.30000000000000004
print(math.divide(0.3, 0.2)) // number, 1.4999999999999998
console.log()

console.log('no round-off errors with BigNumbers')
print(math.add(math.bignumber(0.1), math.bignumber(0.2))) // BigNumber, 0.3
print(math.divide(math.bignumber(0.3), math.bignumber(0.2))) // BigNumber, 1.5
console.log()

console.log('create BigNumbers from strings when exceeding the range of a number')
print(math.bignumber(1.2e+500)) // BigNumber, Infinity      WRONG
print(math.bignumber('1.2e+500')) // BigNumber, 1.2e+500
console.log()

JS 在新的提案中增加了除了Number外的第二种数值类型 BigInt

浏览器和 Node.js 支持版本如下

image.png

BigInt 可以表达的整数范围更广泛,因此使用 BigInt 也可以解决上面说的最大安全值问题

chrome_z0peVBF5BV.png

chrome_0WehqqiQmD.png

2021-07-23