欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

常用的数学计算工具类

程序员文章站 2024-01-31 08:22:40
...
package com.xutil.math;

import java.math.BigDecimal;

/**
 * @title 数学计算工具类
 * @author Xingbz
 * @createDate 2018年11月16日
 */
public class XMathUtil {

    /** 默认的数据精度 */
    private static final int DEF_SCALE = 2;

    /** 默认的精度取舍方式(银行家算法) */
    private static final int DEF_ROUNDMODE = BigDecimal.ROUND_HALF_EVEN;

    //region 各种加法运算

    /** @title 精确加法运算 BigDecimal */
    public static BigDecimal add(BigDecimal v1, BigDecimal v2) {
        if (null == v1) v1 = BigDecimal.ZERO;
        if (null == v2) v2 = BigDecimal.ZERO;
        return v1.add(v2);
    }

    /** @title 精确加法运算 String */
    public static String add(String v1, String v2) {
        if (isBlank(v1)) v1 = "0";
        if (isBlank(v2)) v2 = "0";
        return String.valueOf(add(new BigDecimal(v1.trim()), new BigDecimal(v2.trim())));
    }

    /** @title 相对精确加法运算 保留2位小数 BigDecimal */
    public static BigDecimal addScale2Dec(BigDecimal v1, BigDecimal v2) {
        return scale2Dec(add(v1, v2));
    }

    /** @title 相对精确加法运算 保留2位小数 String */
    public static String addScale2Str(BigDecimal v1, BigDecimal v2) {
        return scale2Str(add(v1, v2));
    }
    //endregion

    //region 各种减法运算

    /** @title 精确减法运算 BigDecimal */
    public static BigDecimal subtract(BigDecimal v1, BigDecimal v2) {
        if (null == v1) return BigDecimal.ZERO;
        if (null == v2) return v1;
        return v1.subtract(v2);
    }

    /** @title 精确减法运算 String */
    public static String subtract(String v1, String v2) {
        if (isBlank(v1)) return "0";
        if (isBlank(v2)) return v1;
        return String.valueOf(subtract(new BigDecimal(v1.trim()), new BigDecimal(v2.trim())));
    }

    /** @title 相对精确减法运算 保留2为小数 BigDecimal */
    public static BigDecimal subtractScale2Dec(BigDecimal v1, BigDecimal v2) {
        return scale2Dec(subtract(v1, v2));
    }

    /** @title 相对精确减法运算 保留2为小数 BigDecimal */
    public static BigDecimal subtractScale2Dec(BigDecimal v1, BigDecimal... valList) {
        if (null == v1) v1 = BigDecimal.ZERO;
        if (null == valList || valList.length == 0) return v1;
        for (BigDecimal val : valList) {
            if (null != val) {
                v1 = subtract(v1, val);
            }
        }
        return scale2Dec(v1);
    }

    /** @title 相对精确减法运算 保留2位小数 String */
    public static String subtractScale2Str(BigDecimal v1, BigDecimal v2) {
        return scale2Str(subtract(v1, v2));
    }
    //endregion

    //region 各种乘法运算

    /** @title 精确乘法运算 BigDecimal */
    public static BigDecimal multiply(BigDecimal v1, BigDecimal v2) {
        if (null == v1 && null == v2) return BigDecimal.ZERO;
        if (null == v1) v1 = BigDecimal.ONE;
        if (null == v2) v2 = BigDecimal.ONE;
        return v1.multiply(v2);
    }

    /** @title 精确乘法运算 String */
    public static String multiply(String v1, String v2) {
        if (isBlank(v1) && isBlank(v2)) return "0";
        if (isBlank(v1)) v1 = "1";
        if (isBlank(v2)) v2 = "1";
        return String.valueOf(multiply(new BigDecimal(v1.trim()), new BigDecimal(v2.trim())));
    }

    /** @title 相对精确乘法运算 保留2位小数 BigDecimal */
    public static BigDecimal multiplyScale2Dec(BigDecimal v1, BigDecimal v2) {
        return scale2Dec(multiply(v1, v2));
    }

    /** @title 相对精确乘法运算 保留2位小数 String */
    public static String multiplyScale2Str(BigDecimal v1, BigDecimal v2) {
        return scale2Str(multiply(v1, v2));
    }
    //endregion

