function TfrmRPDesigner.FloatToCnMoney(Num: Double): string;
const
mnUnit:String='分角元';
hzUnit:String='拾佰仟万拾佰仟亿拾佰仟万拾佰仟';
hzNum:String='零壹贰叁肆伍陆柒捌玖';
var
szChMoney,szNum:String;
iLen, iNum, iAddZero,i:integer;
function DRound(Value:double;cnt:byte):double;
var
fTmp:double;
nTmp:double;
k:int64;
begin
Result:=Value;
if cnt>18 then exit;
nTmp:=Power(10.0,cnt);
fTmp:=0.5;
fTmp:=fTmp/nTmp;
Result:=fTmp+Result;
Result:=Result*nTmp;
k:=0;
asm
fld qword ptr Result
//__ftol begin
push ebp
mov ebp,esp
LEA ESP,k
wait
fstcw word ptr [ebp-$04]
wait
mov al,[ebp-$03]
or [ebp-$04],$00000c01
fldcw word ptr [ebp-$04]
fistp qword ptr [ebp-$0c]
mov [ebp-$03],al
fldcw word ptr [ebp-$04]
mov eax ,[ebp-$0c]
mov edx,[ebp-$08]
mov esp,ebp
pop ebp
//__ftol end
push esp
lea esp,k
mov [esp],eax
add esp,4
mov [esp],edx
mov esp,ebp
pop esp
fild qword ptr k
fstp qword ptr Result
fld qword ptr nTmp
fdivr qword ptr Result
fstp qword ptr Result
end;
end;
begin
iAddZero:=0;
szNum:=FormatFloat('0', DRound(Num,2)*100.0); //这样可能会有数字误差,double只有15位有效数字,这里只有13
Result:='';
iLen:=Length(szNum);
if Pos('E',UpperCase(szNum))>0 then exit;
if (iLen>18) or (iLen=0) or (Num<0) then exit; //数据错误返回 for i:=1 to iLen do
begin
iNum:=StrToInt(copy(szNum,i,1));
if iNum=0 then
begin
if (((iLen-i-2) mod 4)=0) and ((iLen-i-3)>0) and (((iLen-i)>=8) or (iAddZero<3)) then
szChMoney:=copy(szChMoney+hzUnit,((iLen-i-3) mod 8)+1,1);
inc(iAddZero);
end
else
begin
if ((iAddZero>0) and ((iLen-i)>=2)) and (((iLen-i-1) mod 4)<>0) then
szChMoney:=szChMoney+copy(hzNum,1,1);
szChMoney:=szChMoney+copy(hzNum,iNum+1,1);
iAddZero:=0;
end;
if (iAddZero<1) or ((iLen-i)=2) then
if (iLen-i)>=3 then
begin
szChMoney:=szChMoney+copy(hzUnit,((iLen-i-3) mod 8)+1,1);
end
else
szChMoney:=szChMoney+copy(mnUnit,((iLen-i) mod 3)+1,1);
end;
if Trim(szChMoney)='' then
szChMoney:='零元整'
else
if copy(szNum,Length(szNum),1)='0' then szChMoney:=szChMoney+'整';
Result:=szChMoney;
end;----------------
以上的算法,万位为0的时候出错了,比如要转换101000就出错请大家帮帮我,谢谢大家!!!
const
mnUnit:String='分角元';
hzUnit:String='拾佰仟万拾佰仟亿拾佰仟万拾佰仟';
hzNum:String='零壹贰叁肆伍陆柒捌玖';
var
szChMoney,szNum:String;
iLen, iNum, iAddZero,i:integer;
function DRound(Value:double;cnt:byte):double;
var
fTmp:double;
nTmp:double;
k:int64;
begin
Result:=Value;
if cnt>18 then exit;
nTmp:=Power(10.0,cnt);
fTmp:=0.5;
fTmp:=fTmp/nTmp;
Result:=fTmp+Result;
Result:=Result*nTmp;
k:=0;
asm
fld qword ptr Result
//__ftol begin
push ebp
mov ebp,esp
LEA ESP,k
wait
fstcw word ptr [ebp-$04]
wait
mov al,[ebp-$03]
or [ebp-$04],$00000c01
fldcw word ptr [ebp-$04]
fistp qword ptr [ebp-$0c]
mov [ebp-$03],al
fldcw word ptr [ebp-$04]
mov eax ,[ebp-$0c]
mov edx,[ebp-$08]
mov esp,ebp
pop ebp
//__ftol end
push esp
lea esp,k
mov [esp],eax
add esp,4
mov [esp],edx
mov esp,ebp
pop esp
fild qword ptr k
fstp qword ptr Result
fld qword ptr nTmp
fdivr qword ptr Result
fstp qword ptr Result
end;
end;
begin
iAddZero:=0;
szNum:=FormatFloat('0', DRound(Num,2)*100.0); //这样可能会有数字误差,double只有15位有效数字,这里只有13
Result:='';
iLen:=Length(szNum);
if Pos('E',UpperCase(szNum))>0 then exit;
if (iLen>18) or (iLen=0) or (Num<0) then exit; //数据错误返回 for i:=1 to iLen do
begin
iNum:=StrToInt(copy(szNum,i,1));
if iNum=0 then
begin
if (((iLen-i-2) mod 4)=0) and ((iLen-i-3)>0) and (((iLen-i)>=8) or (iAddZero<3)) then
szChMoney:=copy(szChMoney+hzUnit,((iLen-i-3) mod 8)+1,1);
inc(iAddZero);
end
else
begin
if ((iAddZero>0) and ((iLen-i)>=2)) and (((iLen-i-1) mod 4)<>0) then
szChMoney:=szChMoney+copy(hzNum,1,1);
szChMoney:=szChMoney+copy(hzNum,iNum+1,1);
iAddZero:=0;
end;
if (iAddZero<1) or ((iLen-i)=2) then
if (iLen-i)>=3 then
begin
szChMoney:=szChMoney+copy(hzUnit,((iLen-i-3) mod 8)+1,1);
end
else
szChMoney:=szChMoney+copy(mnUnit,((iLen-i) mod 3)+1,1);
end;
if Trim(szChMoney)='' then
szChMoney:='零元整'
else
if copy(szNum,Length(szNum),1)='0' then szChMoney:=szChMoney+'整';
Result:=szChMoney;
end;----------------
以上的算法,万位为0的时候出错了,比如要转换101000就出错请大家帮帮我,谢谢大家!!!
function TfrmRPDesigner.FloatToCnMoney(Num: Double): string;
const
mnUnit:String='分角元';
hzUnit:String='拾佰仟万拾佰仟亿拾佰仟万拾佰仟';
hzNum:String='零壹贰叁肆伍陆柒捌玖';
var
szChMoney,szNum:String;
iLen, iNum, iAddZero,i:integer;
function DRound(Value:double;cnt:byte):double;
var
fTmp:double;
nTmp:double;
k:int64;
begin
Result:=Value;
if cnt>18 then exit;
nTmp:=Power(10.0,cnt);
fTmp:=0.5;
fTmp:=fTmp/nTmp;
Result:=fTmp+Result;
Result:=Result*nTmp;
k:=0;
asm
fld qword ptr Result
//__ftol begin
push ebp
mov ebp,esp
LEA ESP,k
wait
fstcw word ptr [ebp-$04]
wait
mov al,[ebp-$03]
or [ebp-$04],$00000c01
fldcw word ptr [ebp-$04]
fistp qword ptr [ebp-$0c]
mov [ebp-$03],al
fldcw word ptr [ebp-$04]
mov eax ,[ebp-$0c]
mov edx,[ebp-$08]
mov esp,ebp
pop ebp
//__ftol end
push esp
lea esp,k
mov [esp],eax
add esp,4
mov [esp],edx
mov esp,ebp
pop esp
fild qword ptr k
fstp qword ptr Result
fld qword ptr nTmp
fdivr qword ptr Result
fstp qword ptr Result
end;
end;
begin
iAddZero:=0;
szNum:=FormatFloat('0', DRound(Num,2)*100.0); //这样可能会有数字误差,double只有15位有效数字,这里只有13
Result:='';
iLen:=Length(szNum);
if Pos('E',UpperCase(szNum))>0 then exit;
if (iLen>18) or (iLen=0) or (Num<0) then exit; //数据错误返回 for i:=1 to iLen do
begin
iNum:=StrToInt(copy(szNum,i,1));
if iNum=0 then
begin
if (((iLen-i-2) mod 4)=0) and ((iLen-i-3)>0) and (((iLen-i)>=8) or (iAddZero<3)) then
szChMoney:=copy(szChMoney+hzUnit,((iLen-i-3) mod 8)+1,1);
inc(iAddZero);
end
else
begin
if ((iAddZero>0) and ((iLen-i)>=2)) and (((iLen-i-1) mod 4)<>0) then
szChMoney:=szChMoney+copy(hzNum,1,1);
szChMoney:=szChMoney+copy(hzNum,iNum+1,1);
iAddZero:=0;
end;
if (iAddZero<1) or ((iLen-i)=2) then
if (iLen-i)>=3 then
begin
szChMoney:=szChMoney+copy(hzUnit,((iLen-i-3) mod 8)+1,1);
end
else
szChMoney:=szChMoney+copy(mnUnit,((iLen-i) mod 3)+1,1);
end;
if Trim(szChMoney)='' then
szChMoney:='零元整'
else
if copy(szNum,Length(szNum),1)='0' then szChMoney:=szChMoney+'整';
Result:=szChMoney;
end;
不好意思,这个是缩进的了
2. 调试可知首次问题出现在开头的下列语句。
if iNum=0 then
begin
if (((iLen-i-2) mod 4)=0) and ((iLen-i-3)>0) and (((iLen-i)>=8) or (iAddZero<3)) then
szChMoney:=copy(szChMoney+hzUnit,((iLen-i-3) mod 8)+1,1);
inc(iAddZero);
end
3. 对于这种转换问题,个人倾向用递归方式解决。