【Java】将数字转为汉字(中国钱币-数字转汉字)

今天做了一个题,需要把数字转为汉字,想了一段时间没有结果,于是在网上搜索出了如下方法:

  1 package com.b510.number2char;
  2
  3 import java.math.BigDecimal;
  4
  5 /**
  6  * 数字转换为汉语中人民币的大写<br>
  7  *
  8  * @author hongten
  9  * @contact [email protected]
 10  * @create 2013-08-13
 11  */
 12 public class NumberToCN {
 13     /**
 14      * 汉语中数字大写
 15      */
 16     private static final String[] CN_UPPER_NUMBER = { "零", "壹", "贰", "叁", "肆",
 17             "伍", "陆", "柒", "捌", "玖" };
 18     /**
 19      * 汉语中货币单位大写,这样的设计类似于占位符
 20      */
 21     private static final String[] CN_UPPER_MONETRAY_UNIT = { "分", "角", "元",
 22             "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿", "拾", "佰", "仟", "兆", "拾",
 23             "佰", "仟" };
 24     /**
 25      * 特殊字符:整
 26      */
 27     private static final String CN_FULL = "整";
 28     /**
 29      * 特殊字符:负
 30      */
 31     private static final String CN_NEGATIVE = "负";
 32     /**
 33      * 金额的精度,默认值为2
 34      */
 35     private static final int MONEY_PRECISION = 2;
 36     /**
 37      * 特殊字符:零元整
 38      */
 39     private static final String CN_ZEOR_FULL = "零元" + CN_FULL;
 40
 41     /**
 42      * 把输入的金额转换为汉语中人民币的大写
 43      *
 44      * @param numberOfMoney
 45      *            输入的金额
 46      * @return 对应的汉语大写
 47      */
 48     public static String number2CNMontrayUnit(BigDecimal numberOfMoney) {
 49         StringBuffer sb = new StringBuffer();
 50         // -1, 0, or 1 as the value of this BigDecimal is negative, zero, or
 51         // positive.
 52         int signum = numberOfMoney.signum();
 53         // 零元整的情况
 54         if (signum == 0) {
 55             return CN_ZEOR_FULL;
 56         }
 57         //这里会进行金额的四舍五入
 58         long number = numberOfMoney.movePointRight(MONEY_PRECISION)
 59                 .setScale(0, 4).abs().longValue();
 60         // 得到小数点后两位值
 61         long scale = number % 100;
 62         int numUnit = 0;
 63         int numIndex = 0;
 64         boolean getZero = false;
 65         // 判断最后两位数,一共有四中情况:00 = 0, 01 = 1, 10, 11
 66         if (!(scale > 0)) {
 67             numIndex = 2;
 68             number = number / 100;
 69             getZero = true;
 70         }
 71         if ((scale > 0) && (!(scale % 10 > 0))) {
 72             numIndex = 1;
 73             number = number / 10;
 74             getZero = true;
 75         }
 76         int zeroSize = 0;
 77         while (true) {
 78             if (number <= 0) {
 79                 break;
 80             }
 81             // 每次获取到最后一个数
 82             numUnit = (int) (number % 10);
 83             if (numUnit > 0) {
 84                 if ((numIndex == 9) && (zeroSize >= 3)) {
 85                     sb.insert(0, CN_UPPER_MONETRAY_UNIT[6]);
 86                 }
 87                 if ((numIndex == 13) && (zeroSize >= 3)) {
 88                     sb.insert(0, CN_UPPER_MONETRAY_UNIT[10]);
 89                 }
 90                 sb.insert(0, CN_UPPER_MONETRAY_UNIT[numIndex]);
 91                 sb.insert(0, CN_UPPER_NUMBER[numUnit]);
 92                 getZero = false;
 93                 zeroSize = 0;
 94             } else {
 95                 ++zeroSize;
 96                 if (!(getZero)) {
 97                     sb.insert(0, CN_UPPER_NUMBER[numUnit]);
 98                 }
 99                 if (numIndex == 2) {
100                     if (number > 0) {
101                         sb.insert(0, CN_UPPER_MONETRAY_UNIT[numIndex]);
102                     }
103                 } else if (((numIndex - 2) % 4 == 0) && (number % 1000 > 0)) {
104                     sb.insert(0, CN_UPPER_MONETRAY_UNIT[numIndex]);
105                 }
106                 getZero = true;
107             }
108             // 让number每次都去掉最后一个数
109             number = number / 10;
110             ++numIndex;
111         }
112         // 如果signum == -1,则说明输入的数字为负数,就在最前面追加特殊字符:负
113         if (signum == -1) {
114             sb.insert(0, CN_NEGATIVE);
115         }
116         // 输入的数字小数点后两位为"00"的情况,则要在最后追加特殊字符:整
117         if (!(scale > 0)) {
118             sb.append(CN_FULL);
119         }
120         return sb.toString();
121     }
122
123     public static void main(String[] args) {
124         double money = 2020004.01;
125         BigDecimal numberOfMoney = new BigDecimal(money);
126         String s = NumberToCN.number2CNMontrayUnit(numberOfMoney);
127         System.out.println("你输入的金额为:【"+ money +"】   #--# [" +s.toString()+"]");
128     }
129 }

