先看代码
System.out.println(0.2 + 0.1);
System.out.println(0.3 - 0.1);
System.out.println(0.2 * 0.1);
System.out.println(0.3 / 0.1);
输出:
0.30000000000000004
0.19999999999999998
0.020000000000000004
2.9999999999999996
上面展示的代码,原因在于我们的计算机是二进制的,浮点数没有办法是用二进制进行精确表示,所以在计算的时候有一些数在计算的时候就出现了上面的误差。
在计算过程中存在丢失精度的问题,在开发过程中特别是对象是金融行业的时候,这些存在的精度确实是非常严重的,这个时候,BigDecimal就发现了。Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算。双精度浮点型变量double可以处理16位有效数。在实际应用中,需要对更大或者更小的数进行运算和处理。float和double只能用来做科学计算或者是工程计算,在商业计算中要用java.math.BigDecimal。不过BigDecimal所创建的是对象,我们不能使用传统的+、-、*、/等算术运算符直接对其对象进行数学运算,而必须调用其相对应的方法。方法中的参数也必须是BigDecimal的对象。构造器是类的特殊方法,专门用来创建对象,特别是带有参数的对象。
构造方法
BigDecimal有很多个构造方法,这里举几个常用的。
BigDecimal(int) 将int类型装换成BigDecimal对象
BigDecimal(String) 将String类型装换成BigDecimal对象
BigDecimal intBigDecimal = new BigDecimal(1111111111);
System.out.println("intBigDecimal "+intBigDecimal);
BigDecimal strBigDecimal = new BigDecimal("11111111111111111111111");
System.out.println("strBigDecimal: "+strBigDecimal);
输出:
intBigDecimal 1111111111
strBigDecimal: 11111111111111111111111
BigDecimal还可以将double、long、BigInteger转成BigDecimal对象,不过需要注意的是不推荐使用BigDecimal去转换double类型数据
BigDecimal doubleBigDecimal = new BigDecimal(1.33333);
System.out.println("doubleBigDecimal "+doubleBigDecimal);
输出:
doubleBigDecimal 1.3333299999999999041477849459624849259853363037109375
JDK提供的解决方法是使用字符串的形式转换来解决此类精度丢失的问题
BigDecimal temp = new BigDecimal("1.33333");
System.out.println("temp "+temp);
输出:
temp 1.33333
所以通常建议优先使用String的构造方法。
BigDecimal 的运算方式
首先,需要确定的事,BigDecimal不支持 + - * / 这类的运算 它有自己的运算方法
BigDecimal add(BigDecimal augend) 加法运算
BigDecimal subtract(BigDecimal subtrahend) 减法运算
BigDecimal multiply(BigDecimal multiplicand) 乘法运算
BigDecimal divide(BigDecimal divisor) 除法运算
例子:
BigDecimal num1 = new BigDecimal("1.33333");
BigDecimal num2 = new BigDecimal("2.66666");
System.out.println("加:add "+num1.add(num2));
System.out.println("减:subtract "+num1.subtract(num2));
System.out.println("乘:multiply "+num1.multiply(num2));
// num1 除以 num2
System.out.println("除:divide "+num1.divide(num2));
输出:
加:add 3.99999
减:subtract -1.33333
乘:multiply 3.5555377778
除:divide 0.5
需要注意的:加减乘除其实最终都返回的是一个新的BigDecimal对象,因为BigInteger与BigDecimal都是不可变的(immutable)的,在进行每一步运算时,都会产生一个新的对象
BigDecimal temp = null;
BigDecimal num3 = new BigDecimal("1.33333");
BigDecimal num4 = new BigDecimal("2.66666");
temp = num3.add(num4);
System.out.println("num3: " + num3);
System.out.println("temp: " + temp);
输出:
num3: 1.33333
temp: 3.99999