BigDecimal的使用记录

欢迎访问个人博客德鲁大叔撸代码

最近一直忙于工作,好久没更新博客了。今天赶在下班之前做一个简单的记录。
在项目中需要计算一笔交易的返现、手续费、分账串等信息,大量的使用到BIgDecimal,赶在下班之前做一个简单的记录。
在项目中对于金额的操作,我们都是选择使用BIgDecimal (跟金钱打交道,对于精度要求都很高),它支持任何精度的定点数,可以用它来精确计算货币值;相反的,Float和Double只能用来做科学计算或者是工程计算。

一、如何初始化一个BIgdecimal

1
2
3
4
1、BigDecimal(String val):将String类型转换成BigDecimal类型数据(推荐使用)
2、BigDecimal(double val):将double类型转换成BigDecimal类型数据(不推荐使用)
3、BigDecimal valueOf(<T> t):将<T>类型转换成BigDecimal类型数据(推荐使用)
4、BigDecimal(int val):将int类型转换成BigDecimal类型数据

项目中推荐使用第一种方法,第二种墙裂不推荐使用,精度丢失严重!!!!!
第一次计算手续费的时候就用的第二种方法,结果程序执行完,莫名其妙少了7毛钱!!! 只到改用第一种方法才确保了金额的正确性,如下:

1
2
3
4
//交易金额-最终手续费+汇付结算底价-保费金额-角进制金额
BigDecimal amt = new BigDecimal(requestBO.getAmount().toString()).subtract(new BigDecimal(finalFeeAmt.toString())).
add(new BigDecimal(huifuStlmLow.toString())).subtract(new BigDecimal(insuranceAmt.toString())).
subtract(new BigDecimal(jiaoAmt.toString()));

二、BigDecimal的加减乘除操作

1
2
3
4
5
6
7
8
9
BigDecimal add(BigDecimal value):加法,求两个BigDecimal类型数据的和
BigDecimal subtract(BigDecimal value):减法,求两个BigDecimal类型数据的差
BigDecimal multiply(BigDecimal value):乘法,求两个BigDecimal类型数据的积
BigDecimal divide(BigDecimal divisor):除法,求两个BigDecimal类型数据的商
BigDecimal remainder(BigDecimal divisor):求余数,求BigDecimal类型数据除以divisor的余数
BigDecimal max(BigDecimal value):最大数,求两个BigDecimal类型数据的最大值
BigDecimal min(BigDecimal value):最小数,求两个BigDecimal类型数据的最小值
BigDecimal abs():绝对值,求BigDecimal类型数据的绝对值
BigDecimal negate():相反数,求BigDecimal类型数据的相反数

三、常用的舍入模式(设置保留小数点的位数)

1
2
3
4
5
6
7
8
ROUND_UP  舍入模式从零开始。 始终在非零丢弃分数之前增加数字。 请注意,该舍入模式不会降低计算值的大小
ROUND_DOWN 舍入模式向零舍入。 不要在丢弃的分数之前递增数字(即截断)。 请注意,该舍入模式不会增加计算值的大小
ROUND_CEILING 圆形模式向正无穷大转弯。 如果BigDecimal为正,则表现为ROUND_UP ; 如果为负,则表现为ROUND_DOWN 请注意,舍入模式不会降低计算值。
ROUND_FLOOR 舍入模式向负无穷大转弯。 如果BigDecimal为正,则表现为ROUND_DOWN ; 如果为负,表现为ROUND_UP 请注意,舍入模式不会增加计算值。
ROUND_HALF_UP 四舍五入模式向“最近邻居”转弯,除非两个邻居都是等距的,在这种情况下是圆括弧的。 对于ROUND_UP如果丢弃的分数为0.5,则表现为; 否则,表现为ROUND_DOWN 。 请注意,这是我们大多数人在小学教学的舍入模式
ROUND_HALF_DOWN 四舍五入模式向“最近邻居”转弯,除非这两个邻居都是等距离的,在这种情况下,这是倒圆的。 对于ROUND_UP如果丢弃的分数> 0.5,则表示行为; 否则,表现为ROUND_DOWN
ROUND_HALF_EVEN 四舍五入模式向“最近邻居”转弯,除非两个邻居都是等距离的,在这种情况下,向着邻居方向转移。 对于ROUND_HALF_UP行为,如果丢弃的分数的左边的数字是奇数的; 像ROUND_HALF_DOWN一样,如果它是均匀的。 请注意,这是在一系列计算中重复应用时最小化累积误差的舍入模式。
ROUND_UNNECESSARY 舍入模式来确定所请求的操作具有精确的结果,因此不需要舍入。 如果在产生不精确结果的操作上指定了舍入模式,则抛出ArithmeticException 。

在项目中常用到的有两种:
① ROUND_HALF_UP 通俗理解就是我们常说的四舍五入
② ROUND_UP 无论末尾是什么,都向上舍入

比如下图中的例子:
在这里插入图片描述

四、两个BigDecimal类型数据大小值比较

使用场景:生活中,每一张信用卡在使用之前都必须进行激活,在激活的时候,根据不同行的信用卡会有不同的激活押金。当用户在使用信用卡之前必须先进行激活。所谓激活就是刷一笔金额不小于信用卡本身设定的激活押金。比如:A信用卡的激活押金要求是299元,则用户激活的时候刷的金额必须大于299元。(不考虑外扣或者内扣) 那这种场景就需要比较用户的消费金额是不是小于激活押金的299了。
比如下图的例子:
在这里插入图片描述

坚持原创技术分享,您的支持将鼓励我继续创作!