JavaScript:为什么58*0.1=5.8000000000001(而不是5.8)

JavaScript:为什么58*0.1=5.8000000000001(而不是5.8),javascript,decimal,Javascript,Decimal,可能重复: …对此我能做些什么?在计算之后,我希望得到结果的字符串表示形式。正因为如此,零(加上一)正在消除干扰。“toFixed()”并不是一个完美的解决方案,因为我想得到潜在结果的所有(正确)小数,而我以前不知道结果(以及小数的数量)。因此,上面显示的计算只是一个例子。简单的回答是:计算机用二进制表示数字,因此它们不能将所有以10为基数的分数完美地表示为JavaScript数字 (稍微)长一点的答案是,正如维基百科所描述的,因为JavaScript数字是64位浮点(相当于Java、C#等中

可能重复:


…对此我能做些什么?在计算之后,我希望得到结果的字符串表示形式。正因为如此,零(加上一)正在消除干扰。“toFixed()”并不是一个完美的解决方案,因为我想得到潜在结果的所有(正确)小数,而我以前不知道结果(以及小数的数量)。因此,上面显示的计算只是一个例子。

简单的回答是:计算机用二进制表示数字,因此它们不能将所有以10为基数的分数完美地表示为JavaScript数字

(稍微)长一点的答案是,正如维基百科所描述的,因为JavaScript数字是64位浮点(相当于Java、C#等中的
double
类型),所以有效位的数量有限。因此,该基数-2的精度受到限制

作为类比,考虑表示基10中的分数1/3。假设你只有这么多的数字可以使用。这意味着您永远无法在10进制中精确表示1/3,因为1/3需要无穷多的数字才能在10进制中表示。类似地,您永远无法在有限的位数中完美地表示1/10,因为1/10需要无限的位数才能准确地表示。你在这里看到的是一个分数(58/10),计算机无法在有限的位数内精确表示,因此计算机正在尽可能接近它

将无限多个实数压缩成有限位数需要近似表示。尽管有无限多个整数,但在大多数程序中,整数计算的结果可以存储在32位中。相反,给定任何固定的位数,大多数实数计算将产生无法用那么多位数精确表示的量。因此,浮点计算的结果必须经常四舍五入,以适应其有限表示形式。这种舍入误差是浮点计算的特征


上面来自

(加法和乘法基本上与错误相同)参见“因此它们不能完美地表示所有以10为基数的分数”——但计算机可以完美地表示以10为基数的十进制数,如5.8。只是JavaScript使用的数字实现不一定如此,所以实际上5.7+0.1将返回5.8,但5.8*0.1返回5.8000000000001。更一般地说,通过一个适当的数字实现,计算机可以完美地表示任何非重复的10进制十进制数,最高可达实现设置的任意有效数字数。更新做得不错,但分数58/10或5.8仍然可以用JavaScript精确表示:58/10返回5.8。与58*0.1相比,58*0.1返回5.8000000000001。