非常感谢:http://www.cnblogs.com/hongten/p/hongten_java_money.html提供的参考

如下是按照自己的理解写的类似方法:

  1 package com.numbertoch;
  2
  3 import java.math.BigDecimal;
  4
  5 /**
  6  * @author simon - zhou
  7  * @version v1.0
  8  */
  9 public class NumberToBigCh
 10 {
 11     /**
 12      * 汉语中数字大写
 13      */
 14     private static final String[] CN_UPPER_NUMBER = { "零", "壹", "贰", "叁", "肆",
 15             "伍", "陆", "柒", "捌", "玖" };
 16     /**
 17      * 汉语中货币单位大写,这样的设计类似于占位符
 18      */
 19     private static final String[] CN_UPPER_MONETRAY_UNIT = { "分", "角", "元",
 20             "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿", "拾", "佰", "仟", "兆", "拾",
 21             "佰", "仟" };
 22     /**
 23      * 特殊字符:整
 24      */
 25     private static final String CN_FULL = "整";
 26     /**
 27      * 特殊字符:负
 28      */
 29     private static final String CN_NEGATIVE = "负";
 30     /**
 31      * 金额的精度,默认值为2
 32      */
 33     private static final int MONEY_PRECISION = 2;
 34     /**
 35      * 特殊字符:零元整
 36      */
 37     private static final String CN_ZEOR_FULL = "零元" + CN_FULL;
 38
 39     /**
 40      * 把输入的金额转换为汉语中人民币的大写
 41      *
 42      * @param numberOfMoney
 43      *            输入的金额
 44      * @return 对应的汉语大写
 45      */
 46     public static String number2CNMontrayUnit1(BigDecimal numberOfMoney)
 47     {
 48         StringBuffer sb = new StringBuffer();
 49         // 判断这个数字是整数 负数 或者 0 : 1 -1 0
 50         int signum = numberOfMoney.signum();
 51         // 零元整的情况
 52         if (signum == 0)
 53         {
 54             return CN_ZEOR_FULL;
 55         }
 56         // 向右移动2位后,按照四舍五入的精度保留0位,并转为long类型
 57         // 这样移动位置,似乎有bug存在
 58         long number = numberOfMoney.movePointRight(MONEY_PRECISION)
 59                 .setScale(0, 4).abs().longValue();
 60         // 得到小数点后两位值
 61         long scale = number % 100;
 62         System.out.println(240 % 100);
 63         System.out.println(scale);
 64         // 以下处理的是不包含小数的内容
 65         number = number / 100;
 66         String str = "" + number;
 67         System.out.println(str);
 68         long nowNum = 0;
 69         boolean haveZero = false;
 70         // 20200004.01
 71         for (int i = 0; i < str.length(); i++)
 72         {
 73             nowNum = number % 10;
 74             // 如果这个当前位的数字大于0,则添加数字和单位
 75             if (nowNum > 0)
 76             {
 77                 sb.insert(0, CN_UPPER_MONETRAY_UNIT[i + 2]);
 78                 sb.insert(0, CN_UPPER_NUMBER[(int) nowNum]);
 79                 // 本次不是零,则打开零的开关,允许下一次添零
 80                 haveZero = false;
 81             }
 82             else
 83             {
 84                 sb.insert(0, CN_UPPER_NUMBER[0]);
 85                 // 添加零,但是不添加单位 - 如果前面已经添加过零,则不添加
 86                 if (haveZero)
 87                 {
 88                     sb = new StringBuffer(sb.substring(1));
 89                 }
 90                 // 记录本次是零 - 放在else的最后
 91                 haveZero = true;
 92                 // 如果是元,万,亿,兆,则可以添加零
 93                 if (i % 4 == 0)
 94                 {
 95                     // 由于是元,万,亿,兆,所以去掉前面的零,并添加单位
 96                     sb.insert(0, CN_UPPER_MONETRAY_UNIT[i + 2]);
 97                     // 由于下四位和上四位单位不一致,所以上四位可以添加零
 98                     haveZero = false;
 99                 }
100                 //System.out.println(sb.toString());
101             }
102             number = number / 10;
103         }
104         String lastNum = sb.toString();
105         String lastChar = lastNum.substring(lastNum.length() - 1);
106         //System.out.println(lastChar);
107         if (lastChar.equals(CN_UPPER_NUMBER[0]))
108         {
109             sb = new StringBuffer(sb.substring(0, lastNum.length() - 1));
110         }
111         //System.out.println(sb.toString());
112         // 替换特殊的情况
113         sb = new StringBuffer(sb.toString().replaceAll("零元", ""));
114         sb = new StringBuffer(sb.toString().replaceAll("零万", ""));
115         sb = new StringBuffer(sb.toString().replaceAll("零亿", ""));
116         sb = new StringBuffer(sb.toString().replaceAll("零兆", ""));
117         // 如果signum == -1,则说明输入的数字为负数,就在最前面追加特殊字符:负
118         if (signum == -1)
119         {
120             sb.insert(0, CN_NEGATIVE);
121         }
122         StringBuffer sb2 = new StringBuffer();
123         // 处理小数位
124         // 输入的数字小数点后两位为"00"的情况,则要在最后追加特殊字符:整
125         if (!(scale > 0)) {
126             sb2.append(CN_FULL);
127         }
128         //
129         if (scale % 10 > 0)
130         {
131             sb2.insert(0, CN_UPPER_MONETRAY_UNIT[0]);
132             sb2.insert(0, CN_UPPER_NUMBER[(int) (scale % 10)]);
133         }
134         if (scale / 10 > 0)
135         {
136             sb2.insert(0, CN_UPPER_MONETRAY_UNIT[1]);
137             sb2.insert(0, CN_UPPER_NUMBER[(int) (scale / 10)]);
138         }
139         if (scale / 10 == 0 && scale % 10 > 0)
140         {
141             sb2.insert(0, CN_UPPER_NUMBER[0]);
142         }
143         sb.append(sb2.toString());
144         return sb.toString();
145     }
146
147     public static void main(String[] args)
148     {
149         // 约束条件:小数点后至少2位
150         System.out.println(NumberToBigCh.number2CNMontrayUnit1(new BigDecimal(6202000000202.0199)));
151         System.out.println(NumberToBigCh.number2CNMontrayUnit1(new BigDecimal(6202000000202.2199)));
152         System.out.println(NumberToBigCh.number2CNMontrayUnit1(new BigDecimal(6202000000200.4099)));
153         System.out.println(NumberToBigCh.number2CNMontrayUnit1(new BigDecimal(36202004500202.0199)));
154         System.out.println(NumberToBigCh.number2CNMontrayUnit1(new BigDecimal(26000000000202.0199)));
155         System.out.println(NumberToBigCh.number2CNMontrayUnit1(new BigDecimal(26000000000202.00)));
156         System.out.println(NumberToBigCh.number2CNMontrayUnit1(new BigDecimal(26000000000202.401)));
157         System.out.println(NumberToBigCh.number2CNMontrayUnit1(new BigDecimal(26000000000202.001)));
158         System.out.println(NumberToBigCh.number2CNMontrayUnit1(new BigDecimal(26000000000202.011)));
159     }
160 }

