好的,所以我知道有些数字不能用二进制表示,就像1/3一样,不能用十进制表示。
那么我怎么来console.log(0.3)它返回0.3 但是当我在console.log(0.1 + 0.2)时,它返回0.30000000000000004
当简单地输出0.3但是当加法发生时没有计算错误(如果它是偶数)怎么样?
答案 0 :(得分:7)
假设我们以十进制表示大约1/3和2/3。
1/3 = 0.333
2/3 = 0.667
我们加1/3 + 1/3:
1/3+1/3 = 0.333 + 0.333 = 0.666
我们没有得到2/3的近似值。将1/3舍入到我们可以用十进制表示的东西时,产生的数字不等于我们舍入2/3时的一半。
同样的事情发生在二进制中。我们将0.1和0.2舍入到我们可以用二进制表示的数字,但是近似值的总和与我们得到的数值略有不同(如果我们接近0.3)。我们得到更高的东西,结果显示为0.30000000000000004
。
答案 1 :(得分:4)
0.1
和0.2
的内部表示中的不准确性足够小,以至于Javascript打印机在打印这些数字时会忽略它们。但是当你将它们加在一起时,不准确性会累积,这足以在打印结果时显示出来。
答案 2 :(得分:2)
Java打印浮点数的方式是您所看到的行为的重要部分:默认情况下,Java不会打印浮点数的确切值。它打印的数字足以精确识别正在打印的double
。
因此,如果您将x
设置为.3
,则x
实际设置为0.299999999999999988897769753748434595763683319091796875。当Java打印出来时,它只打印“.3”,因为将“.3”转换为double
会产生x
的值,0.299999999999999988897769753748434595763683319091796875。
当您使用.1
和.2
时,这些实际上是值0.1000000000000000055511151231257827021181583404541015625和0.200000000000000011102230246251565404236316680908203125。添加它们时(格式为double
),结果为0.3000000000000000444089209850062616169452667236328125。
当您打印此值时,Java会打印“0.30000000000000004”,因为它需要显示所有这些数字,以便生成一个数字,当转换回double
时,将产生0.3000000000000000444089209850062616169452667236328125。
这是the documentation for how double
values are printed。它说:
小数部分必须打印多少位数?必须至少有一个数字来表示小数部分,并且除此之外必须有多个,但只有多少,更多的数字才能唯一地将参数值与类型
double
的相邻值区分开来。
答案 3 :(得分:1)
正如你所说,在基数10中你无法准确描述1/3的分数。同样,在基数2中,您无法准确描述某些其他分数。因此,当计算机增加0.1和0.2时,它实际上增加了0.10000000001和0.20000000003之类的东西。