概述
本篇文章是自己学习的总结。
BigDecimal舍弃小数
BigDecimal中将小数精确到多少位的操作有很多,可以基于四舍五入,可以暴力截断,也可以只要有小数直接进位等等,有多种方式,下面就说一下有哪些精确小数的方式。
BigDecimal中精确到几位小数是通过setScale(int scale,RoundingMode roundingMode)这个函数实现的,所以理解了这个函数就理解了BigDecimal是如何对小数精确的。
第一个参数scale比较简单,想将小数精确到几位,scalse就等于几。
第二个参数RoundingMode决定的是如何对小数进行精确,这是重点讲解的部分。roundIngMode是定义好的枚举类,他有以下几个值ROUND_UP,ROUND_DOWN,ROUND_CEILING,ROUND_FLOOR,ROUND_HALF_UP,ROUND_HALF_DOWN,ROUND_HALF_EVEN。这些枚举类的效果如下图所示(图片来源Java文档)
注意一下,Java中也有setScalse(int scale,int roundingRode)的函数,但这个函数被弃用了,BigDecimal.CEILING等静态变量不如枚举类安全。
- ROUND_CEILING
这是直接向正无穷大进位。比如
BigDecimal("32.21").setScale(1, RoundingMode.CEILING) = 32.3;
BigDecimal("32.26").setScale(1, RoundingMode.CEILING) = 32.3;
而负数也是向正无穷大进位所以
BigDecimal("-32.21").setScale(1, RoundingMode.CEILING) = -32.2;
BigDecimal("-32.29").setScale(1, RoundingMode.CEILING) = -32.2;
- ROUND_FLOOR
它ROUND_CEILING相反,它是向负无穷大进位,比如
BigDecimal("32.21").setScale(1, RoundingMode.FLOOR) = 32.2;
BigDecimal("32.26").setScale(1, RoundingMode.FLOOR) = 32.2;
而负数向负无穷大进位的情况如下
BigDecimal("-32.21").setScale(1, RoundingMode.FLOOR) = -32.3;
BigDecimal("-32.29").setScale(1, RoundingMode.FLOOR) = -32.3;
- ROUND_DOWN
这是让小数向零的方向进位,比如
BigDecimal("32.21").setScale(1, RoundingMode.DOWN) = 32.2;
BigDecimal("32.28").setScale(1, RoundingMode.DOWN) = 32.2;
而负数的情况就是
BigDecimal("-32.21").setScale(1, RoundingMode.DOWN) = -32.2;
BigDecimal("-32.29").setScale(1, RoundingMode.DOWN) = -32.2;
- ROUND_UP
和ROUND_DOWN相反,它是向远离零的方向进位
BigDecimal("32.21").setScale(1, RoundingMode.UP) = 32.3;
BigDecimal("32.28").setScale(1, RoundingMode.UP) = 32.3;
而负数的情况是
BigDecimal("-32.21").setScale(1, RoundingMode.UP) = -32.3;
BigDecimal("-32.28").setScale(1, RoundingMode.UP) = -32.3;
- ROUND_HALF_UP
这个规则就是常见的四舍五入进位了
BigDecimal("32.25").setScale(1, RoundingMode.HALF_UP) = 32.3;
BigDecimal("-32.25").setScale(1, RoundingMode.HALF_UP) = -32.3;
- ROUND_HALF_DOWN
它和四舍五入比较像,不同点是,它是五舍六入
BigDecimal("32.25").setScale(1, RoundingMode.HALF_DOWN) = 32.2;
BigDecimal("-32.25").setScale(1, RoundingMode.HALF_DOWN) = -32.2;
- ROUND_HALF_EVEN
这也是和四舍五入比较像,但是它的进位有些不一样。该进位模式也被称为银行家舍入,它是像偶数位进位。
比如下面的小数位已经达到5,这是需要进位的,所以精确位进“进位”到偶数的位置。
BigDecimal("32.25").setScale(1, RoundingMode.HALF_EVEN) = 32.2;
而另一个例子
BigDecimal("32.35").setScale(1, RoundingMode.HALF_DOWN) = 32.4;
而精确位的后一位的数值小于5的话,就向奇数方向进位。
divide方法
大数中涉及到除法就会有很多问题,比如无限小数怎么显示。这里将详细说一下使用divide方法时的注意事项。
下面说一下divide的几种重载形式。
- BigDecimal divide(BigDecimal divisor)
这个方法只有一个点是需要注意的,它没法应对结果是无限小数的情况。比如下面的代码会直接报异常
BigDecimal temp = new BigDecimal("10");
System.out.println(temp.divide(BigDecimal.valueOf(3)));
- BigDecimal divide(BigDecimal divisor, int scale,RoundingMode roundingMode)
divisor是被除数,scale是精确到小数后的多少位,roundingMode就是上文介绍的采用哪种模式进行小数的精确。比如下面的例子
BigDecimal temp = new BigDecimal("32.21");
System.out.println(temp.divide(BigDecimal.valueOf(0.3), RoundingMode.CEILING));
输出结果为
同样的,关于RoundingMode roundingMode这个参数,Java仍然提供int roundingMode的形式,不过是被弃用的,一定要使用RoundingMode枚举类。
- BigDecimal divide(BigDecimal divisor, RoundingMode roundingMode)
这个方法和上个方法相同,只是不指明精确到小数多少位。这个函数其实是默认scale和调用这个方法的BigDecimal的scale相等。源码中是这样的
return divide(this.intCompact, this.scale, divisor.intCompact, divisor.scale, scale, roundingMode);
它直接将调用者的scale赋值给结果的scale。比如
BigDecimal temp = BigDecimal.valueOf(32.21); //这个初始化会将scale赋值为2,和32.21的scale相同
那么
BigDecimal result = temp.divide(BigDecimal.valueOf(3.0), RoundingMode.CEILING);
其中的result的scale和temp相同,也是等于2。
最后
以上就是欣喜云朵为你收集整理的Java学习笔记:BigDecimalBigDecimal舍弃小数divide方法的全部内容,希望文章能够帮你解决Java学习笔记:BigDecimalBigDecimal舍弃小数divide方法所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复