本⼈是从事互联⽹⾦融⾏业的,所以会接触到⼀些⾦融类的问题,常见的⼀种就是数字转汉字⼤⼩写的问题。所以抽空就写了⼀个⼩⼩的⼯具类,实现了数字转汉字、⼤数相加、相减、相乘的⼯具类,希望能帮助有需求的同⾏们。本篇就分享⼀下数字转化为汉字的思路吧。
数字转汉字的原理:
拆分:由于整数部分要加权值,⽽⼩数部分直接转换即可,所以⾸先要将数字拆分成整数+⼩数;
整数处理:按照我们的中国⼈的习惯,把数字格式化成4位⼀组,不⾜4位前⾯补0。每次处理4位,按位匹配数组中的汉字+权值。即按照数值找数字数组(num_lower 、num_upper )中对应位置的汉字,按照在4位中的偏移量在单位权值数组
(unit_lower 、unit_upper )中找。⽐如21,转化4位为0021,前⾯的0不⽤管,2对应数字“⼆”,权值是“⼗”,1对应数字“⼀”,权值是“(个)”⽤空字符串代替。即得到“⼆⼗⼀”。每4位处理完后,还要整体对应⼀个权值,⽐如“万、亿、兆”等;⼩数处理:⼩数部分直接按位对应汉字数组和权值即可。废话了这么多,可能云⾥雾⾥的,看看具体代码吧:
//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 * 数字转化为⼩写的汉字 * * @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 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]+\"\ 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|\\\\.|\\\\-|\\\\+]\ throw new RuntimeException(\"数字[\"+num+\"]格式不正确!\"); } } 通过这种分⽽治之的思路,处理起来就简单多了。写个main函数调⽤⼀下: 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\ 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(\"\\"); } //调⽤转化为⼩写和⼤写 System.out.print(\" format:\"+toChineseLower(num)); System.out.println(\"【\"+toChineseUpper(num)+\"】\"); }catch(Exception e){ System.out.println(\" 错误信息:\"+e.getMessage()); } } } 看看结果吧: 从上述代码和运⾏结果中,我们可以看到该功能⽀持多种数据类型的转换、⽀持转化为⼀般汉字和财务专⽤⼤写汉字。还可以智能处理⾮正常逻辑的数字。⽐如“20”会转化为“⼆⼗”⽽⾮“⼆⼗零”;“1 0000 0001” 转换成“⼀亿零⼀”⽽⾮“⼀亿零万零⼀”。这⾥只分享了⼀个转换汉字的功能,下篇将分享⼀下⼤数相乘、相加、相减的⽅法。⽀持⼩数和负数的运算,敬请期待。以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。 因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- 69lv.com 版权所有 湘ICP备2023021910号-1
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务