Bigdecimal–运算+限定格式+取余判断

  • Post author:
  • Post category:其他


一、运算

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。



版权声明:本文为Derek7117原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。