数字转换成汉字金额(转)

ContractedBlock.gif ExpandedBlockStart.gif Code
  1 
  2 
  3 //测试工程
  4 
  5   static void Main(string[] args)
  6 
  7 {
  8 
  9 Console.WriteLine("请输入金额");
 10 
 11 string inputNum = Console.ReadLine();
 12 
 13 while (inputNum != "exit")
 14 
 15 {
 16 
 17 //货币数字转化类
 18 
 19 NumCast nc = new NumCast();
 20 
 21 if (nc.IsValidated<string>(inputNum))
 22 
 23 {
 24 
 25 try
 26 
 27 {
 28 
 29 string chineseCharacter = nc.ConvertToChinese(inputNum);
 30 
 31 Console.WriteLine(chineseCharacter);
 32 
 33 }
 34 
 35 catch (Exception er)
 36 
 37 {
 38 
 39 Console.WriteLine(er.Message);
 40 
 41 }
 42 
 43 }
 44 
 45 else
 46 
 47 {
 48 
 49 Console.WriteLine("不合法的数字或格式");
 50 
 51 }
 52 
 53 Console.WriteLine("\n请输入金额");
 54 
 55 inputNum = Console.ReadLine();
 56 
 57 }
 58 
 59 Console.ReadLine();
 60 
 61 }
 62 
 63 测试结果如下:
 64 
 65 货币转化类(NumCast类)功能介绍
 66 
 67 1 常量的规定
 68 
 69  /// 
 70 
 71 /// 数位
 72 
 73 /// 

 74 
 75 public enum NumLevel { Cent, Chiao, Yuan, Ten, Hundred, Thousand, TenThousand, hundredMillon, Trillion };
 76 
 77 /// 
 78 
 79 /// 数位的指数
 80 
 81 /// 

 82 
 83 private int[] NumLevelExponent = new int[] { -2-101234812 };
 84 
 85 /// 
 86 
 87 /// 数位的中文字符
 88 
 89 /// 

 90 
 91 private string[] NumLeverChineseSign = new string[] { """""""""""""""亿""" };
 92 
 93 /// 
 94 
 95 /// 大写字符
 96 
 97 /// 

 98 
 99 private string[] NumChineseCharacter = new string[] {"","","","","","","","","",""};
100 
101 /// 
102 
103 /// 整(当没有 角分 时)
104 
105 /// 

106 
107 private const string EndOfInt = "";
108 
109 2:数字合法性验证,采用正则表达式验证
110 
111  /// 
112 
113 /// 正则表达验证数字是否合法
114 
115 /// 

116 
117 /// 
118 
119 /// 
120 
121 public bool IsValidated<T>(T Num)
122 
123 {
124 
125 Regex reg = new Regex(@"^(([0])|([1-9]\d{0,23}))(\.\d{1,2})?$");
126 
127 if (reg.IsMatch(Num.ToString()))
128 
129 {
130 
131 return true;
132 
133 }
134 
135 return false;
136 
137 }
138 
139 3: 获取数位 例如 1000的数位为 NumLevel.Thousand
140 
141  
142 
143 /// 
144 
145 /// 获取数字的数位 使用log
146 
147 /// 

148 
149 /// 
150 
151 /// 
152 
153 private NumLevel GetNumLevel(double Num)
154 
155 {
156 
157 double numLevelLength;
158 
159 NumLevel NLvl = new NumLevel();
160 
161 if (Num > 0)
162 
163 {
164 
165 numLevelLength = Math.Floor(Math.Log10(Num));
166 
167 for (int i = NumLevelExponent.Length - 1; i >= 0; i--)
168 
169 {
170 
171 if (numLevelLength >= NumLevelExponent[i])
172 
173 {
174 
175 NLvl = (NumLevel)i;
176 
177 break;
178 
179 }
180 
181 }
182 
183 }
184 
185 else
186 
187 {
188 
189 NLvl = NumLevel.Yuan;
190 
191 }
192 
193 return NLvl;
194 
195 }
196 
197 4:判断数字之间是否有跳位,也就是中文中间是否要加零,例如1020 就应该加零。
198 
199  /// 
200 
201 /// 是否跳位
202 
203 /// 

