为什么这些二进制表示可以得出相同的数字?

3
根据文档,我们可以使用parseInt(string, base)将一个数字的二进制表示转换为该数字本身。
例如,
var number = parseInt("10100", 2);
// number is 20

然而,请看下一个例子:
var number = parseInt("1000110011000011101000010100000110011110010111111100011010000", 2);
// number is 1267891011121314000

var number = parseInt("1000110011000011101000010100000110011110010111111100100000000", 2);
// number is 1267891011121314000

我该如何做到这一点?

请注意,二进制数几乎相同,除了最后的9位。


1
关键词:ieee754,浮点精度。 - zerkms
3个回答

2

1267891011121314000远超过Number.MAX_SAFE_INTEGER(9007199254740991),它无法在内存中安全地表示。

看看这个经典的例子:

1267891011121314000 == 1267891011121314001  // true

我会从另一侧开始:1000110011000011101000010100000110011110010111111100011010000 长度超过了52位。 - zerkms
@zerkms,要了解细节,我们需要查看parseInt的规范。 - Derek 朕會功夫
1
这不是关于parseInt的细节,而是关于IEEE754的。 - zerkms
标准规定ES数字为IEEE754双精度数字(我们不应关心其内部实现方式,外部必须遵循所述标准语义)。“事实上,parseInt专门将值映射到[-2 ^ 31,2 ^ 31-1]”---这肯定是不正确的。 - zerkms

1
因为这是一个61位的数字,而Javascript存储的最高精度类型是64位浮点数(使用IEEE-754双精度浮点数)。
64位浮点数没有61位整数精度,因为使用的64位被分成小数和指数。从位布局的图表中可以看出,只有52位可用于尾数(或小数部分),在存储整数时会使用它们。
许多bignum库存在于解决这种问题,因为它是科学应用中非常普遍的问题。它们不太快,但允许更高的精度。从Github结果中,bignumber.js可能是您需要支持这些值的东西。

首先,第一句话必须重新表述。我错误地使用了“不正确”的词,但它非常具有误导性。parseInt产生的是整数,与其说是64位整体,更多的是52位的小数部分。 - zerkms
@zerkms,这就是我想表达的意思。重新表述得更清楚了。 - ssube
如果你在某处提到了神奇的“52位”,那么我会成为今天最快乐的猫 :-)(无论如何都会点赞)。 - zerkms

0

JavaScript 中的数字有上限和下限。JavaScript 使用 64 位浮点数表示数字。IEEE754

如果需要更大的支持,请在 JavaScript 中查看 BigDecimal 实现。


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