个人记录:最近用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不能直接使用floatdouble类型,应该先转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
后面会慢慢将文章迁移至公众号,也是方便在没有电脑的情况下可以进行翻阅,更新的话会两边同时更新,大家不用担心!
在这里插入图片描述


Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