Java的Double类型乘法精确度

在写Hive的UDF时候,发现了一个double类型的精确度问题。

1
2
3
4
5
6
7
8
9
10
11
12
public class tee {
public static void main(String[] args) {
double a = 1.1;
double b = 1.2;
double c = 1.3;
double d;

d = a * b * c;

System.out.println(d);
}
}
1
2
/Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home/bin/java ...
1.7160000000000002

而实际上1.1 x 1.2 x 1.3 = 1.716

这个结果并不符合预期,原因是由于浮点数是无法在计算机中准确表示的,例如0.1在计算机中只是表示成了一个近似值,因此,浮点数的运算结果具有不可预知性。

解决方案:

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* Provide precise multiplication operations.
*
* @param v1 Multiplicand
* @param v2 multiplier
* @return Product of two parameters
* @author pama
*/
public static double mul(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.multiply(b2).doubleValue();
}

写一个乘法的方法,需要做乘法时候,调用这个方法即可。