谁能向我解释为什么 9999999999999999 转换为 10000000000000000?
alert(9999999999999999); //10000000000000000
谁能向我解释为什么 9999999999999999 转换为 10000000000000000?
alert(9999999999999999); //10000000000000000
Javascript 没有整数,只有 64 位浮点数 - 而且您已经用完了浮点精度。
在 Java 中查看类似问题:为什么 Double.parseDouble 将 9999999999999999 变为 10000000000000000?
JavaScript 只有浮点数,没有整数。
摘要:浮点数只包括有限的精度,超过 15 位(左右),你会得到四舍五入。
9999999999999999
在 JavaScript 内部被视为浮点数。它不能在 IEEE 754 双精度中准确表示,因为它需要 54 位精度(位数为 log2(9999999999999999) = 53,150849512...并且由于不存在小数位,因此必须将结果向上取整)而 IEEE 754 仅提供 53 位(1 个隐含位 + 52 个显式存储的尾数位) - 少了一位。因此,数字只是四舍五入。
由于在这种情况下只丢失了一位,因此即使是 54 位数字也可以精确表示,因为它们仍然包含0
在丢失的位中。考虑到 IEEE 754 的默认无偏舍入模式,奇数 54 位数字被舍入到恰好是 53 位偶数的两倍的最接近的值。
问题:有时 JavaScript 计算似乎产生“不准确”的结果,例如 0.362*100 产生 36.199999999999996。我怎样才能避免这种情况?
答:JavaScript 在内部以双精度浮点格式存储所有数字,尾数为 52 位,指数为 11 位(用于存储数值的 IEEE 754 标准)。这种数字的内部表示可能会导致上述意外结果。大多数大于 253 = 9007199254740992 的整数不能以这种格式精确表示。同样,许多小数/分数(例如 0.362)无法准确表示,导致上述示例中的感知“不准确”。为了避免这些“不准确”的结果,您可能希望将结果四舍五入到您使用的数据的精度。
二进制形式的9999999999999999是100011100001101111001001101111110000001111111111111111 ,它有 54 位数字。
下面我们将把这个数字转换为 Javascript IEEE-754,它有 1 位符号,11 位二进制偏移格式的尾数和 52 位数字本身的符号。
在二进制形式中,第一个数字始终为1,因此 Javascript 在保存为 IEEE-754 格式时会省略尾数中数字的第一个数字。因此,我们将有00011100001101111001001101111110000001111111111111111作为尾数,这是 53 位数字,至于数字我们只能保留 52 位数字,我们将数字四舍五入删除最后一位数字000111000011011110010010000000000000000000000000000000000000
二进制形式的最终数字将为 1 0001110000110111100100110111111000001000000000000000 0,十进制形式为 10000000000000000
1 是第一个未写入尾数 52 位的数字,然后是 52 位尾数和一个 0,使其返回 54 位,即 十进制的10000000000000000
除非您阅读这篇漂亮的文章,否则这可能很难理解