📜  舍入Java中的错误

📅  最后修改于: 2022-05-13 01:55:34.530000             🧑  作者: Mango

舍入Java中的错误

将许多无限实数压缩为有限位数需要近似表示。大多数程序最多存储 32 位或 64 位整数计算的结果。给定任何固定位数,大多数实数计算将产生无法使用那么多位精确表示的数量。因此,浮点计算的结果必须经常四舍五入以适应其有限表示。这种舍入误差是浮点计算的一个特征。

因此,在处理浮点数的计算时(特别是如果计算是以金钱为单位的),我们需要注意编程语言中的舍入错误。
让我们看一个例子:

public class Main {
    public static void main(String[] args)
    {
        double a = 0.7;
        double b = 0.9;
        double x = a + 0.1;
        double y = b - 0.1;
  
        System.out.println("x = " + x);
        System.out.println("y = " + y );
        System.out.println(x == y);
    }
}

输出:

x = 0.7999999999999999
y = 0.8
false

在这里,答案不是我们预期的原因,因为Java编译器完成了四舍五入。


舍入错误的原因

float 和 double 数据类型实现 IEEE 浮点 754 规范。这意味着数字以如下形式表示:

SIGN FRACTION * 2 ^ EXP 

0.15625 = (0.00101) 2 ,浮点格式表示为:1.01 * 2^-3
并非所有分数都可以精确地表示为 2 的幂的分数。举个简单的例子,0.1 = (0.000110011001100110011001100110011001100110011001100110011001…) 2因此不能存储在浮点变量中。

另一个例子:

public class Main {
    public static void main(String[] args)
    {
        double a = 0.7;
        double b = 0.9;
        double x = a + 0.1;
        double y = b - 0.1;
  
        System.out.println("x = " + x);
        System.out.println("y = " + y );
        System.out.println(x == y);
    }
}

输出:

x = 0.7999999999999999
y = 0.8
false

另一个例子:

public class Main {
    public static void main(String args[])
    {
        double a = 1.0;
        double b = 0.10;
        double x = 9 * b;
        a = a - (x);
  
        // Value of a is expected as 0.1
        System.out.println("a = " + a);
    }
}

输出:

a = 0.09999999999999998

如何纠正舍入错误?

  • 对结果进行舍入: Round()函数可用于最小化浮点算术存储不准确性的任何影响。用户可以将数字四舍五入到计算所需的小数位数。例如,在使用货币时,您可能会四舍五入到小数点后 2 位。
  • 算法和函数:使用数值稳定的算法或设计自己的函数来处理这种情况。您可以截断/舍入不确定的数字(您也可以计算运算的数字精度)
  • BigDecimal 类:您可以使用Java.math.BigDecimal 类,该类旨在为我们提供准确性,尤其是在大分数的情况下。

    以下程序显示了如何消除错误:

    public class Main {
        public static void main(String args[])
        {
            double a = 1.0;
            double b = 0.10;
            double x = 9 * b;
            a = a - (x);
      
        /* We use Math.round() function to round the answer to
             closest long, then we multiply and divide by 1.0 to
             to set the decimal places to 1 place (this can be done
             according to the requirements.*/
            System.out.println("a = " + Math.round(a*1.0)/1.0);
        }
    }
    

    输出:

    0.1