实习单位的数字的处理的类


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;
		}
	}
}

你可能感兴趣的:(框架,log4j,J#,UP)