4
    System.out.println(2.14656);

2.14656

    System.out.println(2.14656%2);

0.14656000000000002

怎么回事?

4

3 回答 3

13

确实给出了预期的结果。你的期望是不正确的。

当您键入双精度字面2.14656量时,您实际得到的是最接近的双精度值,即:

2.14656000000000002359001882723532617092132568359375

当它打印出来(到 17 位有效数字)时,println碰巧将它四舍五入,所以你会看到你期望的不错的值。

模运算后(准确),值为:

0.14656000000000002359001882723532617092132568359375

再一次,它在打印时是四舍五入的,但是因为前导数字少了一位,所以舍入点向右更远一位数字,所以你会看到尾随2.

于 2010-10-08T18:13:22.387 回答
4

以 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 等,然后四舍五入到适当的小数位数。刻度的数量,刻度大小的分子和分母,都以整数形式存储在我们的数据库中。除了移动平均线等计算值外,我们实际上不存储任何浮点值。

于 2010-10-08T17:53:43.083 回答
0

http://en.wikipedia.org/wiki/Round-off_error#Representation_error

于 2010-10-08T17:35:23.977 回答