附上测试的运行结果:

由于本人思维不是很强,又不喜欢用while循环,平时通常就用用for循环,用用if之类的,就连else if都看着不舒服。所以代码很拙劣,请谅解。

时间: 2024-10-05 06:15:22

【Java】将数字转为汉字(中国钱币-数字转汉字)的相关文章

剑指Offer面试题8(java版):旋转数组的最小数字

题目: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为旋转. 输入一个递增的排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小元素为1. 这道题最直观的解法并不难,从头到尾遍历一次,我们就能找到最小的元素.这种思路的时间复杂度为O(n).但是这个思路没有利用输入的旋转数组的特性,肯定达不到面试官的要求. 我们注意到旋转之后的数组实际上可以划分为两个排序的子数组,而且前面的子数组的元素都是大于或者等于后面子数组的元

用vue将数字转为中文大写金额

记得引入vue.js文件 <html lang="en"> <head> <meta charset="UTF-8"> <title>用vue将数字转为中文大写金额</title> <script src='vue.js'></script> </head> <body> <div id="box"> <h1 v-if='

PHP中数字转为百分位,千分位,万分位。。。

今天做项目中,需要将文章点击量显示在页面中,需求中给的是多少多少万,虽然不是什么难事,但做程序员这么久了,需要考虑的不再是简单的实现,而且有效率和快捷, 虽然PHP自带的函数有number_format()可以做到实现千分位,但我要的是万分位, 通过查找,发现了可以用以下这个方法: $num = 86231; # 将数字转为万分位 echo $num>10000?sprintf("%.1f", $num/10000):$num; 类似的通过这个方法,可以稍微修改下,就可以实现百分

