一、运算
1、bigdecimal初始化
初始化就是创建bigdecimal对象,无论是转换格式、还是做运算,都要先创建bigdecimal对象。
1)数值是String类型,转换成bigdecimal
String unitSave = micMicrobeRecordTo.getUnitSave();
BigDecimal unitSavebd = new BigDecimal(unitSave);
2)数值直接是数字类型,转换成bigdecimal
BigDecimal num1 = new BigDecimal(0.005);
BigDecimal num2 = new BigDecimal(1000000);
BigDecimal num3 = new BigDecimal(-1000000);
3)bigdecimal提供了一些常用的常量,可以直接生成,比较方便、也不易出错,例如:
//值为0的bigdecimal
BigDecimal.ZERO
//值为1的bigdecimal
BigDecimal.ONE
//值为10的bigdecimal
BigDecimal.TEN
2、加减乘除方法
加法 add()
减法 subtract()
乘法 multiply()
除法 divide()
绝对值 abs()
1)对于加、减、乘方法没什么问题,对于除法要注意,如果不做设置、结果是无线小数的话,会报错,例如 1 / 3,直接用
new BigDecimal("1").devide(new BigDecimal("3"));
就会报错。
解决方法也很简单,其实divide()方法可以参数除了传除数,还可以再传两个参数,一个是结果保留位数,一个是舍入模式
BigDecimal sampleCountbd = sampleAmoutbd.divide(unitSavebd, 0, BigDecimal.ROUND_DOWN);
2)可以做混合运算,例如:
月度剩余总量=上个月月度剩余总量+月接收量-月运出量
resultMonthAmountbd = lastMonthAmoutbd.add(monthReceivebd).subtract(monthOutbd);
3、结果格式化
对于最后的结果,工作中往往有具体的要求,比如要求统一保留2位小数、多余小数位采取四舍五入,比如要求保留整数、不是整数的部分舍去;这些对数据结果格式的要求,bigdecimal处理起来都很方便和准确,实际上正是这个原因,涉及到数字运算,尤其是涉及钱、实验结果等,都要求后台用bigdecimal来处理数据。
数字的格式化,涉及到两个维度,一个是保留位数、一个是舍入方式
两者都可以用setScale()函数来完成设置。
BigDecimal lastSampleCountbd = lastSampleAmoutbd.divide(unitSavebd, 0, BigDecimal.ROUND_DOWN);
String lastSampleAmoutStr = lastSampleAmoutbd.setScale(2, BigDecimal.ROUND_HALF_DOWN).toString();
4、判断结果是整数还是小数–取余运算,推荐两种方法
//法一:
BigDecimal outdiv = monthOutbd.divide(unitSavebd, 2, BigDecimal.ROUND_DOWN);
if(new BigDecimal(outdiv.intValue()).compareTo(outdiv)!=0){//运出量必须为单位存储量的整数倍
Result result = Result.failure();
result.setInfo("月度运出量必须为单位存储量的整数倍,请正确填写");
return result;
}
//法二:
BigDecimal[] receiveArr = monthReceivebd.divideAndRemainder(unitSavebd);
if(receiveArr[1].compareTo(BigDecimal.ZERO)!=0){//运入量必须为单位存储量的整数倍
Result result = Result.failure();
result.setInfo("月度接收量必须为单位存储量的整数倍,请正确填写");
return result;
}
1)第一种方法就是正常的做除法,得到结果后用intValue()方法、取结果的整数部分,然后拿“结果的整数部分”和“结果”对比,如果是整数,两者是相等的,如果是小数则两者不相等,依此判断结果是否为整数。
2)第二种方法是使用divideAndRemainder()方法,该方法返回一个Bigdecimal类型的数组,数组中包含两个元素,第一个元素为两数相除的商,第二个元素为余数;这样的话通过判断余数是否为0,就可以判断结果是否为整数了。
5、补充八种舍入模式解释如下:
1)ROUND_UP
非零就进一位
2、ROUND_DOWN
始终舍去
3、ROUND_CEILING
如果 BigDecimal 为正,则舍入行为与 ROUND_UP 相同;
如果为负,则舍入行为与 ROUND_DOWN 相同。
4、ROUND_FLOOR
如果 BigDecimal 为正,则舍入行为与 ROUND_DOWN 相同;
如果为负,则舍入行为与 ROUND_UP 相同。
5、ROUND_HALF_UP
四舍五入
6、ROUND_HALF_DOWN
五舍六入
7、ROUND_HALF_EVEN
在重复进行一系列计算时,此舍入模式可以将累加错误减到最小。
此舍入模式也称为“银行家舍入法”,主要在美国使用。四舍六入,五分两种情况。
如果前一位为奇数,则入位,否则舍去。
以下例子为保留小数点1位,那么这种舍入方式下的结果。
1.15>1.2 1.25>1.2
8、ROUND_UNNECESSARY
断言请求的操作具有精确的结果,因此不需要舍入。
如果对获得精确结果的操作指定此舍入模式,则抛出ArithmeticException。