舍入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