任何人都可以向我解释为什么9999999999999999被转换为10000000000000000?
alert(9999999999999999); //10000000000000000
Run Code Online (Sandbox Code Playgroud)
Kos*_*Kos 39
Javascript没有整数,只有64位浮点数 - 而且你已经没有浮点精度了.
在Java中看到类似的问题:为什么Double.parseDouble使9999999999999999变为10000000000000000?
Hri*_*iev 10
9999999999999999在JavaScript内部处理为浮点数.它无法以IEEE 754双精度精确表示,因为它需要54位精度(位数为log2(9999999999999999)= 53,150849512 ...并且由于小数位不存在,因此必须将结果调高)而IEEE 754仅提供53位(1个隐含位+ 52个明确存储的尾数位) - 少一位.因此,这个数字很简单.
由于在这种情况下只丢失一位,即使54位数字也可以准确表示,因为它们仍包含0在位中,这会丢失.在给定IEEE 754的默认无偏舍入模式的情况下,奇数54位数被四舍五入到最接近的值,恰好是加倍的偶数53位数.
小智 5
\n\n\n为什么 9999999999999999 转换为 10000000000000000 ?
\n
JavaScript 中的所有数字都以 64 位格式 IEEE-754 存储,也称为 \xe2\x80\x9c 双精度\xe2\x80\x9d,因此正好有 64 位来存储数字:其中52 位用于存储位,其中 11 位存储小数点位置(整数为零),1 位用于符号。
\n\n如果数字太大,它会溢出 64 位存储,可能导致 \nan 无穷大:
\n\nalert( 1e500 ); \n// Result => Infinity\n// "e" multiplies the number by 1 with the given zeroes count.\nRun Code Online (Sandbox Code Playgroud)\n\n如果我们检查 0.1 和 0.2 之和是否为 0.3,我们会得到 false。
\n\nalert( 0.1 + 0.2 == 0.3 )\nRun Code Online (Sandbox Code Playgroud)\n\n奇怪的!如果不是0.3那又是什么呢?发生这种情况是因为,数字以二进制形式(一系列 1 和 0)存储在内存中。但像 0.1、0.2 这样的分数在十进制中看起来很简单,实际上在二进制形式中是无止尽的分数。
\n\n换句话说,0.1 是多少?它是一除以十1/10,十分之一。在十进制数字系统中,这些数字很容易表示。将其与三分之一进行比较:1/3。它变成无限分数 0.33333(3)。
\n\n\xe2\x80\x99s 无法使用二进制系统精确存储 0.1 或精确 0.2,就像无法将三分之一存储为十进制分数一样。
\n\n数字格式 IEEE-754 通过四舍五入到最接近的可能数字来解决这个问题。这些舍入规则通常不允许我们看到 \xe2\x80\x99t 精度损失 \xe2\x80\x9d,因此数字显示为 0.3。但要注意,损失仍然存在。
\n\n如你所见 :
\n\nalert( 9999999999999999 ); // shows 10000000000000000\nRun Code Online (Sandbox Code Playgroud)\n\n这也存在同样的问题:精度损失。数字有64 位,其中 52 位可用于存储数字,但这\xe2\x80\x99s 还不够。所以最低有效数字消失了。
\n\n\n\n\n9999999999999999 到 10000000000000000 背后真正发生的是:
\n
JavaScript 不会在此类事件中触发错误。它会尽力将数字调整为所需的格式,但不幸的是,这种格式不够大。
\n\n参考: https: //javascript.info/number
\n\n您也可以参考这个SO Question,它包含有关JavaScript Numbers的非常详细的信息。
\n| 归档时间: |
|
| 查看次数: |
5699 次 |
| 最近记录: |