|
@@ -0,0 +1,325 @@
|
|
|
+package com.chelvc.framework.common.util;
|
|
|
+
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.math.BigInteger;
|
|
|
+import java.math.RoundingMode;
|
|
|
+
|
|
|
+import lombok.NonNull;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 数字处理工具类
|
|
|
+ *
|
|
|
+ * @author Woody
|
|
|
+ * @date 2024/1/30
|
|
|
+ */
|
|
|
+public final class NumberUtils {
|
|
|
+ /**
|
|
|
+ * 默认小数保留位数
|
|
|
+ */
|
|
|
+ public static final int DEFAULT_DECIMAL_SCALE = 8;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 默认小数四舍五入模式
|
|
|
+ */
|
|
|
+ public static final RoundingMode DEFAULT_ROUND_MODE = RoundingMode.HALF_UP;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 100小数
|
|
|
+ */
|
|
|
+ private static final BigDecimal HUNDRED_DECIMAL = new BigDecimal(100);
|
|
|
+
|
|
|
+ private NumberUtils() {
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 判断数字是否等于0
|
|
|
+ *
|
|
|
+ * @param number 数字
|
|
|
+ * @return true/false
|
|
|
+ */
|
|
|
+ public static boolean isZero(Number number) {
|
|
|
+ if (number instanceof BigInteger) {
|
|
|
+ return BigInteger.ZERO.equals(number);
|
|
|
+ } else if (number instanceof BigDecimal) {
|
|
|
+ return BigDecimal.ZERO.equals(number);
|
|
|
+ }
|
|
|
+ return number != null && number.intValue() == 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将数字转换成小数
|
|
|
+ *
|
|
|
+ * @param number 数字
|
|
|
+ * @return 大数字小数
|
|
|
+ */
|
|
|
+ public static BigDecimal number2decimal(Number number) {
|
|
|
+ if (number == null) {
|
|
|
+ return null;
|
|
|
+ } else if (number instanceof BigDecimal) {
|
|
|
+ return (BigDecimal) number;
|
|
|
+ } else if (number instanceof BigInteger) {
|
|
|
+ return new BigDecimal((BigInteger) number);
|
|
|
+ } else if (number instanceof Float || number instanceof Double) {
|
|
|
+ return BigDecimal.valueOf(number.doubleValue());
|
|
|
+ }
|
|
|
+ return BigDecimal.valueOf(number.longValue());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 乘以10
|
|
|
+ *
|
|
|
+ * @param number 数字
|
|
|
+ * @return 结果
|
|
|
+ */
|
|
|
+ public static BigDecimal multiply10(Number number) {
|
|
|
+ return number == null || isZero(number) ? BigDecimal.ZERO : number2decimal(number).multiply(BigDecimal.TEN);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 乘以100
|
|
|
+ *
|
|
|
+ * @param number 数字
|
|
|
+ * @return 结果
|
|
|
+ */
|
|
|
+ public static BigDecimal multiply100(Number number) {
|
|
|
+ return number == null || isZero(number) ? BigDecimal.ZERO : number2decimal(number).multiply(HUNDRED_DECIMAL);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 除以10
|
|
|
+ *
|
|
|
+ * @param number 被除数
|
|
|
+ * @return 结果
|
|
|
+ */
|
|
|
+ public static BigDecimal divide10(Number number) {
|
|
|
+ return divide(number, BigDecimal.TEN);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 除以10
|
|
|
+ *
|
|
|
+ * @param number 被除数
|
|
|
+ * @param scale 小数位数
|
|
|
+ * @return 结果
|
|
|
+ */
|
|
|
+ public static BigDecimal divide10(Number number, int scale) {
|
|
|
+ return divide(number, BigDecimal.TEN, scale);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 除以10
|
|
|
+ *
|
|
|
+ * @param number 被除数
|
|
|
+ * @param mode 四舍五入模式
|
|
|
+ * @return 结果
|
|
|
+ */
|
|
|
+ public static BigDecimal divide10(Number number, @NonNull RoundingMode mode) {
|
|
|
+ return divide(number, BigDecimal.TEN, mode);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 除以10
|
|
|
+ *
|
|
|
+ * @param number 被除数
|
|
|
+ * @param scale 小数位数
|
|
|
+ * @param mode 四舍五入模式
|
|
|
+ * @return 结果
|
|
|
+ */
|
|
|
+ public static BigDecimal divide10(Number number, int scale, @NonNull RoundingMode mode) {
|
|
|
+ return divide(number, BigDecimal.TEN, scale, mode);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 除以100
|
|
|
+ *
|
|
|
+ * @param number 被除数
|
|
|
+ * @return 结果
|
|
|
+ */
|
|
|
+ public static BigDecimal divide100(Number number) {
|
|
|
+ return divide(number, HUNDRED_DECIMAL);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 除以100
|
|
|
+ *
|
|
|
+ * @param number 被除数
|
|
|
+ * @param scale 小数位数
|
|
|
+ * @return 结果
|
|
|
+ */
|
|
|
+ public static BigDecimal divide100(Number number, int scale) {
|
|
|
+ return divide(number, HUNDRED_DECIMAL, scale);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 除以100
|
|
|
+ *
|
|
|
+ * @param number 被除数
|
|
|
+ * @param mode 四舍五入模式
|
|
|
+ * @return 结果
|
|
|
+ */
|
|
|
+ public static BigDecimal divide100(Number number, @NonNull RoundingMode mode) {
|
|
|
+ return divide(number, HUNDRED_DECIMAL, mode);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 除以100
|
|
|
+ *
|
|
|
+ * @param number 被除数
|
|
|
+ * @param scale 小数位数
|
|
|
+ * @param mode 四舍五入模式
|
|
|
+ * @return 结果
|
|
|
+ */
|
|
|
+ public static BigDecimal divide100(Number number, int scale, @NonNull RoundingMode mode) {
|
|
|
+ return divide(number, HUNDRED_DECIMAL, scale, mode);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 除法
|
|
|
+ *
|
|
|
+ * @param dividend 被除数
|
|
|
+ * @param divisor 除数
|
|
|
+ * @return 结果
|
|
|
+ */
|
|
|
+ public static BigDecimal divide(Number dividend, Number divisor) {
|
|
|
+ return divide(dividend, divisor, DEFAULT_DECIMAL_SCALE);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 除法
|
|
|
+ *
|
|
|
+ * @param dividend 被除数
|
|
|
+ * @param divisor 除数
|
|
|
+ * @param scale 小数位数
|
|
|
+ * @return 结果
|
|
|
+ */
|
|
|
+ public static BigDecimal divide(Number dividend, Number divisor, int scale) {
|
|
|
+ return divide(dividend, divisor, scale, DEFAULT_ROUND_MODE);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 除法
|
|
|
+ *
|
|
|
+ * @param dividend 被除数
|
|
|
+ * @param divisor 除数
|
|
|
+ * @param mode 四舍五入模式
|
|
|
+ * @return 结果
|
|
|
+ */
|
|
|
+ public static BigDecimal divide(Number dividend, Number divisor, @NonNull RoundingMode mode) {
|
|
|
+ return divide(dividend, divisor, DEFAULT_DECIMAL_SCALE, mode);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 除法
|
|
|
+ *
|
|
|
+ * @param dividend 被除数
|
|
|
+ * @param divisor 除数
|
|
|
+ * @param scale 小数位数
|
|
|
+ * @param mode 四舍五入模式
|
|
|
+ * @return 结果
|
|
|
+ */
|
|
|
+ public static BigDecimal divide(Number dividend, Number divisor, int scale, @NonNull RoundingMode mode) {
|
|
|
+ if (dividend == null || divisor == null || isZero(dividend) || isZero(divisor)) {
|
|
|
+ return BigDecimal.ZERO.setScale(scale, mode);
|
|
|
+ }
|
|
|
+ return number2decimal(dividend).divide(number2decimal(divisor), scale, mode);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 格式化小数
|
|
|
+ *
|
|
|
+ * @param decimal 小数
|
|
|
+ * @return 小数字符串
|
|
|
+ */
|
|
|
+ public static String format(BigDecimal decimal) {
|
|
|
+ return format(decimal, false);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 格式化小数
|
|
|
+ *
|
|
|
+ * @param decimal 小数
|
|
|
+ * @param scale 小数保留位数
|
|
|
+ * @return 小数字符串
|
|
|
+ */
|
|
|
+ public static String format(BigDecimal decimal, int scale) {
|
|
|
+ return format(decimal, scale, RoundingMode.HALF_UP, false);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 格式化小数
|
|
|
+ *
|
|
|
+ * @param decimal 小数
|
|
|
+ * @param mode 小数舍弃模式
|
|
|
+ * @return 小数字符串
|
|
|
+ */
|
|
|
+ public static String format(BigDecimal decimal, @NonNull RoundingMode mode) {
|
|
|
+ return format(decimal, DEFAULT_DECIMAL_SCALE, mode, false);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 格式化小数
|
|
|
+ *
|
|
|
+ * @param decimal 小数
|
|
|
+ * @param trimZeros 是否去掉多余的0
|
|
|
+ * @return 小数字符串
|
|
|
+ */
|
|
|
+ public static String format(BigDecimal decimal, boolean trimZeros) {
|
|
|
+ return format(decimal, DEFAULT_DECIMAL_SCALE, RoundingMode.HALF_UP, trimZeros);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 格式化小数
|
|
|
+ *
|
|
|
+ * @param decimal 小数
|
|
|
+ * @param scale 小数保留位数
|
|
|
+ * @param mode 小数舍弃模式
|
|
|
+ * @return 小数字符串
|
|
|
+ */
|
|
|
+ public static String format(BigDecimal decimal, int scale, @NonNull RoundingMode mode) {
|
|
|
+ return format(decimal, scale, mode, false);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 格式化小数
|
|
|
+ *
|
|
|
+ * @param decimal 小数
|
|
|
+ * @param scale 小数保留位数
|
|
|
+ * @param trimZeros 是否去掉多余的0
|
|
|
+ * @return 小数字符串
|
|
|
+ */
|
|
|
+ public static String format(BigDecimal decimal, int scale, boolean trimZeros) {
|
|
|
+ return format(decimal, scale, DEFAULT_ROUND_MODE, trimZeros);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 格式化小数
|
|
|
+ *
|
|
|
+ * @param decimal 小数
|
|
|
+ * @param mode 小数舍弃模式
|
|
|
+ * @param trimZeros 是否去掉多余的0
|
|
|
+ * @return 小数字符串
|
|
|
+ */
|
|
|
+ public static String format(BigDecimal decimal, @NonNull RoundingMode mode, boolean trimZeros) {
|
|
|
+ return format(decimal, DEFAULT_DECIMAL_SCALE, mode, trimZeros);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 格式化小数
|
|
|
+ *
|
|
|
+ * @param decimal 小数
|
|
|
+ * @param scale 小数保留位数
|
|
|
+ * @param mode 小数舍弃模式
|
|
|
+ * @param trimZeros 是否去掉多余的0
|
|
|
+ * @return 小数字符串
|
|
|
+ */
|
|
|
+ public static String format(BigDecimal decimal, int scale, @NonNull RoundingMode mode, boolean trimZeros) {
|
|
|
+ if (decimal == null) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ decimal = decimal.setScale(scale, mode);
|
|
|
+ if (trimZeros) {
|
|
|
+ decimal = decimal.stripTrailingZeros();
|
|
|
+ }
|
|
|
+ return decimal.toPlainString();
|
|
|
+ }
|
|
|
+}
|