原创 2021-04-17 17:39:39

前言
在企业开发的过程中,对金额的精度是要求非常严格的。而double 和float等浮点类型存在着精度问题。所以浮点型不应该被用于严格要求精度的场合下。这个时候就用到了BigDecimal。

构造方法

1.public BigDecimal(int val)
2.public BigDecimal(String val)
3.public BigDecimal(double val)



BigDecimal对整形,字符串类型,浮点型都提供了对应的构造方法。在这里需要注意的就是在使用构造方法的时候尽量使用整形或者字符串类型的构造方法。因为浮点型的构造方法可能会让BigDecimal产生误差。

@Test
void floDemo(){
   double d1 = 123.123;
   BigDecimal num = new BigDecimal(d1);
   BigDecimal num2 = new BigDecimal(Double.toString(d1));
   System.out.println(num);
   System.out.println(num2);
}


常用的比较方法
1.判断两个bigDecimal是否相等equals()方法

@Test
void equals() {
   BigDecimal num = new BigDecimal(0.0);
   if(num.equals(BigDecimal.ZERO)){
       System.out.println("0");
   }else{
       System.out.println("非0");
   }
}



2.比较大小的方法compateTo.方法
num1.compareTo(num2).
当num1 > num2的时候 返回 1
当num1 < num2的时候 返回 -1
当num1 = num2的时候 返回 0

@Test
void numDemo() {
   BigDecimal num = new BigDecimal(1);
   System.out.println("1和0的比较 "+num.compareTo(BigDecimal.ZERO));
   System.out.println("1和1的比较 "+num.compareTo(BigDecimal.ONE));
   System.out.println("1和10的比较 "+num.compareTo(BigDecimal.TEN));

}


加减乘除运算
bigDecimal 是无法直接使用+、-、*、/来计算的,需要使用其提供的方法,。
1.加法:add();

BigDecimal num1 = new BigDecimal(1);
BigDecimal num2 = new BigDecimal(2);
//result = num1+num2;
BigDecimal result = num1.add(BigDecimal.ONE);


result为两数相加的结果。

2.减法subtract()

BigDecimal num1 = new BigDecimal(2);
BigDecimal num2 = new BigDecimal(1);
//res = num1 - num2;
BigDecimal res  = num1.subtract(num2);



3.乘法 multiply()

BigDecimal num1 = new BigDecimal(1);
BigDecimal num2 = new BigDecimal(2);
//res = num1* num2;
BigDecimal res = num1.multiply(num2);



4.除法 divide();
在BigDecimal 的加减乘除运算方法中,最应该被注意的就是除法。因为BigDecimal是需要保证经度的。而除法存在着无法被整除的情况。这时候如果不指定经度和舍入模式会抛出异常。

指定经度,舍入模式以后

 

@Test
void chu(){
   BigDecimal num1 = BigDecimal.ONE;
   BigDecimal num2 = new BigDecimal("3");
   // BigDecimal num3 = num1.divide(num2); //结果抛出异常
   BigDecimal num3 = num1.divide(num2,2,BigDecimal.ROUND_HALF_UP);//结果0.33
   System.out.println(num3);
}



舍入模式
1、ROUND_UP
远离零的舍入模式。
在丢弃非零部分之前始终增加数字(始终对非零舍弃部分前面的数字加1)。
注意,此舍入模式始终不会减少计算值的大小。

数值1.11.7-1.1-1.7
ROUND_UP22-2-2


2、ROUND_DOWN
接近零的舍入模式。
在丢弃某部分之前始终不增加数字(从不对舍弃部分前面的数字加1,即截短)。
注意,此舍入模式始终不会增加计算值的大小。

数值1.11.7-1.1-1.7
ROUND_DOWN11-1-1


3、ROUND_CEILING
接近正无穷大的舍入模式。
如果 BigDecimal 为正,则舍入行为与 ROUND_UP 相同;
如果为负,则舍入行为与 ROUND_DOWN 相同。
注意,此舍入模式始终不会减少计算值。

数值1.11.7-1.1-1.7
ROUND_CEILING22-1-1


4、ROUND_FLOOR
接近负无穷大的舍入模式。
如果 BigDecimal 为正,则舍入行为与 ROUND_DOWN 相同;
如果为负,则舍入行为与 ROUND_UP 相同。
注意,此舍入模式始终不会增加计算值。

数值1.11.7-1.1-1.7
ROUND_FLOOR11-2-2


5、ROUND_HALF_UP
向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则为向上舍入的舍入模式。
如果舍弃部分 >= 0.5,则舍入行为与 ROUND_UP 相同;否则舍入行为与 ROUND_DOWN 相同。
注意,这是我们大多数人在小学时就学过的舍入模式(四舍五入)。

数值1.41.5-1.4-1.5
ROUND_HALF_UP12-1-2


6、ROUND_HALF_DOWN
向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则为上舍入的舍入模式。
如果舍弃部分 > 0.5,则舍入行为与 ROUND_UP 相同;否则舍入行为与 ROUND_DOWN 相同(五舍六入)。

数值1.51.6-1.5-1.6
ROUND_HALF_DOWN12-1-2


7、ROUND_HALF_EVEN
向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。
如果舍弃部分左边的数字为奇数,则舍入行为与 ROUND_HALF_UP 相同;
如果为偶数,则舍入行为与 ROUND_HALF_DOWN 相同。
注意,在重复进行一系列计算时,此舍入模式可以将累加错误减到最小。
此舍入模式也称为“银行家舍入法”,主要在美国使用。四舍六入,五分两种情况。
如果前一位为奇数,则入位,否则舍去。
以下例子为保留小数点1位,那么这种舍入方式下的结果。

数值1.41.51.62.42.52.6
ROUND_HALF_EVEN122223
数值-1.4-1.5-1.6-2.4-2.5-2.6
ROUND_HALF_EVEN-1-2-2-2-2-3


8、ROUND_UNNECESSARY
断言请求的操作具有精确的结果,因此不需要舍入。
如果对获得精确结果的操作指定此舍入模式,则抛出ArithmeticException。
只要不是不是非0的数就会抛出异常。

注意事项
1.在使用构造方法的时候尽量用整形的或者字符串类型的。
2.在做除法运算的时候要指定精度和舍入模式。
 

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

延伸阅读
  1. springboot + maven (profile)实现项目多环境配置
  2. springboot 项目之多配置文件
  3. quartz定时任务cron表达式详解
  4. java基础模块面试题
  5. 一款比较有意思的404页面
发表评论