JavaBigDecimal类常⽤⽅法
最近⼯作中接触到了 Java BigDecimal类,准备整理⼀下⽤到的⼏个常⽤⽅法。
简介
Java在java.math包中提供的API类BigDecimal,⽤来对超过16位有效位的数进⾏精确的运算。双精度浮点型变量double可以处理16位有效数。在实际应⽤中,需要对更⼤或者更⼩的数进⾏运算和处理。float和double只能⽤来做科学计算或者是⼯程计算,在商业计算中要⽤java.math.BigDecimal。BigDecimal所创建的是对象,我们不能使⽤传统的+、-、*、/等算术运算符直接对其对象进⾏数学运算,⽽必须调⽤其相对应的⽅法。⽅法中的参数也必须是BigDecimal的对象。构造器是类的特殊⽅法,专门⽤来创建对象,特别是带有参数的对象。
构造器
BigDecimal(int)      创建⼀个具有参数所指定整数值的对象。
BigDecimal(double) 创建⼀个具有参数所指定双精度值的对象。
BigDecimal(long)    创建⼀个具有参数所指定长整数值的对象。
BigDecimal(String) 创建⼀个具有参数所指定以字符串表⽰的数值的对象。
这⼏个都是常⽤的构造器,他们返回的对象都是BigDecimal对象。换⽽⾔之,将各个类型的值转换为BigDecimal对象,就是通过构造器。
反过来说,将BigDecimal对象转换为其他类型的对象,我们通过以下⼏种:
toString()                将BigDecimal对象的数值转换成字符串。
doubleValue()          将BigDecimal对象中的值以双精度数返回。
floatValue()            将BigDecimal对象中的值以单精度数返回。
longValue()            将BigDecimal对象中的值以长整数返回。
intValue()              将BigDecimal对象中的值以整数返回。
常⽤⽅法
BigDecimal b1 = new BigDecimal("20");
BigDecimal b2 = new BigDecimal("30");
b1.add(b2) :加法,求两个BigDecimal类型数据的和。
b1.subtract(b2):减法,求两个BigDecimal类型数据的差。
b1.multiply(b2):乘法,求两个BigDecimal类型数据的积。
b1.max(b2) : 最⼤数,求两个BigDecimal类型数据的最⼤值
b1.min(b2) : 最⼩数,求两个BigDecimal类型数据的最⼩值。
bi.abs():绝对值,求BigDecimal类型数据的绝对值。
这⾥把除法单独拉出来
BigDecimal divide(BigDecimal divisor, int scale, int roundingMode)
除法 divide有三个参数的⽅法,第⼀参数表⽰除数,第⼆个参数表⽰⼩数点后保留位数,第三个参数
表⽰取舍规则。只有在作除法运算或四舍五⼊时才⽤到取舍规则。因为BigDecimal除法可能出现不能整除的情况,⽐如 4.5/1.3,这时会报错java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result。所以当我们⽤三参数的除法⽅法时,规定了保留⼏位⼩数以及你的保留⽅式,就可以避免异常。
⼏个取舍规则:
ROUND_CEILING //向正⽆穷⽅向舍⼊
ROUND_DOWN //向零⽅向舍⼊
ROUND_FLOOR //向负⽆穷⽅向舍⼊
ROUND_HALF_DOWN  //向(距离)最近的⼀边舍⼊,除⾮两边(的距离)是相等,如果是这样,向下舍⼊, 例如1.55 保留⼀位⼩数结果为1.5
ROUND_HALF_EVEN  //向(距离)最近的⼀边舍⼊,除⾮两边(的距离)是相等,如果是这样,如果保留位数是奇数,使⽤ROUND_HALF_UP,如果是偶数,使⽤ROUND_HALF_DOWN ROUND_HALF_UP  //向(距离)最近的⼀边舍⼊,除⾮两边(的距离)是相等,如果是这样,向上舍⼊, 1.55保留⼀位⼩数结果为1.6
ROUND_UNNECESSARY //计算结果是精确的,不需要舍⼊模式
ROUND_UP //向远离0的⽅向舍⼊
我们最常⽤的四舍五⼊应该是ROUND_HALF_UP
Note that this is the rounding mode that most of us were taught in grade school.
源码中的注释也解释了这⼀点。
这⾥说下除法⾥的第三个参数,
a.divide(b,2,RoundingMode.HALF_UP)
这⾥RoundingMode其实是个枚举类,点进去源码可以看到其实他就是匹配到⼏种取舍规则
UP(BigDecimal.ROUND_UP),
DOWN(BigDecimal.ROUND_DOWN),
CEILING(BigDecimal.ROUND_CEILING),
FLOOR(BigDecimal.ROUND_FLOOR),
HALF_UP(BigDecimal.ROUND_HALF_UP),
HALF_DOWN(BigDecimal.ROUND_HALF_DOWN),
HALF_EVEN(BigDecimal.ROUND_HALF_EVEN),
UNNECESSARY(BigDecimal.ROUND_UNNECESSARY);
⽽最常⽤的就是HALF_UP也就是四舍五⼊。
那如果我们在乘法或者加法减法中也要保留⼏位或者四舍五⼊,该怎么操作呢?
四舍五⼊
BigDecimal中有⼀个setScale()⽅法
bigdecimal除法保留小数
第⼀个参数就是你要保留⼏位,第⼆个可填的参数就是取舍规则,图中的两种殊途同归。
如果你第⼆个参数不加,仅仅想保留⼏位,他在源码中会⾃动帮你选择默认的规则。
public BigDecimal setScale(int newScale) {
return setScale(newScale, ROUND_UNNECESSARY);
}
/**
* Rounding mode to assert that the requested operation has an exact
* result, hence no rounding is necessary.  If this rounding mode is
* specified on an operation that yields an inexact result, an
* {@code ArithmeticException} is thrown.
*/
public final static int ROUND_UNNECESSARY =  7;
源码中提及,当我们需要精确结果的时候,可以⽤这种取舍⽅式,但是如果你的结果不精确就会抛出异常。
栗⼦:
BigDecimal b1 = new BigDecimal("3.5");
BigDecimal b2 = new BigDecimal("7.7");
b1.divide(b2).setScale(2);
Exception in thread "main" java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.    at java.math.BigDecimal.divide(BigDecimal.java:1690)

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。