为什么不对双精度值进行操作会给出预期的结果?

时间:2010-10-08 17:32:17

标签: floating-point double floating-accuracy ieee-754

    System.out.println(2.14656);

2.14656

    System.out.println(2.14656%2);

0.14656000000000002

WTF?

3 个答案:

答案 0 :(得分:13)

确实给出了预期的结果。你的期望是错误的。

当你输入双精度文字2.14656时,实际得到的是最接近的双精度值,即:

2.14656000000000002359001882723532617092132568359375

println碰巧将它打印出来(到17位有效数字),所以你会看到你期望的好价值。

模数运算(精确)后,值为:

0.14656000000000002359001882723532617092132568359375

同样,它在打印时会四舍五入,但由于前导数字较少,因此圆点距离右侧一位数,因此您会看到尾随2

答案 1 :(得分:3)

base-2系统用于存储任意精度的基数为10的数据。

当使用整数二进制时,“圆形”数字是2,4,8,16,32,64等。你会注意到这些数字都不是10,100,1000,10000或任何会是被认为是基数为10的“圆”数。

为CPU内的快速操作构建了浮点数和双精度值。即使您将1.42E-13除以2.11E47,也可以快速完成多个数字之间的数学运算。它们的构造不是为了在10号基地提供“圆形”数字。这是该决定的副作用。

使用浮点数时,您必须接受这种情况。它不是100%精确,但它是准确的。所以你永远不应该使用需要100%精度的浮点变量。在需要执行此操作的位置,找到将其存储在int值中的方法。这也是一个好主意,你可以使用一个浮点数,将输出四舍五入到一些小数位,以避免像你那样偶尔显示。

例如,我在金融行业工作,我们将市场价格表示为多个刻度而不是实际价格。当我们需要显示价格时,我们将此值乘以刻度尺寸,1 / 100,1 / 32或1/20等,然后舍入到适当的小数位数。滴答数,分子大小的分子和分母都在我们的数据库中存储为整数。除了移动平均值之类的计算值之外,我们实际上并不存储浮点值。

答案 2 :(得分:0)