java 用Arrays.binarySearch解读 快速定位数字范围

在一些时候,需要用给一个数字找到适合的区间,Arrays.binarySearch可达到这个目的. static int binarySearch(int[] a, int key)           Searches the specified array of ints for the specified value using the binary search algorithm. import java.util.Arrays; public class Test { public 

java python oracle判断字符串是否为数字的函数

java public boolean isNumeric(String str){ Pattern pattern = Pattern.compile("^-?[0-9]+\\.?[0-9]+"); Matcher isNum = pattern.matcher(str); if( !isNum.matches() ){ return false; } return true; } python def isNum(value): try: int(value) + 1 except

java实现——008旋转数组的最小数字

1 public class T008 { 2 public static void main(String[] args) { 3 int[] num = { 3, 4, 5, 1, 2 }; 4 System.out.println(min(num, 5)); 5 } 6 public static int min(int num[], int len) { 7 if (num == null || len <= 0) { 8 System.out.println("invalid&q

velocity 将数字转为以万为单位,保留2位小数

$count = 123456789  -- 将数字转为以万为单位,保留2位小数 #set($per_count = ($count/100))   --  $count/100 返回值为 1234567 #set($per_count = ($count/100.00)) -- $count/100.00 返回值为 12345.67 $per_count 万

C# 之 Excel 导入一列中既有汉字又有数字:数字可以正常导入,汉字导入为空

今天在做一个Excel导入功能,一切开发就绪,数据可以成功导入.导入后检查数据库发现有一列既有汉字又有数字,数字正常导入,汉字为空.但是前面同样既有汉字又有数字的列可以导入成功. 查看excel 源文件,如下图: 仔细观察两列略有不同,前两列的数字单元格左上角有个绿色三角形,选中单元格,左边有一个信息显示“ 次单元格中的数字为文本形式,或者前面有撇号. ”,也就是 “ 以文本形式存储的数字 ”. 然后尝试选中内容列,右键设置单元格格式为“ 文本 ”,修改后如下图: 再次导入仍然失败,单元格左上角

剑指Offer(Java版)第四十题:在数组中的两个数字,如果前面一个数字大于后面的数字, 则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。 并将P对1000000007取模的结果输出。 即输出P%1000000007

/*在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数P.并将P对1000000007取模的结果输出. 即输出P%1000000007 */ import java.util.*; public class Class40 { public int InversePairs(int[] array){ int length = array.length; int P = 0; for(int i = 0; i < lengt