为什么解析大量字符串形式的数字会得到一个更大的数字?

3
请参见代码片段:

var num = "9223372036854775808";
document.write(num);
document.write("<br>");
document.write(parseInt(num, 10));

运行代码片段后,第一次写入会产生以下结果:
9223372036854775808

第三个写入操作产生了以下输出:
9223372036854776000

但是,我只将字符串形式的数字解析为数字。为什么它会给出一个更大的数字?
我认为这可能与存储容量限制有关,但如果它不能存储较小的数字,为什么会产生更大的数字?
我阅读了这个问题:为什么将一个非常大的数字解析为整数会返回1parseInt文档,但它们并没有帮助太多。
所以,为什么解析字符串形式的大数字会返回一个更大的数字?
1个回答

1

第一个结果没问题,因为它被视为字符串。

在第二个结果中,它超过了int的值,即+/- 9007199254740992,也就是说,parseint可以解析的最大值是9007199254740992,而你的值9223372036854775808大于最大值。它会给出一些垃圾值。

正如blunderboy正确地评论的那样,原因可能是这个:

Javascript中的数字是64位“double”精度,遵循IEE754浮点数。因此,可以准确表示的最大正整数是2^53,其余剩余位用于指数。

如果您查看ECMA规范,就会发现这一点已经被解释了。


...因此,它以浮点数的形式存储,这意味着它具有有限的精度而不是尺寸,所以可能会稍微多一些或少一些。请注意,parseFloat(num)会给出完全相同的结果。还请注意,结果具有16个有效数字,这符合JS浮点数值的预期。 - Amadan
2
@Rahul Tripathi 这不是一些垃圾值。parseInt 绝对使用了一些四舍五入机制...例如,查看 parseInt(9223372036854775108) 的结果为 9223372036854775000 - Sachin Jain
@blunderboy:已更新,加入了最可能导致精度问题的原因。 - Rahul Tripathi
请查看以下链接:link - Nina Scholz
只是澄清一下:2^53不是64位浮点数可以准确存储的最大整数(OP的例子9223372036854776000是另一个可以准确表示为此类数字的例子),但是2^53是边缘情况,之后只有一些整数可以被表示为这样(在2^53之前,每个整数都可以这样表示)。这导致了一些奇怪的情况,例如“9223372036854775200”将解析为“9223372036854775000”,而“9223372036854775300”将解析为“9223372036854776000”(为什么不解析为更接近的值9223372036854775000呢?) - Nils O
2
我刚刚进行了另一个测试,输入数字“714341252076979033”,输出结果为“714341252076979100”。https://jsfiddle.net/0hdoatkj/。因此,我认为当将714341252076979033(十六进制为0x9e9d9958274c359)赋值给最近可表示的双精度值时,它被赋值为714341252076979072(0x9e9d9958274c380)。当我们尝试打印该值时,它被四舍五入到15个有效十进制数字,得到714341252076979100。 - Rahul Tripathi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接