任何人都可以向我解释为什么9999999999999999转换为10000000000000000?
alert(9999999999999999); //10000000000000000
答案 0 :(得分:37)
Javascript没有整数,只有64位浮点数 - 而且你已经没有浮点精度了。
在Java中查看类似问题:why is the Double.parseDouble making 9999999999999999 to 10000000000000000?
答案 1 :(得分:20)
JavaScript只有浮点数,没有整数。
阅读What Every Computer Scientist Should Know About Floating-Point Arithmetic。
总结:浮点数只包含有限的精度,超过15位数(或左右),你将得到四舍五入。
答案 2 :(得分:9)
9999999999999999
在JavaScript内部被视为浮点数。它无法以IEEE 754双精度精确表示,因为它需要54位精度(位数为log2(9999999999999999)= 53,150849512 ...并且由于小数位不存在,因此必须将结果调高)而IEEE 754仅提供53位(1个隐含位+ 52个明确存储的尾数位) - 少一位。因此,这个数字很简单。
由于在这种情况下只丢失了一位,即使54位数字也可以准确表示,因为它们在位中包含0
,这会丢失。考虑到IEEE 754的默认无偏舍入模式,奇数54位数被舍入到最接近的值,恰好是加倍的偶数53位数。
答案 3 :(得分:3)
问题:有时JavaScript计算似乎会产生“不准确”的结果,例如: 0.362 * 100产量36.199999999999996。我怎么能避免这个?
答案:内部JavaScript以双精度浮点格式存储所有数字,具有52位尾数和11位指数(用于存储数值的IEEE 754标准)。数字的内部表示可能会导致意外的结果,如上所述。大多数253以上的整数= 9007199254740992无法以此格式准确表示。同样地,许多小数/分数(例如0.362)不能精确表示,导致上述示例中的“不准确”。为避免这些“不准确”的结果,您可能希望将结果四舍五入到您使用的数据的精度。
答案 4 :(得分:2)
为什么9999999999999999转换为10000000000000000?
JavaScript中的所有数字都以64位格式IEEE-754 存储,也称为“双精度”,因此正好有64位存储数字:其中52位用于存储数字,其中11个存储小数点的位置(对于整数,它们为零),和1位用于符号。
如果数字太大,它会溢出64位存储,可能会给出 无限:
alert( 1e500 );
// Result => Infinity
// "e" multiplies the number by 1 with the given zeroes count.
如果我们检查0.1和0.2之和是否为0.3,我们就会得到假。
alert( 0.1 + 0.2 == 0.3 )
<强>奇怪!那么如果不是0.3会是什么?这是因为,一个数字以二进制形式存储在内存中,一个1和0的序列。但在十进制数字系统中,分数(如0.1,0.2看起来简单)实际上是二进制形式的无限分数。
换句话说,什么是0.1?它是一个除以十分之一十分之十,十分之一。在十进制数字系统中,这样的数字很容易重现。比较三分之一:1/3。它变成了无穷无尽的分数0.33333(3)。
使用二进制系统无法准确存储0.1或0.2,就像没有办法将三分之一存储为小数部分一样。
数字格式IEEE-754通过舍入到最接近的可能数字来解决此问题。这些舍入规则通常不允许我们看到“微小的精度损失” ,所以数字显示为0.3。但要注意,损失仍然存在。
如您所见:
alert( 9999999999999999 ); // shows 10000000000000000
这会遇到同样的问题:精度下降。该数字有 64位,其中52位可用于存储数字,但那还不够。所以最不重要的数字会消失。
9999999999999999背后真正发生的事情是10000000000000000:
JavaScript不会在此类事件中触发错误。它尽力使数字符合所需的格式,但不幸的是,这种格式还不够大。
参考: https://javascript.info/number
您还可以参考此 SO Question ,其中包含有关JavaScript数字的详细信息。