JavaScript 的数字很古怪。我意识到加法不是关联的:
(-9999999999999999 + 1) + 1 === -9999999999999999 + (1 + 1) // false!
可交换性呢?是否有 JavaScript 数字a
,b
例如
typeof a === 'number'
typeof b === 'number'
a + b !== b + a
全部评估为true
(除了NaN
)?
JavaScript 的数字很古怪。我意识到加法不是关联的:
(-9999999999999999 + 1) + 1 === -9999999999999999 + (1 + 1) // false!
可交换性呢?是否有 JavaScript 数字a
,b
例如
typeof a === 'number'
typeof b === 'number'
a + b !== b + a
全部评估为true
(除了NaN
)?
如果你仔细看,你会看到1-9999999999999999返回-10000000000000000,这不是这个操作的结果(应该是-9999999999999998)你只是达到了浮点精度的极限。执行此操作时可以看到相同的效果:0.0000000000000001+1 和 0.0000000000000002+1
所以ecmascript 规范,数字应该遵循 64 位格式的 IEEE 754 标准。这对应于 16 位精度。这正是您的数字的大小。
编辑
关于您关于交换性的问题,以下是规范所述:
在其余情况下,既不涉及无穷大,也不涉及零,也不涉及 NaN,并且操作数具有相同的符号或具有不同的大小,使用 IEEE 754 舍入到最近计算和舍入到最接近的可表示值模式。如果幅度太大而无法表示,则操作溢出,结果是适当符号的无穷大。ECMAScript 语言需要支持 IEEE 754 定义的逐渐下溢。
所以它应该始终是可交换的,因为总和是计算然后四舍五入的。任何其他行为都将是您浏览器的错误。
编辑 2
更清楚的是,规范明确指出(第 11.6.3 节):
加法是一种交换运算,但并不总是结合的。