为什么浮点数有舍入误差?

时间:2014-10-17 03:44:39

标签: java floating-point double

我一直在努力理解Java中带有浮点的舍入错误的概念。虽然我知道双倍不应该用于财务计算,但我不明白为什么“''变量不会出现0.0。如何才能打印出第一张println?

package zetcom;

public class floatingComparison {
public static void main(String[] args) {
    double r = Math.sqrt(2);
    double d = r * r - 2;

    if (d == 0)
    {
        System.out.println("sqrt(2) squared minus 2 is 0");
    }
    else
    {
        System.out.println("sqrt(2) squared minus 2 is " + d);
    }
  }
}

任何解释都将不胜感激。

2 个答案:

答案 0 :(得分:5)

简答:

2的平方根需要无限多个数字 - 即无限精度。 double具有52位精度。这是很多,但它远远不够无限。

如果你试图用两位数(0.33)代表1/3,你不会对舍入错误感到惊讶,对吧?你将它乘以3并且得到0.99而不是1.0的答案并不是完全惊讶。这完全是一回事。

进一步挖掘......

更直观的是,可以用基数10中的无限位数表示的数字可能能够用基数2中的有限位数表示(这是doublefloat使用的内容。例如,1/10在基数10中为0.1,但在基数为2时为0.0001100110011 ...因此,当您将其存储为double时,它也会被舍入,原因与上述相同:存储1/10 in a二进制中的有限位数与十进制中有限位数的1/3存储一样不可能。

深入挖掘......

最后,你也可以反过来看看它。虽然1/3不可能以有限精度以十进制形式写入,但它在基数3中仅为0.1。

答案 1 :(得分:3)

几乎所有语言中的浮点数总是近似(条形幂2),因为它们无法以二进制形式准确表示。这是由于计算机如何处理信息:以位为单位。

例如,你如何用二进制代表.3?如果您尝试使用浮点数实现最大精度,则总是会出现舍入错误,因为它们必须以二进制表示。