目录
- 1正常代码逻辑处理
- 2使用正则
- 总结
一般在收据打印过程中,可能会要求展示中文大写金额,以下提供两种实现。
1正常代码逻辑处理
优点:易理解,好维护
缺点:代码较长
package com.test; import Java.math.BigDecimal; public class NumberToChinese { private static final String[] NUMBERS = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"}; private static final String[] UNITS = {"", "拾", "佰", "仟"}; private static final String[] BIG_UNITS = {"", "万", "亿", "兆"}; public static String numberToChinese(double number) { boolean isNegative = number < 0; number = Math.abs(number); BigDecimal bigDecimal = new BigDecimal(String.valueOf(number)); long integerPart = bigDecimal.longValue(); int decimalPart = (bigDecimal.subtract(new BigDecimal(integerPart)).multiply(new BigDecimal(100))).intValue(); if (integerPart == 0 && decimalPart == 0) { return isNegative ? "负零元整" : "零元整"; } StringBuilder result = new StringBuilder(); int unitIndex = 0; luYCTNfLbLboolean zeroFlag = false; while (integerPart > 0) { long group = integerPart % 10000; if (group != 0) { if (zeroFlag) { result.insert(0, "零"); } result.insert(0, BIG_UNITS[unitIndex]); result.insert(0, groupToChinese(group)); zeroFlag = false; } else { zeroFlag = true; } integerPart /= 10000; unitIndex++; } // 去除多余的零 while (result.length() > 0 && result.charAt(0) == '零') { result.deleteCharAt(0); } // 如果小数部分为 0,直接添加“元整” if (decimalPart == 0) { // 避免出现“零元整”情况,这里判断结果最后是否是大单位,如果是直接加“整” if (result.length() > 0 && isBigUnit(result.charAt(result.length() - 1))) { result.append("整"); } else if("零".equals(result.substring(result.length() - 1,result.length()))) { result.replace(result.length() - 1,result.length(),"").append("元整"); }else{ result.append("元整"); } } else { result.append("元"); Strjsing decimalStr = decimalToChinese(decimalPart); if (!decimalStr.isEmpty()) { result.append(decimalStr); } } ifjs (isNegative) { result.insert(0, "负"); } return result.toString(); } private static String groupToChinese(long group) { StringBuilder groupResult = new StringBuilder(); boolean zeroFlag = false; for (int i = 0; i < 4; i++) { int digit = (int) (group / (long) Math.pow(10, 3 - i) % 10); if (digit != 0) { if (zeroFlag) { groupResult.append("零"); } groupResult.append(NUMBERS[digit]).append(UNITS[3 - i]); zeroFlag = false; } else { zeroFlag = true; } } String result = groupResult.toString(); if (result.endsWith("零")) { result = result.substring(0, result.length() - 1); } return result; } private static String decimalToChinese(int decimalPart) { StringBuilder decimalResult = new StringBuilder(); int jiao = decimalPart / 10; int fen = decimalPart % 10; if (jiao != 0) { decimalResult.append(NUMBERS[jiao]).append("角"); } else if (fen != 0) { decimalResult.append("零"); } if (fen != 0) { decimalResult.append(NUMBERS[fen]).append("分"); } return decimalResult.toString(); } private static boolean isBigUnit(char c) { for (String unit : BIG_UNITS) { if (unit.length() > 0 && unit.charAt(0) == c) { return true; } } return false; } public static void main(String[] args) { double positiveInteger = 510000.00; double positiveDecimal = 12345.67; double negativeInteger = -500000.00; double negativeDecimal = -12345.67; double zeroNumber = 0; double wan = 51111.00; String positiveIntegerChinese = numberToChinese(positiveInteger); String positiveDecimalChinese = numberToChinese(positiveDecimal); String negativeIntegerChinese = numberToChinese(negativeInteger); String negativeDecimalChinese = numberToChinese(negativeDecimal); String zeroChinese = numberToChinese(zeroNumber); String wanChinese = numberToChinese(wan); System.out.println("正整数金额转换结果: " + positiveIntegerChinese); System.out.println("正小数金额转换结果: " + positiveDecimalChinese); System.out.println("负整数金额转换结果: " + negativeInteandroidgerChinese); System.out.println("负小数金额转换结果: " + negativeDecimalChinese); System.out.println("零金额转换结果: " + zeroChinese); System.out.println("wan转换结果: " + wanChinese); } }
代码方法作用解释:
常量定义:
NUMBERS
:存储中文数字大写字符。UNITS
:存储整数部分每四位一组内的单位(个、十、百、千)。BIG_UNITS
:存储整数部分每四位一组的大单位(万、亿、兆)。DECIMAL_UNIT
:存储小数部分的单位(角、分)。
numberToChinese 方法:
- 使用
BigDecimal
处理输入的数字,避免浮点数精度问题。 - 分离整数部分和小数部分。
- 处理整数部分,按每四位一组进行转换,并添加大单位。
- 处理小数部分,根据小数位的值添加对应的中文大写和单位。
- 使用
groupToChinese 方法:
- 将每四位一组的数字转换为中文大写。
- 处理连续零的情况,避免出现多余的零。
2使用正则
优点:代码片段短
缺点:使用了正则的贪婪符号,可能会造成代码回溯情况,严重可造成阻断风险
关于正则常见贪婪字符,点击查看
public static String digitUppercase(double n){ String[] fraction = {"角", "分"}; String[] digit = { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" }; String[][] unit = { luYCTNfLbL {"元", "万", "亿"}, {"", "拾", "佰", "仟"}}; String head = n < 0? "负": ""; n = Math.abs(n); String s = ""; for (int i = 0; i < fraction.length; i++) { BigDecimal bd = BigDecimal.valueOf(n); bd = bd.setScale(2, bd.ROUND_HALF_EVEN); BigDecimal rs = bd.multiply(BigDecimal.valueOf(10)).multiply(BigDecimal.valueOf(Math.pow(10, i))).divideAndRemainder(new BigDecimal(10))[1]; s+=(digit[(int)(Math.floor(rs.doubleValue()))]+ fraction[i]).replaceAll("(零.)+", ""); } if(s.length()<1){ s = "整"; } int integerPart = (int)Math.floor(n); for (int i = 0; i < unit[0].length && integerPart > 0; i++) { String p =""; for (int j = 0; j < unit[1].length && n > 0; j++) { p = digit[integerPart%10]+unit[1][j] + p; integerPart = integerPart/10; } s = p.replaceAll("(零.)*零$", "").replaceAll("^$", "零") + unit[0][i] + s; } return head + s.replaceAll("(零.)*零元", "元").replaceFirst("(零.)+", "").replaceAll("(零.)+", "零").replaceAll("^整$", "零元整"); }
总结
到此这篇关于JAVA数字转中文大写两种实现代码的文章就介绍到这了,更多相关JAVA数字转中文大写内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!
精彩评论