204 
205 /// 
206 
207 private bool IsDumpLevel(double Num)
208 
209 {
210 
211  if (Num > 0)
212 
213 {
214 
215 NumLevel? currentLevel = GetNumLevel(Num);
216 
217 NumLevel? nextLevel = null;
218 
219 int numExponent = this.NumLevelExponent[(int)currentLevel];
220 
221 double postfixNun = Math.Round(Num % (Math.Pow(10, numExponent)),2);
222 
223 if(postfixNun> 0)
224 
225 nextLevel = GetNumLevel(postfixNun);
226 
227 if (currentLevel != null && nextLevel != null)
228 
229 {
230 
231 if (currentLevel > nextLevel + 1)
232 
233 {
234 
235 return true;
236 
237 }
238 
239 }
240 
241 }
242 
243 return false;
244 
245 }
246 
247 5 把长数字分割为两个较小的数字数组,例如把9999亿兆,分割为9999亿和0兆,
248 
249 因为计算机不支持过长的数字。
250 
251  /// 
252 
253 /// 是否大于兆,如果大于就把字符串分为两部分,
254 
255 /// 一部分是兆以前的数字
256 
257 /// 另一部分是兆以后的数字
258 
259 /// 

260 
261 /// 
262 
263 /// 
264 
265 private bool IsBigThanTillion(string Num)
266 
267 {
268 
269 bool isBig = false;
270 
271 if (Num.IndexOf('.'!= -1)
272 
273 {
274 
275 //如果大于兆
276 
277 if (Num.IndexOf('.'> NumLevelExponent[(int)NumLevel.Trillion])
278 
279 {
280 
281 isBig = true;
282 
283 }
284 
285 }
286 
287 else
288 
289 {
290 
291 //如果大于兆
292 
293 if (Num.Length > NumLevelExponent[(int)NumLevel.Trillion])
294 
295 {
296 
297 isBig = true;
298 
299 }
300 
301 }
302 
303 return isBig;
304 
305 }
306 
307 /// 
308 
309 /// 把数字字符串由‘兆’分开两个
310 
311 /// 

312 
313 /// 
314 
315 private double[] SplitNum(string Num)
316 
317 {
318 
319 //兆的开始位
320 
321 double[] TillionLevelNums = new double[2];
322 
323 int trillionLevelLength;
324 
325 if (Num.IndexOf('.'== -1)
326 
327 trillionLevelLength = Num.Length - NumLevelExponent[(int)NumLevel.Trillion];
328 
329 else
330 
331 trillionLevelLength = Num.IndexOf('.'- NumLevelExponent[(int)NumLevel.Trillion];
332 
333 //兆以上的数字
334 
335 TillionLevelNums[0= Convert.ToDouble(Num.Substring(0, trillionLevelLength));
336 
337 //兆以下的数字
338 
339 TillionLevelNums[1= Convert.ToDouble(Num.Substring(trillionLevelLength ));
340 
341 return TillionLevelNums;
342 
343 }
344 
345  
346 
347 6 是否以“壹拾”开头,如果是就可以把它变为“拾”
348 
349   bool isStartOfTen = false;
350 
351 while (Num >=10)
352 
353 {
354 
355 if (Num == 10)
356 
357 {
358 
359 isStartOfTen = true;
360 
361 break;
362 
363 }
364 
365 //Num的数位
366 
367  
368 NumLevel currentLevel = GetNumLevel(Num);
369 
370 int numExponent = this.NumLevelExponent[(int)currentLevel];
371 
372 Num = Convert.ToInt32(Math.Floor(Num / Math.Pow(10, numExponent)));
373 
374 if (currentLevel == NumLevel.Ten && Num == 1)
375 
376 {
377 
378 isStartOfTen = true;
379 
380 break;
381 
382 }
383 
384 }
385 
386 return isStartOfTen;
387 
388 7 合并大于兆连个数组转化成的货币字符串
389 
390 /// 
391 
392 /// 合并分开的数组中文货币字符
393 
394 /// 

395 
396 /// 
397 
398 /// 
399 
400 private string ContactNumChinese(double[] tillionNums)
401 
402 {
403 
404 string uptillionStr = CalculateChineseSign(tillionNums[0], NumLevel.Trillion, true, IsStartOfTen(tillionNums[0]));
405 
406 string downtrillionStr = CalculateChineseSign(tillionNums[1], nulltrue,false);
407 
408 string chineseCharactor = string.Empty;
409 
410 //分开后的字符是否有跳位
411 
412 if (GetNumLevel(tillionNums[1* 10== NumLevel.Trillion)
413 
414 {
415 
416 chineseCharactor = uptillionStr + NumLeverChineseSign[(int)NumLevel.Trillion] + downtrillionStr;
417 
418 }
419 
420 else
421 
422 {
423 
424 chineseCharactor = uptillionStr + NumLeverChineseSign[(int)NumLevel.Trillion];
425 
426 if (downtrillionStr != "零元整")
427 
428 {
429 
430 chineseCharactor += NumChineseCharacter[0+ downtrillionStr;
431 
432 }
433 
434 else
435 
436 {
437 
438 chineseCharactor += "元整";
439 
440 }
441 
442 }
443 
444 return chineseCharactor;
445 
446 }
447 
448 8:递归计算货币数字的中文
449 
450  /// 
451 
452 /// 计算中文字符串
453 
454 /// 

455 
456 /// 数字
457 
458 /// 数位级别 比如1000万的 数位级别为万
459 
460 /// 是否以‘壹拾’开头
461 
462 /// 中文大写
463 
464 public string CalculateChineseSign(double Num, NumLevel? NL ,bool IsDump,bool IsExceptTen)
465 
466 {
467 
468 Num = Math.Round(Num, 2);
469 
470 bool isDump = false;
471 
472 //Num的数位
473 
474 NumLevel? currentLevel = GetNumLevel(Num);
475 
476 int numExponent = this.NumLevelExponent[(int)currentLevel];
477 
478 string Result = string.Empty;
479 
480 //整除后的结果
481 
482 int prefixNum;
483 
484 //余数 当为小数的时候 分子分母各乘100
485 
486 double postfixNun ;
487 
488 if (Num >= 1)
489 
490 {
491 
492 prefixNum = Convert.ToInt32(Math.Floor(Num / Math.Pow(10, numExponent)));
493 
494 postfixNun = Math.Round(Num % (Math.Pow(10, numExponent)), 2);
495 
496 }
497 
498 else
499 
500 {
501 
502 prefixNum = Convert.ToInt32(Math.Floor(Num*100 / Math.Pow(10, numExponent+2)));
503 
504 postfixNun = Math.Round(Num * 100 % (Math.Pow(10, numExponent + 2)), 2);
505 
506 postfixNun *= 0.01;
507 
508 }
509 
510 if (prefixNum < 10 )
511 
512 {
513 
514 //避免以‘壹拾’开头
515 
516 if (!(NumChineseCharacter[(int)prefixNum] == NumChineseCharacter[1]
517 
518 && currentLevel == NumLevel.Ten && IsExceptTen))
519 
520 {
521 
522 Result += NumChineseCharacter[(int)prefixNum];
523 
524 }
525 
526 else
527 
528 {
529 
530 IsExceptTen = false;
531 
532 }
533 
534 //加上单位
535 
536 if (currentLevel == NumLevel.Yuan )
537 
538 {
539 
540 ////当为 “元” 位不为零时 加“元”。
541 
542 if (NL == null)
543 
544 {
545 
546 Result += NumLeverChineseSign[(int)currentLevel];
547 
548 //当小数点后为零时 加 "整"
549 
550 if (postfixNun == 0)
551 
552 {
553 
554 Result += EndOfInt;
555 
556 }
557 
558 }
559 
560 }
561 
562 else
563 
564 {
565 
566 Result += NumLeverChineseSign[(int)currentLevel];
567 
568 }
569 
570  //当真正的个位为零时 加上“元”
571 
572 if (NL == null && postfixNun < 1 && currentLevel > NumLevel.Yuan && postfixNun > 0)
573 
574 {
575 
576 Result += NumLeverChineseSign[(int)NumLevel.Yuan];
577 
578 }
579 
580 }
581 
582 else
583 
584 {
585 
586 //当 前缀数字未被除尽时, 递归下去
587 
588 NumLevel? NextNL = null;
589 
590 if ((int)currentLevel >= (int)(NumLevel.TenThousand))
591 
592 NextNL = currentLevel;
593 
594 Result += CalculateChineseSign((double)prefixNum, NextNL, isDump, IsExceptTen);
595 
596 if ((int)currentLevel >= (int)(NumLevel.TenThousand))
597 
598 {
599 
600 Result += NumLeverChineseSign[(int)currentLevel];
601 
602 }
603 
604 }
605 
606 //是否跳位
607 
608 // 判断是否加零, 比如302 就要给三百 后面加零,变为 三百零二。
609 
610 if (IsDumpLevel(Num))
611 
612 {
613 
614 Result += NumChineseCharacter[0];
615 
616 isDump = true;
617 
618 }
619 
620 //余数是否需要递归
621 
622 if (postfixNun > 0)
623 
624 {
625 
626 Result += CalculateChineseSign(postfixNun, NL, isDump, false);
627 
628 }
629 
630 else if (postfixNun == 0 && currentLevel > NumLevel.Yuan )
631 
632 {
633 
634 //当数字是以零元结尾的加上 元整 比如1000000一百万元整
635 
636 if (NL == null)
637 
638 {
639 
640 Result += NumLeverChineseSign[(int)NumLevel.Yuan];
641 
642 Result += EndOfInt;
643 
644 }
645 
646 }
647 
648 return Result;
649 
650 }
651 
652 9:外部调用的转换方法。
653 
654  /// 
655 
656 /// 外部调用的转换方法
657 
658 /// 

659 
660 /// 
661 
662 /// 
663 
664  
665 public string ConvertToChinese(string Num)
666 
667 {
668 
669 if (!IsValidated<string>(Num))
670 
671 {
672 
673 throw new OverflowException("数值格式不正确,请输入小于9999亿兆的数字且最多精确的分的金额!");
674 
675 }
676 
677 string chineseCharactor = string.Empty;
678 
679 if (IsBigThanTillion(Num))
680 
681 {
682 
683 double[] tillionNums = SplitNum(Num);
684 
685 chineseCharactor = ContactNumChinese(tillionNums);
686 
687 }
688 
689 else
690 
691 {
692 
693 double dNum = Convert.ToDouble(Num);
694 
695 chineseCharactor = CalculateChineseSign(dNum, nulltrue, IsStartOfTen(dNum));
696 
697 }
698 
699 return chineseCharactor;
700 
701 }
702 
703  
704 

一个货币数字转换中文的算法,注意:本文中的算法支持小于1023 (也就是9999亿兆)货币数字转化。

   货币中文说明: 在说明代码之前,首先让我们回顾一下货币的读法。

  10020002.23  读为 壹仟零贰万零贰元贰角叁分

  1020         读为 壹仟零贰拾元整。

  100000       读为 拾万元整

  0.13         读为 壹角叁分

 

 

转载于:https://www.cnblogs.com/xue5ya/archive/2009/04/04/1429477.html

你可能感兴趣的:(数字转换成汉字金额(转))