BigDecimal 加减乘除 | 比较大小 | 取最大最小值 | 保留小数位 | 附上计算工具类
·
个人记录:最近用BigDecimal比较多,对精度要求高,记录一下
一、加减乘除
BigDecimal num1 = new BigDecimal(2);
BigDecimal num2 = new BigDecimal(6);
BigDecimal num3 = null;
-- 加 2+6
num3 = num1.add(num2);
-- 结果:8
-- 减 6-2
num3 = num2.subtract(num1);
-- 结果:4
-- 乘 2*6
num3 = num1.multiply(num2);
-- 结果:12
-- 除 6/2
num3 = num2.divide(num1);
-- 结果:3
二、比较大小
这里比较的时候不能直接 num4.compareTo(new BigDecimal(1)) == 1 或者 -1,只能num4.compareTo(new BigDecimal(1)) > 0或 < 0 或 “= = 0”,不能直接判断1或-1
BigDecimal num4 = new BigDecimal(0);
BigDecimal num5 = new BigDecimal(1);
BigDecimal num6 = new BigDecimal(2);
-- 小于 0<1
int i = num4.compareTo(new BigDecimal(1)); -- 结果:-1
-- 等于 1=1
i = num5.compareTo(new BigDecimal(1)) -- 结果:0
-- 大于 2>1
i = num6.compareTo(new BigDecimal(1)) -- 结果:1
-- 常用一步到位进行判断:
if(num4.compareTo(new BigDecimal(1)) > 0){
return true;
}
三、取最大最小值
BigDecimal num7 = new BigDecimal(11);
BigDecimal num8 = new BigDecimal(22);
-- 比较两个数的大小,返回小的数
System.out.println(num7.min(num8));
-- 结果:11
-- 比较两个数的大小,返回大的数
System.out.println(num7.max(num8));
-- 结果:22
四、保留小数
- 直接删除多余的小数位,如1.745会变成1.74
BigDecimal.setScale(2,BigDecimal.ROUND_DOWN);
- 进位处理,1.744变成1.75
BigDecimal.setScale(2,BigDecimal.ROUND_UP);
- 四舍五入,5向上,如1.745变为1.75
BigDecimal.setScale(2,BigDecimal.ROUND_HALF_UP);
- 四舍五入,不同的是如果是5则向下舍,如1.745变为1.74;1.747变为1.75
BigDecimal.setScale(2,BigDecimal.ROUND_HALF_DOWN);
测试:
-- 注意这里new Bigdecimal不能直接使用float和double类型,应该先转String再转Bigdecimal
System.out.println(new BigDecimal("1.745").setScale(2, BigDecimal.ROUND_DOWN));
System.out.println(new BigDecimal("1.745").setScale(2, BigDecimal.ROUND_UP));
System.out.println(new BigDecimal("1.745").setScale(2, BigDecimal.ROUND_HALF_UP));
System.out.println(new BigDecimal("1.745").setScale(2, BigDecimal.ROUND_HALF_DOWN));
-- 结果
1.74
1.75
1.75
1.74
System.out.println(new BigDecimal("1.744").setScale(2, BigDecimal.ROUND_HALF_UP));
System.out.println(new BigDecimal("1.744").setScale(2, BigDecimal.ROUND_UP));
System.out.println(new BigDecimal("1.744").setScale(2, BigDecimal.ROUND_HALF_UP));
System.out.println(new BigDecimal("1.744").setScale(2, BigDecimal.ROUND_HALF_DOWN));
System.out.println(new BigDecimal("1.747").setScale(2, BigDecimal.ROUND_HALF_DOWN));
-- 结果
1.74
1.75
1.74
1.74
1.75
五、遇到的坑,有小数位的精度问题
注意:
new 新的对象的时候整数可以直接这样:new BigDecimal(10);
但是带小数的会有精度损失,比如:new BigDecimal(10.13456),所以带小数的要使用字符串进行处理:new BigDecimal(“10.13456”)。
六、工具类DecimalUtil
import org.springframework.util.CollectionUtils;
import java.math.BigDecimal;
import java.util.List;
/**
* 描述:BigDecimal运算工具类
* 创建人:慌途L
*/
public class DecimalUtil {
/**
* 加法计算(result = x + y)
*
* @param x 被加数(可为null)
* @param y 加数 (可为null)
* @return 和 (可为null)
* @author dengcs
*/
public static BigDecimal add(BigDecimal x, BigDecimal y) {
if (x == null) {
return y;
}
if (y == null) {
return x;
}
return x.add(y);
}
/**
* 加法计算(result = a + b + c + d)
*
* @param a 被加数(可为null)
* @param b 加数(可为null)
* @param c 加数(可为null)
* @param d 加数(可为null)
* @return BigDecimal (可为null)
* @author dengcs
*/
public static BigDecimal add(BigDecimal a, BigDecimal b, BigDecimal c, BigDecimal d) {
BigDecimal ab = add(a, b);
BigDecimal cd = add(c, d);
return add(ab, cd);
}
/**
* 累加计算(result=x + result)
*
* @param addend 加数(可为null)
* @param augend 被加数 (可为null,若被加数不为为null,result默认值为0)
* @return 和 (可为null)
* @author dengcs
*/
public static BigDecimal accumulate(BigDecimal addend, BigDecimal augend) {
if (addend == null) {
return augend;
}
if (augend == null) {
augend = new BigDecimal("0");
}
return augend.add(addend);
}
/**
* 减法计算(result = x - y)
*
* @param x 被减数(可为null)
* @param y 减数(可为null)
* @return BigDecimal 差 (可为null)
* @author dengcs
*/
public static BigDecimal subtract(BigDecimal x, BigDecimal y) {
if (x == null || y == null) {
return null;
}
return x.subtract(y);
}
/**
* 乘法计算(result = x × y)
*
* @param x 乘数(可为null)
* @param y 乘数(可为null)
* @return BigDecimal 积
* @author dengcs
*/
public static BigDecimal multiply(BigDecimal x, BigDecimal y) {
if (x == null || y == null) {
return null;
}
return x.multiply(y);
}
public static BigDecimal multiply(List<BigDecimal> nums) {
if (CollectionUtils.isEmpty(nums)) {
return BigDecimal.ZERO;
}
return nums.stream().reduce(BigDecimal.ONE, BigDecimal::multiply);
}
/**
* 除法计算(result = x ÷ y)
*
* @param x 被除数(可为null)
* @param y 除数(可为null)
* @return 商 (可为null,四舍五入,默认保留20位小数)
* @author dengcs
*/
public static BigDecimal divide(BigDecimal x, BigDecimal y) {
if (x == null || y == null || y.compareTo(BigDecimal.ZERO) == 0) {
return null;
}
// 结果为0.000..时,不用科学计数法展示
return stripTrailingZeros(x.divide(y, 20, BigDecimal.ROUND_HALF_UP));
}
/**
* 转为字符串(防止返回可续计数法表达式)
*
* @param x 要转字符串的小数
* @return String
* @author dengcs
*/
public static String toPlainString(BigDecimal x) {
if (x == null) {
return null;
}
return x.toPlainString();
}
/**
* 保留小数位数
*
* @param x 目标小数
* @param scale 要保留小数位数
* @return BigDecimal 结果四舍五入
* @author dengcs
*/
public static BigDecimal scale(BigDecimal x, int scale) {
if (x == null) {
return null;
}
return x.setScale(scale, BigDecimal.ROUND_HALF_UP);
}
/**
* 整型转为BigDecimal
*
* @param x(可为null)
* @return BigDecimal (可为null)
* @author dengcs
*/
public static BigDecimal toBigDecimal(Integer x) {
if (x == null) {
return null;
}
return new BigDecimal(x.toString());
}
/**
* 长整型转为BigDecimal
*
* @param x(可为null)
* @return BigDecimal (可为null)
* @author dengcs
*/
public static BigDecimal toBigDecimal(Long x) {
if (x == null) {
return null;
}
return new BigDecimal(x.toString());
}
/**
* 双精度型转为BigDecimal
*
* @param x(可为null)
* @return BigDecimal (可为null)
* @author dengcs
*/
public static BigDecimal toBigDecimal(Double x) {
if (x == null) {
return null;
}
return new BigDecimal(x.toString());
}
/**
* 单精度型转为BigDecimal
*
* @param x(可为null)
* @return BigDecimal (可为null)
* @author dengcs
*/
public static BigDecimal toBigDecimal(Float x) {
if (x == null) {
return null;
}
return new BigDecimal(x.toString());
}
/**
* 字符串型转为BigDecimal
*
* @param x(可为null)
* @return BigDecimal (可为null)
* @author dengcs
*/
public static BigDecimal toBigDecimal(String x) {
if (x == null) {
return null;
}
return new BigDecimal(x);
}
/**
* 对象类型转为BigDecimal
*
* @param x(可为null)
* @return BigDecimal (可为null)
* @author dengcs
*/
public static BigDecimal toBigDecimal(Object x) {
if (x == null) {
return null;
}
BigDecimal result = null;
try {
result = new BigDecimal(x.toString());
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 倍数计算,用于单位换算
*
* @param x 目标数(可为null)
* @param multiple 倍数 (可为null)
* @return BigDecimal (可为null)
* @author dengcs
*/
public static BigDecimal multiple(BigDecimal x, Integer multiple) {
if (x == null || multiple == null) {
return null;
}
return DecimalUtil.multiply(x, toBigDecimal(multiple));
}
/**
* 去除小数点后的0(如: 输入1.000返回1)
*
* @param x 目标数(可为null)
* @return
*/
public static BigDecimal stripTrailingZeros(BigDecimal x) {
if (x == null) {
return null;
}
return x.stripTrailingZeros();
}
}
欢迎关注公众号:慌途L
后面会慢慢将文章迁移至公众号,也是方便在没有电脑的情况下可以进行翻阅,更新的话会两边同时更新,大家不用担心!
更多推荐
已为社区贡献3条内容
所有评论(0)