数字转化为汉字

package com.dsw.zfjd.utils;

import java.util.Arrays;
import java.util.List;

public class NumberToChinese {
    // num 表示数字,lower表示小写,upper表示大写
    private static final String[] num_lower = { "零", "一", "二", "三", "四", "五", "六", "七", "八", "九" };
    private static final String[] num_upper = { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" };

    // unit 表示单位权值,lower表示小写,upper表示大写
    private static final String[] unit_lower = { "", "十", "百", "千" };
    private static final String[] unit_upper = { "", "拾", "佰", "仟" };
    private static final String[] unit_common = { "", "万", "亿", "兆", "京", "垓", "秭", "穰", "沟", "涧", "正", "载" };

    // 允许的格式
    private static final List<String> promissTypes = Arrays.asList("INTEGER", "INT", "LONG", "DECIMAL", "FLOAT",
            "DOUBLE", "STRING", "BYTE", "TYPE", "SHORT");

    /**
     * 数字转化为小写的汉字
     * 
     * @param num
     *            将要转化的数字
     * @return
     */
    public static String toChineseLower(Object num) {
        return format(num, num_lower, unit_lower);
    }

    /**
     * 数字转化为大写的汉字
     * 
     * @param num
     *            将要转化的数字
     * @return
     */
    public static String toChineseUpper(Object num) {
        return format(num, num_upper, unit_upper);
    }

    /**
     * 格式化数字
     * 
     * @param num
     *            原数字
     * @param numArray
     *            数字大小写数组
     * @param unit
     *            单位权值
     * @return
     */
    private static String format(Object num, String[] numArray, String[] unit) {
        if (!promissTypes.contains(num.getClass().getSimpleName().toUpperCase())) {
            throw new RuntimeException("不支持的格式类型");
        }
        // 获取整数部分
        String intnum = getInt(String.valueOf(num));
        // 获取小数部分
        String decimal = getFraction(String.valueOf(num));
        // 格式化整数部分
        String result = formatIntPart(intnum, numArray, unit);
        if (!"".equals(decimal)) {// 小数部分不为空
            // 格式化小数
            result += "点" + formatFractionalPart(decimal, numArray);
        }
        return result;
    }

    /**
     * 格式化整数部分
     * 
     * @param num
     *            整数部分
     * @param numArray
     *            数字大小写数组
     * @return
     */
    private static String formatIntPart(String num, String[] numArray, String[] unit) {

        // 按4位分割成不同的组(不足四位的前面补0)
        Integer[] intnums = split2IntArray(num);

        boolean zero = false;
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < intnums.length; i++) {
            // 格式化当前4位
            String r = formatInt(intnums[i], numArray, unit);
            if ("".equals(r)) {//
                if ((i + 1) == intnums.length) {
                    sb.append(numArray[0]);// 结果中追加“零”
                } else {
                    zero = true;
                }
            } else {// 当前4位格式化结果不为空(即不为0)
                if (zero || (i > 0 && intnums[i] < 1000)) {// 如果前4位为0,当前4位不为0
                    sb.append(numArray[0]);// 结果中追加“零”
                }
                sb.append(r);
                sb.append(unit_common[intnums.length - 1 - i]);// 在结果中添加权值
                zero = false;
            }
        }
        return sb.toString();
    }

