记java中用BigDecimal来解决数据类型不同及精确度高的相乘问题(多用于钱的计算)

  • 1、加减问题
  • 2、乘除问题
  • 3、BigDecimal下的构造函数
  • 4、BigDecimal下的常用方法
  • 5、相除时的舍入方法


1、加减问题

//valueOf用于转换原始值
BigDecimal priceNumBigAfter = BigDecimal.valueOf(priceNum);
BigDecimal balance = BigDecimal.valueOf(userByUserAccount.getBalance());
BigDecimal allPay = BigDecimal.valueOf(userByUserAccount.getAllPay());
User user = new User();
//用BigDecimal提供精确减法运算的subtract方法,余额减法运算
user.setBalance(balance.subtract(priceNumBigAfter).doubleValue());
//用BigDecimal提供精确减法运算的add方法,总消费加法运算
user.setAllPay(allPay.add(priceNumBigAfter).doubleValue());

2、乘除问题

//引入BigDecimal解决double相乘问题
BigDecimal orderPrice = BigDecimal.valueOf(userOrder.getOrderPrice());
BigDecimal orderTerm = BigDecimal.valueOf(userOrder.getOrderTerm());
//单价和月份相乘,得到总价
double priceNum = orderPrice.multiply(orderTerm).doubleValue();

BigDecimal b1 = new BigDecimal(Double.toString(d1));
BigDecimal b2 = new BigDecimal(Double.toString(d2));

//除不尽时有多种重载方法,此处选择保留两位小数,四舍五入
return b1.divide(b2, 2, BigDecimal.ROUND_HALF_UP);

3、BigDecimal下的构造函数

BigDecimal(int)

创建一个具有参数所指定整数值的对象

BigDecimal(double)

创建一个具有参数所指定双精度值的对象

BigDecimal(long)

创建一个具有参数所指定长整数值的对象

BigDecimal(String)

创建一个具有参数所指定以字符串表示的数值的对象

4、BigDecimal下的常用方法

add(BigDecimal)

BigDecimal对象中的值相加,返回BigDecimal对象

subtract(BigDecimal)

BigDecimal对象中的值相减,返回BigDecimal对象

multiply(BigDecimal)

BigDecimal对象中的值相乘,返回BigDecimal对象

divide(BigDecimal)

BigDecimal对象中的值相除,返回BigDecimal对象

toString()

将BigDecimal对象中的值转换成字符串

doubleValue()

将BigDecimal对象中的值转换成双精度数

floatValue()

将BigDecimal对象中的值转换成单精度数

longValue()

将BigDecimal对象中的值转换成长整数

intValue()

将BigDecimal对象中的值转换成整数

5、相除时的舍入方法


作者:行者_shi

尽管数据库存储的是一个高精度的浮点数,但是通常在应用中展示的时候往往需要限制一下小数点的位数,比如两到三位小数即可,这时就需要使用到setScale(int newScale, int roundingMode)函数,作为BigDecimal的公有静态变量,舍入模式(Rounding Mode)的运算规则比较多,公有八种,这里作个说明,官方文档也有介绍。

ROUND_UP
向远离零的方向舍入。舍弃非零部分,并将非零舍弃部分相邻的一位数字加一。
ROUND_DOWN
向接近零的方向舍入。舍弃非零部分,同时不会非零舍弃部分相邻的一位数字加一,采取截取行为。
ROUND_CEILING
向正无穷的方向舍入。如果为正数,舍入结果同ROUND_UP一致;如果为负数,舍入结果同ROUND_DOWN一致。注意:此模式不会减少数值大小。
ROUND_FLOOR
向负无穷的方向舍入。如果为正数,舍入结果同ROUND_DOWN一致;如果为负数,舍入结果同ROUND_UP一致。注意:此模式不会增加数值大小。
ROUND_HALF_UP
向“最接近”的数字舍入,如果与两个相邻数字的距离相等,则为向上舍入的舍入模式。如果舍弃部分>= 0.5,则舍入行为与ROUND_UP相同;否则舍入行为与ROUND_DOWN相同。这种模式也就是我们常说的我们的“四舍五入”。
ROUND_HALF_DOWN
向“最接近”的数字舍入,如果与两个相邻数字的距离相等,则为向下舍入的舍入模式。如果舍弃部分> 0.5,则舍入行为与ROUND_UP相同;否则舍入行为与ROUND_DOWN相同。这种模式也就是我们常说的我们的“五舍六入”。
ROUND_HALF_EVEN
向“最接近”的数字舍入,如果与两个相邻数字的距离相等,则相邻的偶数舍入。如果舍弃部分左边的数字奇数,则舍入行为与 ROUND_HALF_UP 相同;如果为偶数,则舍入行为与 ROUND_HALF_DOWN 相同。注意:在重复进行一系列计算时,此舍入模式可以将累加错误减到最小。此舍入模式也称为“银行家舍入法”,主要在美国使用。四舍六入,五分两种情况,如果前一位为奇数,则入位,否则舍去。
ROUND_UNNECESSARY
断言请求的操作具有精确的结果,因此不需要舍入。如果对获得精确结果的操作指定此舍入模式,则抛出ArithmeticException。