将JavaScript二进制字符串转换回原始字符串并不相等

3

我有一个包含64个元素的JavaScript数组,我将其用作位掩码。不幸的是,当进行字符串转换为二进制和再次转换回字符串时,我遇到了问题。尽管这对于其他一些数组有效,但在这里发生了什么?

var a = [1, 1, 1, 1, 1, 1, 1, 1,
         1, 1, 1, 1, 1, 1, 1, 1,
         1, 1, 0, 0, 1, 1, 1, 1,
         1, 1, 0, 0, 1, 1, 1, 1,
         1, 1, 0, 0, 0, 0, 1, 1,
         1, 1, 0, 0, 0, 0, 1, 1,
         1, 1, 1, 1, 1, 1, 1, 1,
         1, 1, 1, 1, 1, 1, 1, 1];

var str1 = a.join('');
  //-> '1111111111111111110011111100111111000011110000111111111111111111'

var str2 = parseInt(str1, 2).toString(2);
  //-> '1111111111111111110011111100111111000011110001000000000000000000'

str1 === str2  //-> false

我希望str2str1是相同的,但事实并非如此。

1
你正在失去精度。请参见https://dev59.com/hnVC5IYBdhLWcg3wZwNT。 - ziesemer
如果您使用更灵活的语言(如Python),您会发现这两个二进制字符串只相差1个值。分别是1844669108998242304018446691089982423039。(正如@zie所说的精度问题) - Brigand
我能说把一个二进制掩码的字符串表示传给parseInt看起来相当愚蠢吗? 如果你必须将其作为字符串表示,为什么不尝试使用类似于 function matchMask(str, pos) { return str.charAt(pos) != '0'; } 这样的方法呢? - Alxandr
1
如果您不在意礼貌,可以说任何您喜欢的话。但是为每个元素调用 matchMask 稍显低效。 - Marcus Booster
1个回答

6
在JavaScript中,Number类型是64位双精度值更多信息,和更多信息)。这里指定了64位,超出了64位双精度值可以准确表示的范围(因为它是一种浮点数类型,所以必须分配一些位来表示精度)。JavaScript没有整数类型(更不用说64位版本了),这就需要完全保真的转换。
我对浮点位表示并不是很了解,但我记得一个64位双精度数可以准确地表示大约53个有效位的整数值,请参见链接获取详细信息。

1
根据这篇回答,它只能精确到53位。 - Brigand
@FakeRainBrigand:谢谢,我已经添加了一个到8.5节的链接。(我已经提到了53位的事情,但我记不清楚它的来源;我在规范之外的某个地方读到了它,谢谢。) - T.J. Crowder

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