    /**
     * 格式化小数部分
     * 
     * @param decimal
     *            小数部分
     * @param numArray
     *            数字大小写数组
     * @return
     */
    private static String formatFractionalPart(String decimal, String[] numArray) {
        char[] val = String.valueOf(decimal).toCharArray();
        int len = val.length;
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < len; i++) {
            int n = Integer.valueOf(val[i] + "");
            sb.append(numArray[n]);
        }
        return sb.toString();
    }

    /**
     * 获取整数部分
     * 
     * @param num
     * @return
     */
    private static String getInt(String num) {
        // 检查格式
        checkNum(num);

        char[] val = String.valueOf(num).toCharArray();
        StringBuffer sb = new StringBuffer();
        int t, s = 0;
        for (int i = 0; i < val.length; i++) {
            if (val[i] == '.') {
                break;
            }
            t = Integer.parseInt(val[i] + "", 16);
            if (s + t == 0) {
                continue;
            }
            sb.append(t);
            s += t;
        }
        return (sb.length() == 0 ? "0" : sb.toString());
    }

    /**
     * 获取小数部分
     * 
     * @param num
     * @return
     */
    private static String getFraction(String num) {
        int i = num.lastIndexOf(".");
        if (num.indexOf(".") != i) {
            throw new RuntimeException("数字格式不正确,最多只能有一位小数点!");
        }
        String fraction = "";
        if (i >= 0) {
            fraction = getInt(new StringBuffer(num).reverse().toString());
            if (fraction.equals("0")) {
                return "";
            }
        }
        return new StringBuffer(fraction).reverse().toString();
    }

    /**
     * 检查数字格式
     * 
     * @param num
     */
    private static void checkNum(String num) {
        if (num.indexOf(".") != num.lastIndexOf(".")) {
            throw new RuntimeException("数字[" + num + "]格式不正确!");
        }
        if (num.indexOf("-") != num.lastIndexOf("-") || num.lastIndexOf("-") > 0) {
            throw new RuntimeException("数字[" + num + "]格式不正确!");
        }
        if (num.indexOf("+") != num.lastIndexOf("+")) {
            throw new RuntimeException("数字[" + num + "]格式不正确!");
        }
        if (num.indexOf("+") != num.lastIndexOf("+")) {
            throw new RuntimeException("数字[" + num + "]格式不正确!");
        }
        if (num.replaceAll("[\\d|\\.|\\-|\\+]", "").length() > 0) {
            throw new RuntimeException("数字[" + num + "]格式不正确!");
        }
    }
    
    /**
     * 分割数字,每4位一组
     * 
     * @param num
     * @return
     */
    private static Integer[] split2IntArray(String num) {
        String prev = num.substring(0, num.length() % 4);
        String stuff = num.substring(num.length() % 4);
        if (!"".equals(prev)) {
            num = String.format("%04d", Integer.valueOf(prev)) + stuff;
        }
        Integer[] ints = new Integer[num.length() / 4];
        int idx = 0;
        for (int i = 0; i < num.length(); i += 4) {
            String n = num.substring(i, i + 4);
            ints[idx++] = Integer.valueOf(n);
        }
        return ints;
    }
    
    /**
     * 格式化4位整数
     * 
     * @param num
     * @param numArray
     * @return
     */
    private static String formatInt(int num, String[] numArray, String[] unit) {
        char[] val = String.valueOf(num).toCharArray();
        int len = val.length;
        StringBuilder sb = new StringBuilder();
        boolean isZero = false;
        for (int i = 0; i < len; i++) {
            int n = Integer.valueOf(val[i] + "");// 获取当前位的数值
            if (n == 0) {
                isZero = true;
            } else {
                if (isZero) {
                    sb.append(numArray[Integer.valueOf(val[i - 1] + "")]);
                }
                sb.append(numArray[n]);
                sb.append(unit[(len - 1) - i]);
                isZero = false;
            }
        }
        return sb.toString();
    }
    
    public static void main(String[] args) {
        short s = 10;
        byte b = 10;
        char c = 'A';
        Object[] nums = { s, b, c, 0, 1001, 100100001L, 21., 205.23F, 205.23D, "01000010", "1000000100105.0123", ".142",
                "20.00", "1..2", true };
        System.out.println("将任意数字转化为汉字(包括整数、小数以及各种类型的数字)");
        System.out.println("--------------------------------------------");
        for (Object num : nums) {
            try {
                System.out.print("[" + num.getClass().getSimpleName() + "]" + num);
                for (int i = 0; i < 25 - String.valueOf(num + num.getClass().getSimpleName()).length(); i += 4) {
                    System.out.print("\t");
                }
                // 调用转化为小写和大写
                System.out.print(" format:" + toChineseLower(num));
                System.out.println("【" + toChineseUpper(num) + "】");
            } catch (Exception e) {
                System.out.println(" 错误信息:" + e.getMessage());
            }
        }
    }
}
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值