BigDecimal
1.BigDecimal 四则运算
先介绍下BigDecimal: 属于 java.math.BigDecimal;
在我们写代码过程中有时会遇到较大数字之间的计算问题,比如金额的计算,这个时候使用浮点类型进行计算可能就不那么准确了,会损失一定的精准度。
如果要用BigDecimal 进行数学运算,不能使用+ , - ,* , /等传统运算符,而要调用其对应的方法;
1.1BigDecimal 初始化
// 第一种,value 数字(浮点(float double)(不推荐,因为值不精准,如下图所示))
BigDecimal num1 = new BigDecimal(5);
BigDecimal num2 = new BigDecimal(0.05);
BigDecimal num3 = new BigDecimal(-5);// 第二种,字符串表示(推荐使用)
BigDecimal num11 = new BigDecimal("5");
BigDecimal num12 = new BigDecimal("0.05");
BigDecimal num13 = new BigDecimal("-5");// 第三种,特殊的值(0、1、10) 和普通的数据类型赋值不同,BigDecimal 需要创建对象,特殊值虽然不需要我们创建,但是在底层也是new 了对象的.
BigDecimal num21 = BigDecimal.ZERO;//0
BigDecimal num22 = BigDecimal.ONE;//1
BigDecimal num23 = BigDecimal.TEN;//10
1.2四则运算
就是对BigDecimal 的方法调用:
加法: **add()**函数
减法: **subtract()**函数
乘法: **multiply()**函数
除法: **divide()**函数
绝对值: **abs()**函数
public class BigDecimalTest {public static void main(String[] args) {BigDecimal num1 = new BigDecimal(5);BigDecimal num2 = new BigDecimal(0.05);BigDecimal num3 = new BigDecimal(-5);BigDecimal num11 = new BigDecimal("5");BigDecimal num12 = new BigDecimal("0.05");BigDecimal num13 = new BigDecimal("-5");BigDecimal num21 = BigDecimal.ZERO;BigDecimal num22 = BigDecimal.ONE;BigDecimal num23 = BigDecimal.TEN;//加法BigDecimal result1 = num1.add(num2);BigDecimal result11 = num11.add(num12);//减法BigDecimal result2 = num1.subtract(num2);BigDecimal result12 = num11.subtract(num12);//乘法BigDecimal result3 = num1.multiply(num2);BigDecimal result13 = num11.multiply(num12);//除法BigDecimal result4 = num2.divide(num1, 2, BigDecimal.ROUND_HALF_UP);BigDecimal result14 = num12.divide(num11, 2, BigDecimal.ROUND_HALF_UP);//绝对值BigDecimal result5 = num3.abs();BigDecimal result15 = num13.abs();System.out.println("result1(value加法)->" + result1);System.out.println("result11(string加法)->" + result11);System.out.println("result2(value减法)->" + result2);System.out.println("result12(string减法)->" + result12);System.out.println("result3(value乘法)->" + result3);System.out.println("result13(string乘法)->" + result13);System.out.println("result4(value除法)->" + result4);System.out.println("result14(string除法)->" + result14);System.out.println("result5(绝对值)->" + result5);System.out.println("result15(绝对值)->" + result15);/*System.out.println("num1->" + num1);System.out.println("num2->" + num2);System.out.println("num3->" + num3);System.out.println("num11->" + num11);System.out.println("num12->" + num12);System.out.println("num13->" + num13);System.out.println("num21->" + num21);System.out.println("num22->" + num22);System.out.println("num23->" + num23);*/}
}
1.3除法divide()除不尽的舍入规则
// 即为 (BigDecimal divisor 除数, int scale 精确小数位, int roundingMode 舍入模式)
public BigDecimal divide(BigDecimal divisor, int scale, RoundingMode roundingMode) {return divide(divisor, scale, roundingMode.oldMode);}
使用除法需要考虑被除数的值问题,被除数在运算前应做判断。
结果的保留问题,精确的小数值位数和舍入模式。
计算1÷3的结果(最后一种ROUND_UNNECESSARY在结果为无限小数的情况下会报错,ArithmeticException)。
舍入模式:
1), ROUND_UP:进位制:不管精度保留数字后面是大是小(0除外)都会往前进1
2), ROUND_DOWN:无论精确小数位后面是多少,都直接丢弃.
3), ROUND_CEILING:无论后面是多少**(后面是0的话除外)**,
值为正,舍入模式与ROUND_UP相同,
值为负,舍入模式与ROUND_DOWN相同.
4), ROUND_FLOOR:无论后面是多少**(后面是0的话除外)**,
值为正,舍入模式与ROUND_DOWN相同,
值为负,舍入模式与ROUND_UP相同.
5), ROUND_HALF_UP:在绝对值的角度舍和入,这就是我们熟识的四舍五入模式;
如果与两个相邻数字的距离相等,则为向上舍入的舍入模式。
如果舍弃部分 >= 0.5,则舍入行为与 ROUND_UP 相同;
否则舍入行为与 ROUND_DOWN 相同。
6), ROUND_HALF_DOWN:在绝对值的角度舍和入;
如果与两个相邻数字的距离相等,则为向上舍入的舍入模式。
如果舍弃部分 > 0.5,则舍入行为与 ROUND_UP 相同;
否则舍入行为与 ROUND_DOWN 相同(五舍六入)。
7), ROUND_HALF_EVEN:
如果与两个相邻数字的距离相等,则向相邻的偶数舍入。
如果舍弃部分左边的数字为奇数,则舍入行为与 ROUND_HALF_UP 相同;
如果为偶数,则舍入行为与 ROUND_HALF_DOWN 相同。
注意,在重复进行一系列计算时,此舍入模式可以将累加错误减到最小。
此舍入模式也称为“银行家舍入法”,主要在美国使用。四舍六入,五分两种情况。
如果前一位为奇数,则入位,否则舍去。
以下例子为保留小数点1位,那么这种舍入方式下的结果。
1.15->1.2
1.25->1.2
8), ROUND_UNNECESSARY: 断言请求的操作具有精确的结果,因此不需要舍入**(**如果对获得精确结果的操作指定此舍入模式,则抛出ArithmeticException)。
2.BigDecimal.valueOf(double val)与new BigDecimal(double val) 的区别
BigDecimal.valueOf(double val)与new BigDecimal(double val)的区别是什么呢?
查看java源码,可以发现BigDecimal.valueOf(double val)方法还是调用了new BigDecimal() 构造方法,不过它是将val参数转成String类型后才传递过去的:
public static BigDecimal valueOf(