|
|
@@ -0,0 +1,126 @@
|
|
|
+package com.jzg.commons.util;
|
|
|
+
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.math.RoundingMode;
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ * BigDecimal 高精度运算工具类(适用于金额计算)
|
|
|
+ */
|
|
|
+public class BigDecimalUtil {
|
|
|
+
|
|
|
+ /** 默认除法运算精度(保留小数点后几位) */
|
|
|
+ private static final int DEF_DIV_SCALE = 2;
|
|
|
+ /** 默认舍入模式:四舍五入 */
|
|
|
+ private static final RoundingMode DEF_ROUNDING_MODE = RoundingMode.HALF_UP;
|
|
|
+
|
|
|
+ // 私有构造器,防止被实例化
|
|
|
+ private BigDecimalUtil() {}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 提供精确的加法运算
|
|
|
+ * @param v1 被加数
|
|
|
+ * @param v2 加数
|
|
|
+ * @return 两个参数的和
|
|
|
+ */
|
|
|
+ public static BigDecimal add(BigDecimal v1, BigDecimal v2) {
|
|
|
+ if (v1 == null) v1 = BigDecimal.ZERO;
|
|
|
+ if (v2 == null) v2 = BigDecimal.ZERO;
|
|
|
+ return v1.add(v2);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 提供精确的减法运算
|
|
|
+ * @param v1 被减数
|
|
|
+ * @param v2 减数
|
|
|
+ * @return 两个参数的差
|
|
|
+ */
|
|
|
+ public static BigDecimal subtract(BigDecimal v1, BigDecimal v2) {
|
|
|
+ if (v1 == null) v1 = BigDecimal.ZERO;
|
|
|
+ if (v2 == null) v2 = BigDecimal.ZERO;
|
|
|
+ return v1.subtract(v2);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 提供精确的乘法运算
|
|
|
+ * @param v1 被乘数
|
|
|
+ * @param v2 乘数
|
|
|
+ * @return 两个参数的积
|
|
|
+ */
|
|
|
+ public static BigDecimal multiply(BigDecimal v1, BigDecimal v2) {
|
|
|
+ if (v1 == null) v1 = BigDecimal.ZERO;
|
|
|
+ if (v2 == null) v2 = BigDecimal.ZERO;
|
|
|
+ return v1.multiply(v2);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 提供(相对)精确的除法运算。
|
|
|
+ * 当发生除不尽的情况时,默认精确到小数点以后2位,并四舍五入。
|
|
|
+ * @param v1 被除数
|
|
|
+ * @param v2 除数
|
|
|
+ * @return 两个参数的商
|
|
|
+ */
|
|
|
+ public static BigDecimal divide(BigDecimal v1, BigDecimal v2) {
|
|
|
+ return divide(v1, v2, DEF_DIV_SCALE);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 提供(相对)精确的除法运算。
|
|
|
+ * 当发生除不尽的情况时,由 scale 参数指定精度,并四舍五入。
|
|
|
+ * @param v1 被除数
|
|
|
+ * @param v2 除数
|
|
|
+ * @param scale 表示需要精确到小数点以后几位
|
|
|
+ * @return 两个参数的商
|
|
|
+ */
|
|
|
+ public static BigDecimal divide(BigDecimal v1, BigDecimal v2, int scale) {
|
|
|
+ if (v2 == null || v2.compareTo(BigDecimal.ZERO) == 0) {
|
|
|
+ throw new IllegalArgumentException("除数不能为0或null");
|
|
|
+ }
|
|
|
+ if (v1 == null) v1 = BigDecimal.ZERO;
|
|
|
+ return v1.divide(v2, scale, DEF_ROUNDING_MODE);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 对数值进行四舍五入(保留指定小数位)
|
|
|
+ * @param v 需要处理的数值
|
|
|
+ * @param scale 小数点后保留几位
|
|
|
+ * @return 处理后的结果
|
|
|
+ */
|
|
|
+ public static BigDecimal round(BigDecimal v, int scale) {
|
|
|
+ if (v == null) return BigDecimal.ZERO;
|
|
|
+ return v.setScale(scale, DEF_ROUNDING_MODE);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 比较两个数值的大小
|
|
|
+ * @param v1 第一个数
|
|
|
+ * @param v2 第二个数
|
|
|
+ * @return 如果 v1 > v2 返回 1;v1 < v2 返回 -1;相等返回 0
|
|
|
+ */
|
|
|
+ public static int compareTo(BigDecimal v1, BigDecimal v2) {
|
|
|
+ if (v1 == null) v1 = BigDecimal.ZERO;
|
|
|
+ if (v2 == null) v2 = BigDecimal.ZERO;
|
|
|
+ return v1.compareTo(v2);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 安全地将 double 转换为 BigDecimal(防止精度丢失)
|
|
|
+ * @param v 需要转换的 double 值
|
|
|
+ * @return 转换后的 BigDecimal 对象
|
|
|
+ */
|
|
|
+ public static BigDecimal valueOf(double v) {
|
|
|
+ return BigDecimal.valueOf(v);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 安全地将 String 转换为 BigDecimal
|
|
|
+ * @param v 需要转换的字符串
|
|
|
+ * @return 转换后的 BigDecimal 对象,若为 null 或空则返回 ZERO
|
|
|
+ */
|
|
|
+ public static BigDecimal valueOf(String v) {
|
|
|
+ if (v == null || v.trim().isEmpty()) {
|
|
|
+ return BigDecimal.ZERO;
|
|
|
+ }
|
|
|
+ return new BigDecimal(v);
|
|
|
+ }
|
|
|
+}
|