大写金额转为英文的算法 修改版

 大写金额转为英文的算法 修改版
 
 从网上找到了这个算法,原作是Dylan Thomas,但是我使用后发现有少少的缺点,例如英文金额的习惯是小数用Cents Twenty-Five这样的表示,但原版中没有小数的功能,只是简单的用百分数表示了。
另外十位的部分也有少许欠缺,25应为:Twenty-Five,再其次就是增加了0到1之间的小数的表示。我在网上搜了一下发现似乎没人修正这些问题,特此发贴与大家分享:

  1. {**********}
  2. { Number to letters unit version 1.2 }
  3. { copyright (C) Dylan Thomas 2000 }
  4. { License: No significant restrictions. }
  5. { Language: US. English }
  6. { Last Edit By logitech1229 2006. }
  7. unit NumberToLetters;
  8. interface
  9. (* This function returns the written equivalent of a number. *)
  10. function NumToLetters(Number: Real): string;
  11. implementation
  12. uses SysUtils;
  13. type
  14. TNumberStr = string[13];
  15. const
  16. Numbers: array[1..19of TNumberStr = ('One','Two','Three''Four',
  17. 'Five''Six''Seven''Eight''Nine''Ten''Eleven''Twelve',
  18. 'Thirteen''Fourteen''Fifteen''Sixteen''Seventeen''Eighteen',
  19. 'Nineteen');
  20. Tenths: array[1..9of TNumberStr = ('Ten''Twenty''Thirty''Forty',
  21. 'Fifty''Sixty''Seventy','Eighty','Ninety');
  22. ErrorString = 'not in valid range';
  23. Min = 1.00;
  24. Max = 4294967295.99;
  25. function NumToLetters(Number: Real): string;
  26. var Dec:String;
  27. function RecurseNumber(N: LongWord): string;
  28. begin
  29. case N of
  30. 1..19:
  31. Result := Numbers[N];
  32. 20..99:
  33. begin
  34. if (N in [20,30,40,50,60,70,80,90]) then Result := Tenths[N div 10]
  35. else Result := Tenths[N div 10] +'-'+ RecurseNumber(N mod 10);
  36. end;
  37. 100..999:
  38. Result := Numbers[N div 100] + ' Hundred And ' + RecurseNumber(N mod 100);
  39. 1000..999999:
  40. Result := RecurseNumber(N div 1000) + ' Thousand, ' +
  41. RecurseNumber(N mod 1000);
  42. 1000000..999999999: Result := RecurseNumber(N div 1000000) + ' Million, '
  43. + RecurseNumber(N mod 1000000);
  44. 1000000000..4294967295: Result := RecurseNumber(N div 1000000000) +
  45. ' Billion, ' + RecurseNumber(N mod 1000000000);
  46. end{Case N of}
  47. end{RecurseNumber}
  48. begin
  49. {Calls := 0;} 
  50. if (Number >= Min) and (Number <= Max) then
  51. begin
  52. Result := RecurseNumber(Round(Int(Number)));
  53. {Added for cents in a currency value}
  54. if not(Frac(Number) = 0.00then
  55.   {write like 'cents Twenty-five',If you want a result like 'Nought Point two five',you can use strings in {}}
  56.   Result :=Result + ' And Cents '+ RecurseNumber(Round(Frac(Number)*100))
  57.   {Result :=Result +' Point '+ RecurseNumber(Round(Int(Frac(Number)*10)))+' '+RecurseNumber(Round(Int(Frac(Number*10)*10)))}
  58. else Result := Result +' Only';
  59. end;
  60. if (Number >0and (Number<Min) then
  61. begin
  62.   if not(Frac(Number) = 0.00then
  63.   {write like 'cents Twenty-five',If you want a result like 'Nought Point two five',you can use strings in {}}
  64.   Result :=Result + ' Cents '+ RecurseNumber(Round(Frac(Number)*100));
  65.   {Result :=Result +' Point '+ RecurseNumber(Round(Int(Frac(Number)*10)))+' '+RecurseNumber(Round(Int(Frac(Number*10)*10)))}
  66. end;
  67. end;{NumToLetters}
  68. end

-------------------------------------------------------------------------------

  1. function NumToChar(const n: Real): string;   //可以到万亿,并且可以随便扩大范围
  2.   const cNum: WideString = '零壹贰叁肆伍陆柒捌玖--万仟佰拾亿仟佰拾万仟佰拾元角分';
  3.         cCha:array[0..10..12]of string =
  4.         (( '零元','零拾','零佰','零仟','零万','零亿','亿万','零零零','零零','零万','零亿','亿万','零元'),
  5.          ( '元','零','零','零','万','亿','亿','零','零','万','亿','亿','元'));
  6.   var i : Integer;
  7.       sNum,sTemp : WideString;
  8. begin
  9.   result :='';
  10.   sNum := format('%15d',[round(n * 100)]);
  11.   for i := 0 to 14 do
  12.   begin
  13.     stemp := copy(snum,i+1,1);
  14.     if stemp=' ' then continue
  15.     else result := result + cNum[strtoint(stemp)+1] + cNum[i+13];
  16.   end;
  17.   for i:= 0 to 12 do
  18.   Result := StringReplace(Result, cCha[0,i], cCha[1,i], [rfReplaceAll]);
  19.   if pos('零分',result)=0
  20.     then Result := StringReplace(Result, '零角''零', [rfReplaceAll])
  21.     else Result := StringReplace(Result, '零角','整', [rfReplaceAll]);
  22.   Result := StringReplace(Result, '零分','', [rfReplaceAll]);
  23. end

 

-------------------------------------------------------------------------------

  1. function Changdx2(mmje: Double): String;
  2. const s1: String = '零壹贰叁肆伍陆柒捌玖';
  3.       s2: String = '分角元拾佰仟万拾佰仟亿拾佰仟万';
  4.  function StrTran(const S, S1, S2: String): String;
  5.   begin
  6.     Result := StringReplace(S, S1, S2, [rfReplaceAll]);
  7.   end;
  8.  var s, dx: String;
  9.      i, Len: Integer;
  10. begin
  11. if mmje < 0 then
  12.   begin dx := '负';
  13.         mmje := -mmje;
  14.   end;
  15.    s := Format('%.0f', [mmje*100]);
  16.    Len := Length(s);
  17.   for i := 1 to Len do
  18.    dx := dx + Copy(s1, (Ord(s[i]) - ord('0'))*2 + 12) + Copy(s2, (Len - i)*2 + 12);
  19.    dx := StrTran(StrTran(StrTran(StrTran(StrTran(dx, '零仟''零'), '零佰''零'), '零拾''零'), '零角''零'), '零分''整');
  20.    dx := StrTran(StrTran(StrTran(StrTran(StrTran(dx, '零零''零'), '零零''零'), '零亿''亿'), '零万''万'), '零元''元');
  21.  if dx = '整' then Result := '零元整'
  22.   else Result := StrTran(StrTran(dx, '亿万''亿零'), '零整''整');
  23. end;

 

--------------------------------------------------------------------------------

 

  1. public static String numtochinese(String input)
  2. String s1="零壹贰叁肆伍陆柒捌玖"; 
  3. String s4="分角整元拾佰仟万拾佰仟亿拾佰仟"; 
  4. String temp=""; 
  5. String result=""; 
  6. if (input==null) return "输入字串不是数字串只能包括以下字符(´0´~´9´,´.´),输入字串最大只能精确到仟亿,小数点只能两位!"; 
  7. temp=input.trim(); 
  8. float f; 
  9. try{ 
  10. f=Float.parseFloat(temp); 
  11. }catch(Exception e){return "输入字串不是数字串只能包括以下字符(´0´~´9´,´.´),输入字串最大只能精确到仟亿,小数点只能两位!";} 
  12. int len=0
  13. if (temp.indexOf(".")==-1) len=temp.length(); 
  14. else len=temp.indexOf("."); 
  15. if(len>s4.length()-3) return("输入字串最大只能精确到仟亿,小数点只能两位!"); 
  16. int n1,n2=0
  17. String num=""; 
  18. String unit=""; 
  19. for(int i=0;iif(i>len+2){break;} 
  20. if(i==len) {continue;} 
  21. n1=Integer.parseInt(String.valueOf(temp.charAt(i))); 
  22. num=s1.substring(n1,n1+1); 
  23. n1=len-i+2
  24. unit=s4.substring(n1,n1+1); 
  25. result=result.concat(num).concat(unit); 
  26. if ((len==temp.length()) ¦ ¦(len==temp.length()-1)) result=result.concat("整"); 
  27. if (len==temp.length()-2) result=result.concat("零分"); 
  28. return result; 

--------------------------------------------------------------------------------

 

  1. //因为找不到相关函数,便自己写了一个,是仿Excel 金额转换,不限金额长度。 
  2. const NumberArray: array[0..9of string = ('零''壹','貳','叁','肆','伍','陆','柒','捌','玖');
  3. // 数字转与大写
  4. function GetMoneySwitch(AMoney: string): string;
  5. // 去除所有分隔符
  6. procedure ClearComma(var AValue: string);
  7. begin
  8. while Pos(',', AValue) > 0 do
  9. Delete(AValue, Pos(',', AValue), 1);
  10. end;
  11. // 测试如果为零将不返回值
  12. function FiltrateValue(const AValue, AStr: string): string;
  13. var
  14. IntValue: Integer;
  15. begin
  16. IntValue:= StrToIntDef(AValue, 0);
  17. if IntValue > 0 then Result:= AStr; 
  18. end;
  19. // 直接将数字翻译成大写
  20. function Direct(const AValue: string): string;
  21. var
  22. ResultStr: string;
  23. iCount: Integer;
  24. begin
  25. for iCount:= 1 to Length(AValue) do
  26. ResultStr:= ResultStr + NumberArray[StrToInt(AValue[iCount])];
  27. Result:= ResultStr;
  28. end;
  29. // 将四位长度的数字翻译与大写
  30. function FourBit(const AValue: string): string;
  31. var
  32. i, x, j: Integer;
  33. IntValue: Integer;
  34. ResultStr: string;
  35. begin
  36. IntValue:= StrToIntDef(AValue, 0);
  37. x:= IntValue;
  38. i := x div 1000;
  39. j := x mod 1000;
  40. if i <> 0 then ResultStr:= NumberArray[i] + '仟'
  41. else begin
  42. if Length(AValue) > 3 then ResultStr:= '零';
  43. end;
  44. i := j div 100;
  45. j := j mod 100;
  46. if i <> 0 then ResultStr:= ResultStr + NumberArray[i] + '佰'
  47. else begin
  48. if (ResultStr <> ''and (Length(AValue) > 2and
  49. (Copy(ResultStr, Length(ResultStr)-12) <> '零'then
  50. ResultStr:= ResultStr + '零';
  51. end;
  52. i := j div 10;
  53. j := j mod 10;
  54. if i <> 0 then ResultStr := ResultStr + NumberArray[i] + '拾'
  55. else begin
  56. if (ResultStr <> ''and (Length(AValue) > 1and
  57. (Copy(ResultStr, Length(ResultStr)-12) <> '零'then
  58. ResultStr:= ResultStr + '零';
  59. end;
  60. ResultStr := ResultStr + NumberArray[j];
  61. while Copy(ResultStr, Length(ResultStr)-12) = '零' do
  62. Delete(ResultStr, Length(ResultStr)-12);
  63. Result := ResultStr;
  64. end
  65. var
  66. IntegerValue: string// 整数部分的值
  67. KilomegaValue: string// 存储大于千兆的数字
  68. AccountValue: string// 在千兆以内的整数部分
  69. DecimalValue: string// 存在小数点后的值
  70. ResultKilomega: string// 大于千兆并翻译后的大写字符
  71. ResultAccount: string// 在千兆以内的整数部分并翻译后的大写字符
  72. ResultDecimal: string// 小数点后的值并翻译后的大写字符
  73. FourBitStr: string// 最大四位值的字符
  74. begin
  75. // 清除分隔符
  76. ClearComma(AMoney);
  77. // 验证字符串是否合法
  78. try
  79. AMoney:= FloatToStr(StrToFloat(AMoney));
  80. except
  81. raise Exception.Create('无效的数值字符串');
  82. end;
  83. // 取到小数据点后的值
  84. // 取出整数部分的值
  85. if Pos('.', AMoney) > 0 then
  86. begin
  87. DecimalValue:= Copy(AMoney, Pos('.', AMoney) + 1, Length(AMoney));
  88. IntegerValue:= Copy(AMoney, 0, Pos('.', AMoney)-1);
  89. ResultDecimal:= '.' + Direct(DecimalValue);
  90. end
  91. else IntegerValue:= AMoney;
  92. // 取到大于千兆的数字
  93. // 取到在千兆以内的整数部分
  94. if Length(IntegerValue) > 16 then
  95. begin
  96. KilomegaValue:= Copy(IntegerValue, 0, Length(IntegerValue) - 12);
  97. AccountValue:= Copy(IntegerValue,
  98. Length(IntegerValue) - 11, Length(IntegerValue));
  99. ResultKilomega:= Direct(KilomegaValue) + '兆';
  100. end
  101. else AccountValue:= IntegerValue;
  102. { 翻译在千兆以内的整数部分 }
  103. // 翻译在兆与仟兆之间的部份
  104. if Length(AccountValue) > 12 then
  105. begin
  106. FourBitStr:= Copy(AccountValue, 0, Length(AccountValue) - 12);
  107. ResultAccount:= ResultAccount +
  108. FourBit(FourBitStr) + FiltrateValue(FourBitStr, '兆');
  109. Delete(AccountValue, 1, Length(AccountValue) - 12);
  110. end;
  111. // 翻译在亿与仟亿之间的部份
  112. if Length(AccountValue) >= 8 then
  113. begin
  114. FourBitStr:= Copy(AccountValue, 0, Length(AccountValue) - 8);
  115. ResultAccount:= ResultAccount +
  116. FourBit(FourBitStr) + FiltrateValue(FourBitStr, '亿');
  117. Delete(AccountValue, 1, Length(AccountValue) - 8);
  118. end;
  119. // 翻译在万与仟万之间的部份
  120. if Length(AccountValue) >= 5 then
  121. begin
  122. FourBitStr:= Copy(AccountValue, 0, Length(AccountValue) - 4);
  123. ResultAccount:= ResultAccount +
  124. FourBit(FourBitStr) + FiltrateValue(FourBitStr, '万');
  125. Delete(AccountValue, 1, Length(AccountValue) - 4);
  126. end;
  127. // 翻译万以下的部份
  128. if Length(AccountValue) > 0 then
  129. begin
  130. ResultAccount:= ResultAccount +
  131. FourBit(Copy(AccountValue, 0, Length(AccountValue)));
  132. end;
  133. // 组合字符串
  134. Result:= ResultKilomega + ResultAccount + ResultDecimal;
  135. end;

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值