    //region 各种除法运算

    /** @title 相对精确除法运算 BigDecimal */
    public static BigDecimal divide(BigDecimal v1, BigDecimal v2) {
        return divide(v1, v2, DEF_SCALE);
    }

    /** @title 相对精确除法运算 保留scale位小数 BigDecimal */
    public static BigDecimal divide(BigDecimal v1, BigDecimal v2, Integer scale) {
        if (null == v1 || null == v2) return BigDecimal.ZERO;
        if (null == scale || scale < 0) scale = DEF_SCALE;
        return v1.divide(v2, scale, DEF_ROUNDMODE);
    }

    /** @title 相对精确除法运算 String */
    public static String divide(String v1, String v2) {
        return divide(v1, v2, DEF_SCALE);
    }

    /** @title 相对精确除法运算 保留scale位小数 String */
    public static String divide(String v1, String v2, Integer scale) {
        if (isBlank(v1) || isBlank(v2)) return "0";
        if (null == scale || scale < 0) scale = DEF_SCALE;
        return String.valueOf(divide(new BigDecimal(v1.trim()), new BigDecimal(v2.trim()), scale));
    }
    //endregion

    //region 各种求和运算

    /** @title 精确求和运算 , 忽略NULL BigDecimal */
    public static BigDecimal sum(BigDecimal v1, BigDecimal... valList) {
        if (null == v1) v1 = BigDecimal.ZERO;
        if (null == valList || valList.length == 0) return v1;
        for (BigDecimal val : valList) {
            if (null != val) {
                v1 = v1.add(val);
            }
        }
        return v1;
    }

    /** @title 精确求和运算 , 忽略NULL String */
    public static String sum(String v1, String... valList) {
        if (isBlank(v1)) v1 = "0";
        if (null == valList || valList.length == 0) return v1;
        BigDecimal b1 = new BigDecimal(v1.trim());
        for (String val : valList) {
            if (!isBlank(val)) {
                b1 = add(b1, new BigDecimal(val.trim()));
            }
        }
        return String.valueOf(b1);
    }

    /** @title 相对精确求和运算 , 保留2位小数 , 忽略NULL BigDecimal */
    public static BigDecimal sumScale2Dec(BigDecimal v1, BigDecimal... valList) {
        return scale2Dec(sum(v1, valList));
    }
    //endregion

    //region 平均数 最大/小数

    /** @title 平均数 BigDecimal*/
    public static BigDecimal avg(BigDecimal... valList) {
        if (null != valList && valList.length != 0) {
            return divide(sum(BigDecimal.ZERO, valList), new BigDecimal(valList.length));
        }
        return BigDecimal.ZERO;
    }

    /** @title 平均数 String */
    public static String avg(String... valList) {
        if (null != valList && valList.length != 0) {
            return divide(sum("0", valList), String.valueOf(valList.length));
        }
        return "0";
    }

    /** @title 最大值 BigDecimal */
    public static BigDecimal max(BigDecimal v1, BigDecimal... valList) {
        BigDecimal max = v1;
        if (null == valList || valList.length == 0) {
            return max;
        }
        for (BigDecimal val : valList) {
            if (null != val && val.compareTo(max) > 0) {
                max = val;
            }
        }
        return max;
    }

    /** @title 最大值 String */
    public static String max(String v1, String... valList) {
        if (isBlank(v1)) {
            return null;
        }
        if (null == valList || valList.length == 0) {
            return v1;
        }
        BigDecimal maxBd = new BigDecimal(v1.trim());

        for (String val : valList) {
            if (!isBlank(val) && new BigDecimal(val).compareTo(maxBd) > 0) {
                maxBd = new BigDecimal(val);
            }
        }
        return String.valueOf(maxBd);
    }

    /** @title 最大值 BigDecimal */
    public static BigDecimal maxArr(BigDecimal... valList) {
        return null == valList || valList.length == 0 ? null : max(valList[0], valList);
    }

    /** @title 最大值 String */
    public static String maxArr(String... valList) {
        return null == valList || valList.length == 0 ? null : max(valList[0], valList);
    }

