package com.anyi.business.bank.tpp.pub; import java.math.BigDecimal; import com.martian.utils.tools.LogTools;//公司的框架,封装log4j,记录日志 /** * 数字的处理 */ public class MathTools { /** 两位精度 */ private final static int PRECISION_TWO = 2; private static final char[] RMB_NUMS = "零壹贰叁肆伍陆柒捌玖".toCharArray(); private static final String[] UNITS = { "元", "角", "分", "整" }; private static final String[] U1 = { "", "拾", "佰", "仟" }; private static final String[] U2 = { "", "万", "亿" }; /** * 求和:四舍五入,小数点后保留两位有效数字 * * @param augend * 被加数 * @param addend * 加数 * @return 和 */ public static double add(double augend, double addend) { BigDecimal sum = BigDecimal.valueOf(augend).add( BigDecimal.valueOf(addend)); return setScale(sum).doubleValue(); } /** * 求差:四舍五入,小数点后保留两位有效数字 * * @param minuend * 被减数 * @param subtrahend * 减数 * @return 差 */ public static double subtract(double minuend, double subtrahend) { BigDecimal difference = BigDecimal.valueOf(minuend).subtract( BigDecimal.valueOf(subtrahend)); return setScale(difference).doubleValue(); } /** * 求积:四舍五入,小数点后保留两位有效数字 * * @param multiplicand * 被乘数 * @param multiplier * 乘数 * @return 积 */ public static double multiply(double multiplicand, double multiplier) { BigDecimal product = BigDecimal.valueOf(multiplicand).multiply( BigDecimal.valueOf(multiplier)); return setScale(product).doubleValue(); } /** * 求商:四舍五入,小数点后保留两位有效数字 * * @param dividend * 被除数 * @param divisor * 除数 * @return 商 */ public static double divide(double dividend, double divisor) { int scale = PRECISION_TWO; int roundingMode = BigDecimal.ROUND_HALF_UP; BigDecimal quotient = BigDecimal.valueOf(dividend).divide( BigDecimal.valueOf(divisor), scale, roundingMode); return quotient.doubleValue(); } /** * 求和:四舍五入,根据参数scale确定小数点后保留有效数字位数 * * @param augend * 被加数 * @param addend * 加数 * @param scale * 刻度、数值范围 * @return 和 */ public static double add(double augend, double addend, int scale) { BigDecimal sum = BigDecimal.valueOf(augend).add( BigDecimal.valueOf(addend)); return setScale(sum, scale).doubleValue(); } /** * 求差:四舍五入,根据参数scale确定小数点后保留有效数字位数 * * @param minuend * 被减数 * @param subtrahend * 减数 * @param scale * 刻度、数值范围 * @return 差 */ public static double subtract(double minuend, double subtrahend, int scale) { BigDecimal difference = BigDecimal.valueOf(minuend).subtract( BigDecimal.valueOf(subtrahend)); return setScale(difference, scale).doubleValue(); } /** * 求积:四舍五入,根据参数scale确定小数点后保留有效数字位数 * * @param multiplicand * 被乘数 * @param multiplier * 乘数 * @param scale * 刻度、数值范围 * @return 积 */ public static double multiply(double multiplicand, double multiplier, int scale) { BigDecimal product = BigDecimal.valueOf(multiplicand).multiply( BigDecimal.valueOf(multiplier)); return setScale(product, scale).doubleValue(); } /** * 求商:四舍五入,根据参数scale确定小数点后保留有效数字位数 * * @param dividend * 被除数 * @param divisor * 除数 * @param scale * 刻度、数值范围 * @return 商 */ public static double divide(double dividend, double divisor, int scale) { int roundingMode = BigDecimal.ROUND_HALF_UP; BigDecimal quotient = BigDecimal.valueOf(dividend).divide( BigDecimal.valueOf(divisor), scale, roundingMode); return quotient.doubleValue(); } /** * 求和,没有限制 * * @param addend * 加数 * @param augend * 被加数 * @return 和 */ public static double addWithoutRestriction(double addend, double augend) { BigDecimal sum = BigDecimal.valueOf(addend).add( BigDecimal.valueOf(augend)); return sum.doubleValue(); } /** * 求差,没有限制 * * @param minuend * 被减数 * @param subtrahend * 减数 * @return 差 */ public static double subtractWithoutRestriction(double minuend, double subtrahend) { BigDecimal difference = BigDecimal.valueOf(minuend).subtract( BigDecimal.valueOf(subtrahend)); return difference.doubleValue(); } /** * 求积,没有限制 * * @param multiplicand * 被乘数 * @param multiplier * 乘数 * @return 积 */ public static double multiplyWithoutRestriction(double multiplicand, double multiplier) { BigDecimal product = BigDecimal.valueOf(multiplicand).multiply( BigDecimal.valueOf(multiplier)); return product.doubleValue(); } /** * 求商,没有限制 * * @param dividend * 被除数 * @param divisor * 除数 * @return 商 * @throws ArithmeticException * 当准确的商值没有无穷的十进制扩展 或者 divisor==0 */ public static double divideWithoutRestriction(double dividend, double divisor) throws ArithmeticException { BigDecimal quotient = BigDecimal.valueOf(dividend).divide( BigDecimal.valueOf(divisor)); return quotient.doubleValue(); } /** * 求相反数 * * @param val * 数值 * @return 相反数 */ public static double negate(double val) { BigDecimal negate = BigDecimal.valueOf(val).negate(); return setScale(negate).doubleValue(); } /** * 求相反数,根据参数scale确定小数点后保留有效数字位数 * * @param val * 数值 * @param scale * 刻度、数值范围 * @return */ public static double negate(double val, int scale) { BigDecimal negate = BigDecimal.valueOf(val).negate(); return setScale(negate, scale).doubleValue(); } /** * 四舍五入,小数点后保留两位有效数字 * * @param val * 数字 * @return 四舍五入,小数点后保留两位有效数字后的数字 */ public static BigDecimal setScale(BigDecimal val) { return val.setScale(PRECISION_TWO, BigDecimal.ROUND_HALF_UP); } /** * 四舍五入,根据参数scale确定小数点后保留有效数字位数 * * @param val * 数字 * @param scale * 小数点后保留有效数字的位数 * @return */ public static BigDecimal setScale(BigDecimal val, int scale) { return val.setScale(scale, BigDecimal.ROUND_HALF_UP); } /** * 将金额(整数部分等于或少于12位,小数部分2位)转换为中文大写形式. * * @param amount * 金额数字 * @return 中文大写 * @throws IllegalArgumentException */ public static String convert(String amount) throws IllegalArgumentException { String result = ""; String integer = ""; // 整数部分 String fraction = ""; // 小数部分 boolean isNegative = false; // 去掉分隔符 amount = amount.replace(",", ""); // 去掉负号 if (!(amount.indexOf("-") == -1)) { amount = amount.replace("-", ""); isNegative = true; } // 验证金额正确性 if (!checkNum(amount)) throw new NumberFormatException("非法数据,请检查!"); if (Double.valueOf(amount) == 0) { return result = "零元整"; } if (amount.indexOf(".") == -1) { integer = amount; fraction = "00"; } else { int index = amount.indexOf("."); integer = amount.substring(0, index); fraction = amount.substring(index + 1); } if (!integer.equals("0")) { result += integer2rmb(integer) + UNITS[0]; // 整数部分 } if (fraction.equals("00")) { result += UNITS[3]; // 添加[整] } else if (fraction.startsWith("0") && integer.equals("0")) { result += fraction2rmb(fraction).substring(1); // 去掉分前面的[零] } else { result += fraction2rmb(fraction); // 小数部分 } if (isNegative) { return "负".concat(result); } return result; } // 将金额小数部分转换为中文大写 private static String fraction2rmb(String fraction) { char jiao = fraction.charAt(0); // 角 char fen = fraction.charAt(1); // 分 return (RMB_NUMS[jiao - '0'] + (jiao > '0' ? UNITS[1] : "")) + (fen > '0' ? RMB_NUMS[fen - '0'] + UNITS[2] : ""); } // 将金额整数部分转换为中文大写 private static String integer2rmb(String integer) { StringBuilder buffer = new StringBuilder(); // 从个位数开始转换 int i, j; for (i = integer.length() - 1, j = 0; i >= 0; i--, j++) { char n = integer.charAt(i); if (n == '0') { // 当n是0且n的右边一位不是0时,插入[零] if (i < integer.length() - 1 && integer.charAt(i + 1) != '0') { buffer.append(RMB_NUMS[0]); } // 插入[万]或者[亿] if (j % 4 == 0) { if (i > 0 && integer.charAt(i - 1) != '0' || i > 1 && integer.charAt(i - 2) != '0' || i > 2 && integer.charAt(i - 3) != '0') { buffer.append(U2[j / 4]); } } } else { if (j % 4 == 0) { buffer.append(U2[j / 4]); // 插入[万]或者[亿] } buffer.append(U1[j % 4]); // 插入[拾]、[佰]或[仟] buffer.append(RMB_NUMS[n - '0']); // 插入数字 } } return buffer.reverse().toString(); } /** * 判断用户输入的数据是否合法,用户只能输入大于零的数字,不能输入其它字符 * * @param s * String * @return 如果用户输入数据合法,返回 true,否则返回 false */ private static boolean checkNum(String s) { // 如果用户输入的数里有非数字字符,则视为非法数据,返回 false try { if (s.indexOf(".") == -1) { if (s.length() >= 13) { LogTools.debug("整数位大于11位"); return false; } } else { int fractionDigits = s.length() - s.indexOf(".") - 1; if (s.indexOf(".") >= 13) { LogTools.debug("整数位大于11位"); return false; } else if (fractionDigits > 2) { LogTools.debug("小数位多于两位。"); return false; } } Double.valueOf(s); return true; } catch (NumberFormatException e) { LogTools.debug("非法数据,请检查!"); return false; } } }