所以我试图理解 JavaScript 在处理大数时的行为。考虑以下(在 Firefox 和 Chrome 中测试):
console.log(9007199254740993) // 9007199254740992
console.log(9007199254740994) // 9007199254740994
console.log(9007199254740995) // 9007199254740996
console.log(9007199254740996) // 9007199254740996
console.log(9007199254740997) // 9007199254740996
console.log(9007199254740998) // 9007199254740998
console.log(9007199254740999) // 9007199254741000
现在,我知道为什么它会输出“错误”的数字——它试图将它们转换为浮点表示,并四舍五入到最接近的可能浮点值——但我不完全确定它为什么选择这些特定的数字。我的猜测是它试图四舍五入到最接近的“偶数”数,因为 9007199254740996 可以被 4 整除而 9007199254740994 不是,它认为 9007199254740996 更“偶数”。
最佳答案
正如 Mark Dickinson 在对该问题的评论中指出的那样,ECMA-262 ECMAScript 语言规范要求使用 IEEE 754 64 位二进制浮点数来表示 Number Type 。相关的舍入规则是“选择该集合中值与 x 最接近的成员。如果集合中的两个值相等,则选择具有偶数有效数的那个......”。
这些规则是通用的,适用于算术的舍入结果以及文字值。
以下是问题相关范围内的所有数字,这些数字可以在 IEEE 754 64 位二进制浮点中精确表示。每个都显示为其十进制值,也显示为其位模式的十六进制表示。具有偶数有效数的数字在其位模式中具有偶数最右边的十六进制数字。
9007199254740992 bit pattern 0x4340000000000000
9007199254740994 bit pattern 0x4340000000000001
9007199254740996 bit pattern 0x4340000000000002
9007199254740998 bit pattern 0x4340000000000003
9007199254741000 bit pattern 0x4340000000000004
每个偶数输入都是这些数字之一,并四舍五入到该数字。每个奇数输入正好位于其中两个输入的中间,并四舍五入到具有偶数有效数的那个。这导致将奇数输入四舍五入为 9007199254740992、9007199254740996 和 9007199254741000。