Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/417.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
javascript计算错误?_Javascript - Fatal编程技术网

javascript计算错误?

javascript计算错误?,javascript,Javascript,让我们看看这个例子 <html> <body onload="alert((0.1234*300));alert((0.00005*300))"/> </html> 为什么结果不是37.02和0.015,而是37.01999999996和0.015000000000000001 Ps:0.00005*300出错,而0.0005*30和0.005*3正常。JavaScript中的所有数字都以二进制形式表示为,其精度约为14或15位有效数字。因为它们是,所

让我们看看这个例子

<html>
 <body onload="alert((0.1234*300));alert((0.00005*300))"/>
</html>

为什么结果不是37.02和0.015,而是37.01999999996和0.015000000000000001


Ps:0.00005*300出错,而0.0005*30和0.005*3正常。

JavaScript中的所有数字都以二进制形式表示为,其精度约为14或15位有效数字。因为它们是,所以它们并不总是精确地表示实数():

您还将有兴趣查看以下帖子:


当您显示一个
数字时,需要仔细阅读,然后使用其
toString(基数)
函数首先将其转换为
字符串。此函数将数字四舍五入为预定义的位数。因此,您可能希望使用
来表示精度(精度)
来表示固定(数字)
来表示分数(分形数字)
。所有这些函数都将
数字
转换为
字符串
,但与
toString
不同的是,您可以使用参数指定位数

在这里处理有理数时,舍入是必要的,因为内部表示是二进制的,外部表示(作为
字符串
)是十进制的

0.1234是一个有理数。因为它是一个小数点(1234/10000),所以很容易用十进制来写。但在二进制系统中,表示是无限长的。它从0.000开始,然后以500位的重复数无休止地继续

为了能够存储这个数字,它从四舍五入开始

1.1111100101110010010001110100010100111000111011110011010011010110101.. * 2^-4

哪一个是最近的IEEE754双精度

差值约为4.1966*10^-18,因此0.1234实际上是0.1233999999995803

如果您尝试使用JavaScript显示此数字,它将被转换为字符串。在此过程中,它被四舍五入到0.123400000。。并截断为0.1234。所以在表面上它看起来仍然像0.1234,即使它稍微小一点

当该数字乘以300时,结果为37.01999999998741。。在二进制中具有有限表示形式:

1.00101000001010001111010111000010100011110101110000100110001 * 2^5
但这一数字也必须四舍五入,以符合双精度:

1.0010100000101000111101011100001010001111010111000010 * 2^5
这实际上是37.019999996021。。但再次将其转换为字符串,使其四舍五入为37.01999999996

如果只看0.1234和0.1234*300这两个数字,您会注意到这两个数字都四舍五入到17位:

12339999999999999580..
37019999999999996021..

您想分享结果吗?刚刚编辑了结果附件调整仅供参考,IEEE双精度数学精度故障的海报子项是
0.1+0.2
。试试看*唉*有时我认为,没有任何真正进步的唯一原因是,老年人和有经验的人都会死去,而年轻人则必须一次又一次地接受同样的教育-PYep,但我想弄清楚的是什么时候会发生这种情况,或者我应该在任何地方使用round()吗?因为只有0.00005*300出错,而0.0005*30正常,所以0.005*3正常。在计算过程中,大部分时间必须四舍五入才能得到表示。如果我可以问的话,你真的需要这么高的精度吗?你有两个选择。。我建议你要么像你自己建议的那样进行
Math.round
,要么你可以将它乘以100、1000,等等——这是你需要的精度。以数百或数千为单位进行计算,然后将其除以您之前使用的数字。很好且透彻的解释。我只是希望这一点能被理解。
1.0010100000101000111101011100001010001111010111000010 * 2^5
12339999999999999580..
37019999999999996021..