写合同需要把金额转换成大写,找了一些,都有些错。谁有比较完美的?
解决方案 »
- 怎么从两个不同的数据库中查询数据
- 我买的联想旭日410双核笔记本电脑,使用的是VS2005,WIN2003,为什么不能不使用DELPHI7呢?运行DELPHI7就出错误,换了内存也不行?哪位帮我
- 这样删除表:jb
- 大家知道怎么让文本像表格一样显示吗
- 串口发给我的是十六进制数,我该如何正确接受并显示信息,急!解决一定结贴!
- sos:如何判断groupbox中的dataset值已经发生改变?
- 100分证求vfp汉字字段问题!
- 怎么会有这么莫名其妙的错误,求救!!
- 如何有效的控制EXCEL文檔
- 哈,大家来看看这里是这样给分的!!!!!这年头赚钱真容易!
- delphi如何读取远程远程的txt或者ini文件中的内容并执行!
- richEdit可以设置某一行某几个字的字体颜色,请问能设置某一行的某几个字的背景颜色吗?
NumberArray: array[0..9] of string =
('零', '壹','貳','叁','肆','伍','陆','柒','捌','玖');// 数字转与大写
function GetMoneySwitch(AMoney: string): string; // 去除所有分隔符
procedure ClearComma(var AValue: string);
begin
while Pos(',', AValue) > 0 do
Delete(AValue, Pos(',', AValue), 1);
end; // 测试如果为零将不返回值
function FiltrateValue(const AValue, AStr: string): string;
var
IntValue: Integer;
begin
IntValue:= StrToIntDef(AValue, 0);
if IntValue > 0 then Result:= AStr;
end; // 直接将数字翻译成大写
function Direct(const AValue: string): string;
var
ResultStr: string;
iCount: Integer;
begin
for iCount:= 1 to Length(AValue) do
ResultStr:= ResultStr + NumberArray[StrToInt(AValue[iCount])];
Result:= ResultStr;
end; // 将四位长度的数字翻译与大写
function FourBit(const AValue: string): string;
var
i, x, j: Integer;
IntValue: Integer;
ResultStr: string;
begin IntValue:= StrToIntDef(AValue, 0);
x:= IntValue; i := x div 1000;
j := x mod 1000;
if i <> 0 then ResultStr:= NumberArray[i] + '仟'
else begin
if Length(AValue) > 3 then ResultStr:= '零';
end; i := j div 100;
j := j mod 100;
if i <> 0 then ResultStr:= ResultStr + NumberArray[i] + '佰'
else begin
if (ResultStr <> '') and (Length(AValue) > 2) and
(Copy(ResultStr, Length(ResultStr)-1, 2) <> '零') then
ResultStr:= ResultStr + '零';
end; i := j div 10;
j := j mod 10;
if i <> 0 then ResultStr := ResultStr + NumberArray[i] + '拾'
else begin
if (ResultStr <> '') and (Length(AValue) > 1) and
(Copy(ResultStr, Length(ResultStr)-1, 2) <> '零') then
ResultStr:= ResultStr + '零';
end; ResultStr := ResultStr + NumberArray[j]; while Copy(ResultStr, Length(ResultStr)-1, 2) = '零' do
Delete(ResultStr, Length(ResultStr)-1, 2); Result := ResultStr;
end; var
IntegerValue: string; // 整数部分的值
KilomegaValue: string; // 存储大于千兆的数字
AccountValue: string; // 在千兆以内的整数部分
DecimalValue: string; // 存在小数点后的值 ResultKilomega: string; // 大于千兆并翻译后的大写字符
ResultAccount: string; // 在千兆以内的整数部分并翻译后的大写字符
ResultDecimal: string; // 小数点后的值并翻译后的大写字符 FourBitStr: string; // 最大四位值的字符
begin // 清除分隔符
ClearComma(AMoney); // 验证字符串是否合法
try
AMoney:= FloatToStr(StrToFloat(AMoney));
except
raise Exception.Create('无效的数值字符串');
end; // 取到小数据点后的值
// 取出整数部分的值
if Pos('.', AMoney) > 0 then
begin
DecimalValue:= Copy(AMoney, Pos('.', AMoney) + 1, Length(AMoney));
IntegerValue:= Copy(AMoney, 0, Pos('.', AMoney)-1);
ResultDecimal:= '.' + Direct(DecimalValue);
end
else IntegerValue:= AMoney; // 取到大于千兆的数字
// 取到在千兆以内的整数部分
if Length(IntegerValue) > 16 then
begin
KilomegaValue:= Copy(IntegerValue, 0, Length(IntegerValue) - 12);
AccountValue:= Copy(IntegerValue,
Length(IntegerValue) - 11, Length(IntegerValue));
ResultKilomega:= Direct(KilomegaValue) + '兆';
end
else AccountValue:= IntegerValue; { 翻译在千兆以内的整数部分 } // 翻译在兆与仟兆之间的部份
if Length(AccountValue) > 12 then
begin
FourBitStr:= Copy(AccountValue, 0, Length(AccountValue) - 12);
ResultAccount:= ResultAccount +
FourBit(FourBitStr) + FiltrateValue(FourBitStr, '兆');
Delete(AccountValue, 1, Length(AccountValue) - 12);
end;
// 翻译在亿与仟亿之间的部份
if Length(AccountValue) >= 8 then
begin
FourBitStr:= Copy(AccountValue, 0, Length(AccountValue) - 8);
ResultAccount:= ResultAccount +
FourBit(FourBitStr) + FiltrateValue(FourBitStr, '亿');
Delete(AccountValue, 1, Length(AccountValue) - 8);
end;
// 翻译在万与仟万之间的部份
if Length(AccountValue) >= 5 then
begin
FourBitStr:= Copy(AccountValue, 0, Length(AccountValue) - 4);
ResultAccount:= ResultAccount +
FourBit(FourBitStr) + FiltrateValue(FourBitStr, '万');
Delete(AccountValue, 1, Length(AccountValue) - 4);
end;
// 翻译万以下的部份
if Length(AccountValue) > 0 then
begin
ResultAccount:= ResultAccount +
FourBit(Copy(AccountValue, 0, Length(AccountValue)));
end; // 组合字符串
Result:= ResultKilomega + ResultAccount + ResultDecimal;
end;
var
SmallMonth,BigMonth:string;
wei1,qianwei1:string[2];
qianwei,dianweizhi,qian:integer;
ObjSmall:real;
small:real;
begin
if smallpara<>'' then
small:=strtofloat(smallpara)
else
small:=0; ObjSmall:=Abs(small);
qianwei:=-2;
Smallmonth:=formatfloat('0.00',ObjSmall); {---------------------------------}
dianweizhi :=pos('.',Smallmonth); for qian:=length(Smallmonth) downto 1 do begin
if qian<>dianweizhi then begin
case strtoint(copy(Smallmonth,qian,1)) of 1:wei1:='壹';
2:wei1:='贰';
3:wei1:='叁';
4:wei1:='肆';
5:wei1:='伍';
6:wei1:='陆';
7:wei1:='柒';
8:wei1:='捌';
9:wei1:='玖';
0:wei1:='零';
end;
case qianwei of -3:qianwei1:='厘';
-2:qianwei1:='分';
-1:qianwei1:='角';
0 :qianwei1:='元';
1 :qianwei1:='拾';
2 :qianwei1:='佰';
3 :qianwei1:='仟';
4 :qianwei1:='万';
5 :qianwei1:='拾';
6 :qianwei1:='佰';
7 :qianwei1:='仟';
8 :qianwei1:='亿';
9 :qianwei1:='拾';
10:qianwei1:='佰';
11:qianwei1:='仟';
end;
inc(qianwei);
if Small<0 then
BigMonth :='??'+wei1+qianwei1+BigMonth else
BigMonth :=wei1+qianwei1+BigMonth end;
end;
Result:=BigMonth;
end;
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;function DecimalToChinese(number:Extended;CnType:integer):string;implementationfunction DecimalToChinese(number:Extended;CnType:integer):string;
var
NumStr:array[1..12] of string; //中文数位名
Str1,Str2,IntStr,DecStr:string; //整数部分,小数部分,大写整数部分,大写小数部分
Num:array[1..10] of string; //各个数位段,即每四位为一段
N:array[1..10] of string; //各位数字
Number1,Number2,Number3:string; //定义数字的三个数位段
PointPos:integer; //小数点位置
DecPos:integer;
NumHead:string; //正负性
NumberName:string; //用于代替参数Number的字符串
NumLen:integer; //参数Number的串长度
begin
NumStr[1] :='零'; NumStr[2] :='壹'; //初始化
NumStr[3] :='贰'; NumStr[4] :='叁';
NumStr[5] :='肆'; NumStr[6] :='伍';
NumStr[7] :='陆'; NumStr[8] :='柒';
NumStr[9] :='捌'; NumStr[10]:='玖';
NumStr[11]:='拾';
if Number<0 then //如果是负数,则在前面加‘负'
begin
NumHead:='负';
Number:=-Number;
end;
NumberName:=FloatToStr(Number);
NumLen:=Length(NumberName);
PointPos:=Pos('.',NumberName);
if PointPos=0 then //输入值为纯整数
Str1:=NumberName
else //输入值为浮点数
begin
if CnType=0 then //如果转换为人民币大写,并且小数数位超过2位,则只保留2位
if (NumLen-pos('.',NumberName))>2 then
NumberName:=Trim(format('%'+IntToStr(NumLen)+'.2f',[Number]));
Str1:=Copy(NumberName,1,Pos('.',NumberName)-1); //取整数部分
Str2:=Copy(NumberName,Pos('.',NumberName)+1,length(numberName)
-Pos('.',NumberName)); //取小数部分
end;
{*****分析转换整数部分*****分析整数部分在100000000以上的}
if length(str1)>8 then
begin
//按每4位为一段拆分成三段,逐段分析
Num[1]:=Copy(str1,1,length(Str1)-8); //取8位以上的那部分数段
Num[2]:=Copy(str1,length(Str1)-7,4); //取千万到万的4位
Num[3]:=Copy(str1,length(Str1)-3,4); //取千到个位的4位
Number1:=DecimalToChinese(StrToInt64(Num[1]),1)+'亿'; //通过函数嵌套调用,得到亿上的数段格式,即若干亿
if StrToInt64(Num[2])=0 then //如果千万到万4位为0
begin
if StrToInt64(Num[3])=0 then //并且末尾4位为0
Number2:=''
else
begin
if StrToInt64(Num[3])<1000 then
Number2:='' //如果第三段也是零XX百十个,则中间段的"零"去掉
else
Number2:=Numstr[1]; //读零
end;
end
else
begin
if StrToInt64(Num[2])>1000 then //中间4位大于1000
Number2:=DecimalToChinese(strtoint64(Num[2]),1)+'万'
else //不足一千万,则读X亿零xx百、十、万
Number2:=NumStr[1]+DecimalToChinese(StrToInt64(Num[2]),1)+'万';
end;
if StrToInt64(Num[3])=0 then //末尾4位为0
Number3:=''
else
begin
if strtoint64(num[3])>1000 then //末尾4位大于1000
Number3:=DecimalToChinese(StrToInt64(Num[3]),1)
else //不足一千,则读X万零XX百、十
Number3:=numstr[1]+DecimalToChinese(StrToInt64(Num[3]),1);
end;
IntStr:=Number1+Number2+Number3;
end;
{分析整数部分在10000~99999999之间的}
if (Length(Str1)>=5) and (Length(Str1)<=8) then
begin
Num[1]:=Copy(Str1,1,Length(Str1)-4); //取得第一段(千万位到万位)
if Length(Num[1])=3 then //为方便分析,若不足4位,用'0'补齐为4位
num[1]:='0'+Num[1];
if Length(Num[1])=2 then
num[1]:='00'+Num[1];
if Length(Num[1])=1 then
Num[1]:='000'+Num[1];
Num[2]:=Copy(Str1,Length(Str1)-3,4); //取得第二段(千位到个位)
Number1:=DecimalToChinese(StrToInt64(Num[1]),1)+'万';
if strtoint64(num[2])=0 then
number2:=''
else
begin
if strtoint64(num[2])>1000 then //中间4位大于1000
Number2:=DecimalToChinese(StrToInt64(num[2]),1)
else
Number2:=NumStr[1]+DecimalToChinese(StrToInt64(num[2]),1);
end;
IntStr:=Number1+Number2;
end;
{分析整数部分不到10000的}
if length(str1)<5 then
begin
num[1]:=str1; //不足4位,用'0'补齐
if Length(Num[1])=3 then
Num[1]:='0'+Num[1];
if length(num[1])=2 then
Num[1]:='00'+Num[1];
if length(num[1])=1 then
Num[1]:='000'+Num[1];
Number1:=''; //亿以上的为空
Number2:=''; //万以上的为空
//分析千位
if Copy(Num[1],1,1)='0' then
N[1]:=''
else
N[1]:=numstr[strtoint64(copy(num[1],1,1))+1]+'仟';
//分析百位
if Copy(Num[1],2,1)='0' then
begin
if Copy(Num[1],1,1)='0' then
N[2]:=''
else
N[2]:=NumStr[1]
end
else
N[2]:=NumStr[StrToInt64(Copy(num[1],2,1))+1]+'佰';
//分析十位
if Copy(Num[1],3,1)='0' then
begin
if Copy(Num[1],2,1)='0' then
N[3]:=''
else
N[3]:=NumStr[1]
end
else
begin
if (Copy(Num[1],1,1)='0') and (Copy(Num[1],2,1)='0')
and (Copy(Num[1],3,1)='1') then //如果百位为0且十位为1则不读出壹字
N[3]:='拾'
else
N[3]:=numstr[strtoint64(copy(num[1],3,1))+1] +'拾';
end;
//分析个位
if Copy(Num[1],4,1)='0' then
N[4]:=''
else
N[4]:=NumStr[StrToInt64(Copy(Num[1],4,1))+1];
if Copy(Num[1],Length(Num[1])-2,3)='000' then //当末尾有000时
begin
N[2]:='';
N[3]:='';
N[4]:=''
end;
if Copy(Num[1],Length(Num[1])-1,2)='00' then //当末尾有00时
begin
N[3]:='';
N[4]:='';
end;
if Copy(Num[1],Length(Num[1]),1)='0' then //当末尾有0时
N[4]:='';
//数段合并
Number3:=N[1]+N[2]+N[3]+N[4];
//取得整数位值
IntStr:=Number1+Number2+Number3;
end;
{如果整数为零,转换为"零"}
if Str1='0' then IntStr:=numstr[1];
{整数转换完毕}
{*****分析和转换小数部分*****}
if Length(Str2)>0 then //如果小数数段不为空,则分析小数
begin
if CnType=0 then //一.如果转换为人民币表达式
begin
if Length(Str2)=1 then Str2:=Str2+'0';
if Copy(Str2,1,1)='0' then //角为0
begin
if IntStr='零' then N[1]:='' else N[1]:='零'; //如果元为0,则不读0角,否则读零若干分
end
else
N[1]:=NumStr[StrToInt64(Copy(Str2,1,1))+1]+'角';
if Copy(Str2,2,1)='0' then N[2]:=''
else N[2]:=Numstr[StrToInt64(Copy(Str2,2,1))+1]+'分';
DecStr:=N[1]+N[2];
end
else //二.如果转换为数字表达式
begin
DecStr:='';
for Decpos:=1 to Length(Str2) do
begin
DecStr:=DecStr+NumStr[StrToInt64(Copy(Str2,DecPos,1))+1];
end;
end;
end;
{小数转换完毕}
{输出本函数的结果***********************}
if CnType=0 then //将数字字串转换为人民币的大写格式
begin
if Str2='' then //如果为纯整数
Result:=NumHead+IntStr+'元整'
else
begin
if IntStr='零' then //如果整数为零,就只显示小数
Result:=NumHead+DecStr
else
Result:=NumHead+intstr+'元'+DecStr+'整';
end;
end;
if CnType=1 then //将数字字串转换为普通大写格式
begin
if str2='' then //如果为纯整数
Result:=NumHead+IntStr
else
Result:=NumHead+IntStr+'点'+DecStr
end;
end;end.
function NumToRmb(const S:WideString):WideString;
//[====防止出现000001的情况
procedure DeleZero(var S:WideString);
begin
if s[1]='0' then
begin
Delete(s,1,1);
if Length(s)>1 then
DeleZero(s); //递归
end;
end;
//=======]
const
ARmbUnits:WideString='仟佰拾万仟佰拾亿仟佰拾万仟佰拾元元角分厘';
AUpper:WideString='零壹贰叁肆伍陆柒捌玖';
AYuanPos=16;
AKeyWordPos=[4,8,12,16]; //万亿万元的位置
var
dotPos,Len,nUnitLen:integer;
Amount,RMB,sNum,sUnit:WideString;
i,n,k:integer;
begin
Amount:=Trim(S);
try
DeleZero(Amount); //调用内部过程
len:=Length(Amount);
dotPos:=pos('.',Amount); //小数点的位置
//===[判断数字长度有否越界
if dotPos>0 then
begin
if dotPos>AYuanPos+1 then
begin
ShowMessage('数值超过千亿位');
Exit;
end else nUnitLen:=AYuanPos-dotPos+1; //对齐元
end else
begin
if Len>AYuanPos then
begin
ShowMessage('数值超过千亿位');
Exit;
end else nUnitLen:=AYuanPos-Len; //对齐元
end; //======]
RMB:='';
// if dotPos>0 then
// nUnitLen:=AYuanPos-dotPos+1 //对齐元
// else nUnitLen:=AYuanPos-Len;
i:=1;
while i<=Len do
begin
if i=dotPos then inc(i); //碰到小数点挪到下位
n:=nUnitLen+i; //计算金额单位的位置
k:=strtoint(Amount[i]);
sNum:=AUpper[k+1]; //数字数值
sUnit:=ARmbUnits[n]; //单位
if k=0 then //为零的大写习惯
begin
if i<Len then
begin
if i+1<>dotPos then
begin
k:=strtoint(Amount[i+1]);
if (k=0) or (n in AKeyWordPos) then sNum:='';
end else sNum:='';
end else sNum:='';
if not(n in AKeyWordPos)
or (dotPos=2) then sUnit:='';
end;
RMB:=RMB+sNum+sUnit;
inc(i);
end;
if Pos('零',RMB)=1 then Delete(RMB,1,1);//解决0.09类的问题
k:=Pos('亿万',RMB); //解决亿万问题
if k>0 then Delete(RMB,k+1,1);
if RMB[1]='元' then
Result:=' ' //排除0000只出现一个元字的问题
else
Result:=RMB; //输出
except
ShowMessage('输入非法数值,请重新输入');
end;
end;
==== hongqi162 失踪的月亮
小写:1000100011.12
大写:壹拾亿零壹拾万零壹拾壹.壹貳
---------
小写:0.09
大写:.零玖
---------
====3150379孒淵
小写:1000100011.12
大写:壹拾零亿零仟零佰壹拾零万零仟零佰壹拾壹元壹角贰分
---------
====mygodsos乌龙哈里
小写:1000100011.12
大写:壹拾亿零壹拾万零壹拾壹元壹角贰分
---------
小写:0.09
大写:玖分
---------
====unsigned僵哥
小写:1000100011.12
大写:拾零壹拾壹元壹角贰分
---------
小写:101011.12
大写:佰壹仟零壹拾壹元壹角贰分
---------
小写:0.09
大写:玖分
---------
*****************************************
我用strtofloat把字符串转化成数字,不知道是不是这个影响了unsigned的
lydwei的我不行测试了,太复杂了只有mygodsos的正确,失踪的月亮的怎么没有后面的元角分之类的
uses Tst_RMBTest;procedure TForm1.Button1Click(Sender: TObject);
var
s:string;
t:string;
n:Double;
begin
Memo1.Lines.Add('==== hongqi162 失踪的月亮');
s:='1000100011.12';
t:=GetMoneySwitch(s);
Memo1.Lines.Add('小写:'+s);
Memo1.Lines.Add('大写:'+t);
Memo1.Lines.Add('---------');
s:='0.09';
t:=GetMoneySwitch(s);
Memo1.Lines.Add('小写:'+s);
Memo1.Lines.Add('大写:'+t);
Memo1.Lines.Add('---------');
Memo1.Lines.Add('====3150379孒淵');
s:='1000100011.12';
t:=UpperMoney(s);
Memo1.Lines.Add('小写:'+s);
Memo1.Lines.Add('大写:'+t);
Memo1.Lines.Add('---------');
Memo1.Lines.Add('====mygodsos乌龙哈里');
s:='1000100011.12';
t:=NumToRmb(s);
Memo1.Lines.Add('小写:'+s);
Memo1.Lines.Add('大写:'+t);
Memo1.Lines.Add('---------');
s:='0.09';
t:=NumToRmb(s);
Memo1.Lines.Add('小写:'+s);
Memo1.Lines.Add('大写:'+t);
Memo1.Lines.Add('---------'); Memo1.Lines.Add('====unsigned僵哥');
s:='1000100011.12';
n:=StrToFloat(s);
t:=toChineseCapitalMoney(n);
Memo1.Lines.Add('小写:'+s);
Memo1.Lines.Add('大写:'+t);
Memo1.Lines.Add('---------');
s:='101011.12';
n:=StrToFloat(s);
t:=toChineseCapitalMoney(n);
Memo1.Lines.Add('小写:'+s);
Memo1.Lines.Add('大写:'+t);
Memo1.Lines.Add('---------');
s:='0.09';
n:=StrToFloat(s);
t:=toChineseCapitalMoney(n);
Memo1.Lines.Add('小写:'+s);
Memo1.Lines.Add('大写:'+t);
Memo1.Lines.Add('---------');
end;
end.
1楼的函数
math; const mnUnit:WideString ='分角元';
const OtherWords:WideString='整负';
const hzUnit:WideString = '拾佰仟万拾佰仟亿';
const hzNum:WideString='零壹贰叁肆伍陆柒捌玖';function Money2ChineseCapital2(const Num:double ): WideString;
var
szNum:PWideChar;
i,iLen,iLen2, iNum, iAddZero,ResultCount:Integer;
buff:AnsiString;
buf:PAnsiChar; dblNum: Double;
begin
SetLength(Result,33*2 + 1);
iAddZero := 0;
if Num < 0.0 then
dblNum := Num * 100.0 + 0.5
else
dblNum := Num * 100.0 - 0.5; buff := format('%0.0f',[dblNum]);
iLen := Length(buff);
szNum := PWideChar(Result);
buf := PAnsiChar(buff);
if(Num<0.0) then
begin
szNum^:=OtherWords[2];
Inc(szNum);
Inc(buf);
Dec(iLen);
end; for i:=1 to iLen do
begin
iNum :=Ord(buf^)-48;
Inc(buf);
iLen2 := iLen-i;
if(iNum=0) then
begin
if(((iLen2-2) mod 4)=0) and ((iLen2-3)>0) and (((iLen2>=8) or (iAddZero<3))) then
begin
szNum^ := hzUnit[(iLen2-3) mod 8 + 1];
Inc(szNum);
end;
Inc(iAddZero);
if(iLen>1) and (iLen2=1) then
begin
szNum^:=hzNum[1];
Inc(szNum);
end;
end
else
begin
if(((iAddZero>0) and (iLen2>=2)) and (((iLen2-1) mod 4)<>0) or ((iAddZero>=4) and ((iLen2-1)>0))) then
begin
szNum^:=hzNum[1];
Inc(szNum);
end;
szNum^:=hzNum[iNum+1];
Inc(szNum);
iAddZero:=0;
end;
if (iAddZero<1) or (iLen2=2) then
begin
if(iLen-i>=3) then
begin
szNum^:=hzUnit[(iLen2-3) mod 8 + 1];
Inc(szNum);
end
else
begin
szNum^:=mnUnit[(iLen2) mod 3 +1 ];
Inc(szNum);
end;
end;
end;
ResultCount := szNum-PWideChar(Result);
if((Num < 0.0) and (ResultCount - 1 = 0)) or ((Num>=0.0) and (ResultCount=0)) then
begin
szNum^:=hzNum[1];
Inc(szNum);
szNum^:=mnUnit[3];
Inc(szNum);
szNum^:=OtherWords[1];
Inc(szNum);
Inc(ResultCount,3);
end
else
if((Num<0.0) and (buf[iLen+1] ='0')) or ((Num>=0.0) and (buf[iLen] ='0')) then
begin
szNum^:=OtherWords[1];
Inc(ResultCount);
end; SetLength(Result, ResultCount);
end;
math;const mnUnit:WideString ='分角元';
const OtherWords:WideString='整负';
const hzUnit:WideString = '拾佰仟万拾佰仟亿';
const hzNum:WideString='零壹贰叁肆伍陆柒捌玖';function Money2ChineseCapital2(const Num:double ): WideString;
var
szNum:PWideChar;
i,iLen,iLen2, iNum, iAddZero,ResultCount:Integer;
buff:AnsiString;
buf:PAnsiChar; dblNum: Double;
begin
SetLength(Result,33*2 + 1);
iAddZero := 0;
if Num < 0.0 then
dblNum := Num * 100.0 + 0.5
else
dblNum := Num * 100.0 - 0.5; buff := format('%0.0f',[dblNum]);
if Pos(buff,'e')>0 then begin
SetLength(Result,0);
Raise Exception.Create('数值过大!');
Exit;
end;
iLen := Length(buff);
szNum := PWideChar(Result);
buf := PAnsiChar(buff);
if(Num<0.0) then
begin
szNum^:=OtherWords[2];
Inc(szNum);
Inc(buf);
Dec(iLen);
end; for i:=1 to iLen do
begin
iNum :=Ord(buf^)-48;
Inc(buf);
iLen2 := iLen-i;
if(iNum=0) then
begin
if(((iLen2-2) mod 4)=0) and ((iLen2-3)>0) and (((iLen2>=8) or (iAddZero<3))) then
begin
szNum^ := hzUnit[(iLen2-3) mod 8 + 1];
Inc(szNum);
end;
Inc(iAddZero);
if(iLen>1) and (iLen2=1) and (buff[iLen] <> '0') then
begin
szNum^:=hzNum[1];
Inc(szNum);
end;
end
else
begin
if(((iAddZero>0) and (iLen2>=2)) and (((iLen2-1) mod 4)<>0) or ((iAddZero>=4) and ((iLen2-1)>0))) then
begin
szNum^:=hzNum[1];
Inc(szNum);
end;
szNum^:=hzNum[iNum+1];
Inc(szNum);
iAddZero:=0;
end;
if (iAddZero<1) or (iLen2=2) then
begin
if(iLen-i>=3) then
begin
szNum^:=hzUnit[(iLen2-3) mod 8 + 1];
Inc(szNum);
end
else
begin
szNum^:=mnUnit[(iLen2) mod 3 +1 ];
Inc(szNum);
end;
end;
end;
ResultCount := szNum-PWideChar(Result);
if((Num < 0.0) and (ResultCount - 1 = 0)) or ((Num>=0.0) and (ResultCount=0)) then
begin
szNum^:=hzNum[1];
Inc(szNum);
szNum^:=mnUnit[3];
Inc(szNum);
szNum^:=OtherWords[1];
Inc(szNum);
Inc(ResultCount,3);
end
else
if((Num<0.0) and (buff[iLen+1] ='0')) or ((Num>=0.0) and (buff[iLen] ='0')) then
begin
szNum^:=OtherWords[1];
Inc(ResultCount);
end; SetLength(Result, ResultCount);
end;
=====
测试环境:delphi2007 Winxp sp3
1000000100011.123
壹万亿零壹拾万零壹拾壹元壹角贰分叁厘
循环50000次,mygodsos耗时:1140
壹万亿零壹拾万零壹拾壹元壹角贰分
循环50000次,unsigned耗时:125
======
虽然比较晦涩,但比我的快那么多,我改改看
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;namespace RMM大小写转换
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private string str = "";
private void button1_Click(object sender, EventArgs e)
{
string str1 = textBox1.Text.Trim();
string str2 = Convert.ToDouble(str1).ToString ("f2");
int str2len = str2.Length;
for (int i = str2len ; i > 0; i--)
{
if (i==3)
continue ;
changetobig(i, Convert.ToInt16(str2.Substring(str2len-i, 1)), str2);
}
this.textBox2.Text = str; }
private void changetobig(int weishu ,int value,string strsource)
{
#region //处理相应的数值
switch (value)
{
case 0:
str += "";
break;
case 1:
str += "壹";
break;
case 2:
str += "贰";
break;
case 3:
str += "叁";
break;
case 4:
str += "肆";
break;
case 5:
str += "伍";
break;
case 6:
str += "陆";
break;
case 7:
str += "柒";
break;
case 8:
str += "捌";
break;
case 9:
str += "玖";
break;
default:
break;
}
#endregion
#region 处理相应的单位
switch (weishu)
{
case 1:
if (value !=0)
str+="分";
break ;
case 2:
if (value !=0)
str+="角";
break;
case 3:
break;
case 4:
if ((value == 0 && strsource.Length == 4) || ((strsource.Length > 7) && (Convert.ToDouble(strsource.Substring(strsource.Length - 7, 4)) == 0)))
str += "";
else
str += "元";
break;
case 5:
if (value != 0)
str += "十";
break;
case 6:
if (value != 0)
str += "百";
break;
case 7:
if (value != 0)
str += "千";
break;
case 8:
if ((value == 0 && strsource.Length == 8) || ((strsource.Length > 11) && (Convert.ToDouble(strsource.Substring(strsource.Length - 11, 4)) == 0)))
str += "";
else
str += "万";
break;
case 9:
if (value != 0)
str += "十";
break;
case 10:
if (value != 0)
str += "百";
break;
case 11:
if (value != 0)
str += "千";
break;
case 12:
if ((value == 0 && strsource.Length == 12) || ((strsource.Length > 15) && (Convert.ToDouble(strsource.Substring(strsource.Length - 15, 4)) == 0)))
str += "";
else
str += "亿";
break;
case 13:
if (value != 0)
str += "十";
break;
case 14:
if (value != 0)
str += "百";
break;
default:
break; }
#endregion }
}
}自己写的调试通过,不过没有写输入验证(以确认有效字符那块),可以满足千亿以内的数值转换,估计写合同也足够了吧!
这个运算速度应该算超快的!总共也就那几步!
function UpperMun(i:Real):string;
const
d='零壹贰叁肆伍陆柒捌玖分角元拾佰仟万拾佰仟亿十百千';
var
m,k:string;
j:integer;
begin
k:='';
m:=floattostr(int(i*100));
for j:=length(m) downto 1 do
k:=k+d[(strtoint(m[Length(m)-j+1])+1)*2-1]+d[(strtoint(m[Length(m)-j+1])+1)*2]+d[(10+j)*2-1]+d[(10+j)*2];
Result:=k;
end;
你看看你的结果,我都还没用10000000010000011.123来测试测试环境:delphi2007 Winxp sp3
100011.123
壹拾零万零仟零佰壹拾壹元壹角贰分