The solution to the abnormal result of java type operation
- 2020-05-24 05:37:39
- OfStack
Question:
Operating on two values of type double sometimes results in outlier values. Such as:
System.out.println(19.99+20);
System.out.println(1.0-0.66);
System.out.println(0.033*100);
System.out.println(12.3/100);
Output:
39.989999999999995
0.33999999999999997
3.3000000000000003
0.12300000000000001
Solutions:
The simple floating point types float and double in Java are not capable of performing operations because they are normal most of the time, but occasionally present the problems shown above. The problem is not bug of JAVA, because the computer itself is in base 2, and floating point Numbers are actually only approximations, so when converting from base 2 to 10 floating point Numbers, the accuracy is easily lost, resulting in a drop in precision.
To ensure accuracy, use the BigDecimal class, and instead of directly transferring double to BigDecimal, transfer double to string to BigDecimal. That is, you cannot use the BigDecimal(double val) method and you will find no effect. Use the BigDecimal(String val) method. Specific examples are shown below.
Example of operation for double type 4:
1, add
public static double add(double a1, double b1) {
BigDecimal a2 = new BigDecimal(Double.toString(a1));
BigDecimal b2 = new BigDecimal(Double.toString(b1));
return a2.add(b2).doubleValue();
}
2, by subtracting
public static double sub(double a1, double b1) {
BigDecimal a2 = new BigDecimal(Double.toString(a1));
BigDecimal b2 = new BigDecimal(Double.toString(b1));
return a2.subtract(b2).doubleValue();
}
3, multiply
public static double mul(double a1, double b1) {
BigDecimal a2 = new BigDecimal(Double.toString(a1));
BigDecimal b2 = new BigDecimal(Double.toString(b1));
return a2.multiply(b2).doubleValue();
}
4, deduct
public static double div(double a1, double b1, int scale) {
if (scale < 0) {
throw new IllegalArgumentException("error");
}
BigDecimal a2 = new BigDecimal(Double.toString(a1));
BigDecimal b2 = new BigDecimal(Double.toString(b1));
return a2.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
}
Precision is specified when the scale parameter is not infinite.