    /** @title 最小值 BigDecimal */
    public static BigDecimal min(BigDecimal v1, BigDecimal... valList) {
        BigDecimal min = v1;
        if (null == valList || valList.length == 0) {
            return min;
        }
        for (BigDecimal val : valList) {
            if (null != val && val.compareTo(min) < 0) {
                min = val;
            }
        }
        return min;
    }

    /** @title 最小值 String */
    public static String min(String v1, String... valList) {
        if (isBlank(v1)) {
            return null;
        }
        if (null == valList || valList.length == 0) {
            return v1;
        }
        BigDecimal minBd = new BigDecimal(v1.trim());

        for (String val : valList) {
            if (!isBlank(val) && new BigDecimal(val).compareTo(minBd) < 0) {
                minBd = new BigDecimal(val);
            }
        }
        return String.valueOf(minBd);
    }

    /** @title 最小值 BigDecimal */
    public static BigDecimal minArr(BigDecimal... valList) {
        return null == valList || valList.length == 0 ? null : min(valList[0], valList);
    }

    /** @title 最小值 String */
    public static String minArr(String... valList) {
        return null == valList || valList.length == 0 ? null : min(valList[0], valList);
    }
    //endregion

    //region 比较大小

    /** @title val1 < val2 , 任何一个为null则返回false */
    public static boolean lessThan(BigDecimal val1, BigDecimal val2) {
        return isNoneNull(val1, val2) && val1.compareTo(val2) < 0;
    }

    /** @title val1 <= val2 , 任何一个为null则返回false */
    public static boolean lessThanOrEqual(BigDecimal val1, BigDecimal val2) {
        return isNoneNull(val1, val2) && val1.compareTo(val2) <= 0;
    }

    /** @title val1 > val2 , 任何一个为null则返回false */
    public static boolean moreThan(BigDecimal val1, BigDecimal val2) {
        return isNoneNull(val1, val2) && val1.compareTo(val2) > 0;
    }

    /** @title val1 >= val2 , 任何一个为null则返回false */
    public static boolean moreThanOrEqual(BigDecimal val1, BigDecimal val2) {
        return isNoneNull(val1, val2) && val1.compareTo(val2) >= 0;
    }

    /** @title val1 = val2 , 任何一个为null则返回false */
    public static boolean equalTo(BigDecimal val1, BigDecimal val2) {
        return isNoneNull(val1, val2) && val1.compareTo(val2) == 0;
    }
    //endregion

    //region 各种转换输出

    /** @title 常规BigDecimal , 保留2位小数 */
    public static BigDecimal scale2Dec(BigDecimal value) {
        return null == value ? null : value.setScale(DEF_SCALE, DEF_ROUNDMODE);
    }

    /** @title 原生数值 */
    public static String str(BigDecimal value) {
        return null == value ? "" : value.toString();
    }

    /** @title 整数 */
    public static String intBigDecimal(BigDecimal value) {
        return null == value ? "" : value.intValue() + "";
    }

    /** @title 常规字符串 , 保留2位小数 , 默认"" */
    public static String scale2Str(BigDecimal value) {
        return null == value ? "" : value.setScale(DEF_SCALE, DEF_ROUNDMODE).toString();
    }

    /** @title 常规字符串 , 保留2位小数 , 默认0 */
    public static String normalBigDecimalDefZero(BigDecimal value) {
        return null == value ? "0" : value.setScale(DEF_SCALE, DEF_ROUNDMODE).toString();
    }

    /** @title 带百分号的字符串 */
    public static String scale2Percentage(BigDecimal value) {
        return null == value ? "" : value.setScale(DEF_SCALE, DEF_ROUNDMODE).toString() + "%";
    }
    //endregion

    //region 自身判断 , 不依赖第三方

    /** @title 判断字符串是否为空(不依赖第三方) */
    private static boolean isBlank(String str) {
        return null == str || str.trim().length() == 0;
    }

    /** 校验一组对象是否全是非null值 , 有任意一个null则返回false */
    private static boolean isNoneNull(final Object... objects) {
        if (null == objects || objects.length == 0) {
            return true;
        }
        for (final Object object : objects) {
            if (null == object) {
                return false;
            }
        }
        return true;
    }
    //endregion
}