由于标准的数字变量类型取值有限,如果需要进行运算的数字超过了范围,用标准的数字变量类型就显得无能为力了!下面的四个函数利用Delphi中的字符串对象实现了大数运算。 加法、乘法由zswang编写 function StrLeft(const mStr: string; mDelimiter: string): string; function StrRight(const mStr: string; mDelimiter: string): string; function formatnum(mNumber: string):string; function InfiniteAdd(mNumberA, mNumberB: string): string; { 无限位数加法 } function InfiniteMult(mNumberA, mNumberB: string): string; { 无限位数乘法 } function fMult(mNumber: string; mByte: Byte): string; { 无限位数乘法子函数 } var function InfiniteSub(mNumberA, mNumberB: string): string; { 无限位数减法 } function InfiniteDiv(mNumberA, mNumberB: string;n:integer): string; { 无限位数除法 } function vDecimal(mNumber: string):integer; function formatnum2(mNumber: string):string; var 一时消遣娱乐之作~~~
begin
Result := Copy(mStr, 1, Pos(mDelimiter, mStr) – 1);
end; { StrLeft }
begin
if Pos(mDelimiter, mStr) <= 0 then
Result :=
else Result := Copy(mStr, Pos(mDelimiter, mStr) + Length(mDelimiter), MaxInt);
end; { StrRight }
var
m:integer;
TemStr:string;
begin
Result:=;
for m:=1 to Length(mNumber) do
begin
if mNumber[m]=. then
Result:=Result+.
else
Result:=Result+IntToStr(StrToIntDef(mNumber[m], 0));
end;
while Pos(0, Result) = 1 do Delete(Result, 1, 1); //排除整数前无效的0
if Pos(., Result )<= 0 then Result := Result + .; //没有有小数点补小数点
TemStr:=StrRight(Result,.);
while Copy(TemStr, Length(TemStr), 1) = 0 do Delete(TemStr, Length(TemStr), 1); //排除小数后无效的0
Result:=StrLeft(Result,.)+.+TemStr;
if Copy(Result, Length(Result), 1) = . then Delete(Result, Length(Result), 1); //排除无效小数点
if Copy(Result, 1, 1)=. then Result:=0+Result;
if (Result = ) then Result := 0;
end;
var
I: Integer;
T: Integer;
begin
Result := ;
if Pos(., mNumberA) <= 0 then mNumberA := mNumberA + .; //没有有小数点补小数点
if Pos(., mNumberB) <= 0 then mNumberB := mNumberB + .; //没有有小数点补小数点
I := Max(Length(StrLeft(mNumberA, .)), Length(StrLeft(mNumberB, .))); //整数部分最大长度
mNumberA := DupeString(0, I – Length(StrLeft(mNumberA, .))) + mNumberA; //整数前补0
mNumberB := DupeString(0, I – Length(StrLeft(mNumberB, .))) + mNumberB; //整数前补0
T := Max(Length(StrRight(mNumberA, .)), Length(StrRight(mNumberB, .))); //小数部分最大长度
mNumberA := mNumberA + DupeString(0, T – Length(StrRight(mNumberA, .))); //小数后补0
mNumberB := mNumberB + DupeString(0, T – Length(StrRight(mNumberB, .))); //小数后补0
I := I + T + 1; //计算总长度//小数长度和整数长度加上小数点长度
T := 0; //进位数初始化
for I := I downto 1 do //从后向前扫描
if [mNumberA[I], mNumberB[I]] <> [.] then begin //不是小数点时
T := StrToIntDef(mNumberA[I], 0) + T; //累加当前数位
T := StrToIntDef(mNumberB[I], 0) + T; //累加当前数位
Result := IntToStr(T mod 10) + Result; //计算当前数位上的数字
T := T div 10; //计算进位数
end else Result := . + Result; //加上小数点
if T <> 0 then Result := IntToStr(T mod 10) + Result; //处理进位数
while Pos(0, Result) = 1 do Delete(Result, 1, 1); //排除整数前无效的0
while Copy(Result, Length(Result), 1) = 0 do
Delete(Result, Length(Result), 1); //排除小数后无效的0
if Copy(Result, Length(Result), 1) = . then
Delete(Result, Length(Result), 1); //排除无效小数点
if Copy(Result, 1, 1) = . then Result := 0 + Result; //处理无0小数情况
if (Result = ) then Result := 0; //处理空字符情况
end; { InfiniteAdd }
var
I: Integer;
T: Integer;
begin
Result := ;
T := 0;
for I := Length(mNumber) downto 1 do begin //从后向前扫描
T := StrToIntDef(mNumber[I], 0) * mByte + T; //累加当前数位
Result := IntToStr(T mod 10) + Result; //计算当前数位上的数字
T := T div 10; //计算进位数
end;
if T <> 0 then Result := IntToStr(T mod 10) + Result; //处理进位数
end; { fMult }
I: Integer;
vDecimal: Integer; //小数位数
T: string;
begin
Result := ;
///////Begin 处理小数
if Pos(., mNumberA) <= 0 then mNumberA := mNumberA + .; //没有有小数点补小数点
if Pos(., mNumberB) <= 0 then mNumberB := mNumberB + .; //没有有小数点补小数点
vDecimal := Length(StrRight(mNumberA, .)) + Length(StrRight(mNumberB, .)); //计算小数位数
mNumberA := StrLeft(mNumberA, .) + StrRight(mNumberA, .); //删除小数点
mNumberB := StrLeft(mNumberB, .) + StrRight(mNumberB, .); //删除小数点
///////End 处理小数
T := ;
for I := Length(mNumberB) downto 1 do begin
Result := InfiniteAdd(Result, fMult(mNumberA, StrToIntDef(mNumberB[I], 0)) + T);
T := T + 0;
end;
Insert(., Result, Length(Result) – vDecimal + 1);
while Pos(0, Result) = 1 do Delete(Result, 1, 1); //排除整数前无效的0
while Copy(Result, Length(Result), 1) = 0 do
Delete(Result, Length(Result), 1); //排除小数后无效的0
if Copy(Result, Length(Result), 1) = . then
Delete(Result, Length(Result), 1); //排除无效小数点
if Copy(Result, 1, 1) = . then Result := 0 + Result; //处理无0小数情况
if (Result = ) then Result := 0; //处理空字符情况
end; { InfiniteMult }
var
I: Integer;
T: Integer;
TemNumA:String;
minus:Boolean;
begin
Result := ;
mNumberA:=formatnum(mNumberA);
mNumberB:=formatnum(mNumberB);
if Pos(., mNumberA) <= 0 then mNumberA := mNumberA + .; //没有有小数点补小数点
if Pos(., mNumberB) <= 0 then mNumberB := mNumberB + .; //没有有小数点补小数点
I := Max(Length(StrLeft(mNumberA, .)), Length(StrLeft(mNumberB, .))); //整数部分最大长度
mNumberA := DupeString(0, I – Length(StrLeft(mNumberA, .))) + mNumberA; //整数前补0
mNumberB := DupeString(0, I – Length(StrLeft(mNumberB, .))) + mNumberB; //整数前补0
T := Max(Length(StrRight(mNumberA, .)), Length(StrRight(mNumberB, .))); //小数部分最大长度
if ((Length(StrLeft(mNumberA, .))) > (Length(StrLeft(mNumberB, .)))) or(((Length(StrLeft(mNumberA, .))) = (Length(StrLeft(mNumberB, .))))and(mNumberB>mNumberA))then
begin
TemNumA := mNumberA;
mNumberA := mNumberB + DupeString(0, T – Length(StrRight(mNumberB, .))); //小数后补0
mNumberB := TemNumA + DupeString(0, T – Length(StrRight(TemNumA, .))); //小数后补0
minus:=True;
end
else
begin
mNumberA := mNumberA + DupeString(0, T – Length(StrRight(mNumberA, .))); //小数后补0
mNumberB := mNumberB + DupeString(0, T – Length(StrRight(mNumberB, .))); //小数后补0
minus:=False;
end;
I := I + T + 1; //计算总长度//小数长度和整数长度加上小数点长度
T := 0; //进位数初始化
for I := I downto 1 do //从后向前扫描
if [mNumberA[I], mNumberB[I]] <> [.] then begin //不是小数点时
T := StrToIntDef(mNumberB[I], 0) – T; //累加当前数位
T := StrToIntDef(mNumberA[I], 0) – T; //累加当前数位
if (T<0) and (I<>1) then
begin
T:=T+10;
Result := IntToStr(T mod 10) + Result; //计算当前数位上的数字
T := -1; //计算进位数
end
else
begin
Result := IntToStr(T mod 10) + Result; //计算当前数位上的数字
T := T div 10; //计算进位数
end;
end else Result := . + Result; //加上小数点
if T <> 0 then Result := IntToStr(T mod 10) + Result; //处理进位数
while Pos(0, Result) = 1 do Delete(Result, 1, 1); //排除整数前无效的0
while Copy(Result, Length(Result), 1) = 0 do
Delete(Result, Length(Result), 1); //排除小数后无效的0
if Copy(Result, Length(Result), 1) = . then
Delete(Result, Length(Result), 1); //排除无效小数点
if Copy(Result, 1, 1) = . then Result := 0 + Result; //处理无0小数情况
if (Result = ) then Result := 0; //处理空字符情况
if minus then Result:=-+Result;
end; { InfiniteSub}
//n为有效数字个数
var m,x:integer;
begin
x:=0;
if Pos(., mNumber) <= 0 then
begin
for m:=Length(mNumber) downto 1 do
begin
if mNumber[m]=0 then x:=x+1 else Break;
end;
Result:=-x;
end
else
Result:=Length(StrRight(mNumber, .));
end;
begin
Result:=mNumber;
if Pos(., Result )<= 0 then Result := Result + .;
Result:=StrLeft(Result,.)+StrRight(Result,.);
while Pos(0, Result) = 1 do
Delete(Result, 1, 1);//排除整数前无效的0
while Copy(Result, Length(Result), 1) = 0 do
Delete(Result, Length(Result), 1);//排除小数后无效的0
end;
I,J,t,v,y,Len: Integer;
TemSub,TemNum: string;
begin
Result := ;
mNumberA:=formatnum(mNumberA);
mNumberB:=formatnum(mNumberB);
v:=vDecimal(mNumberA)-vDecimal(mNumberB);
mNumberA:=formatnum2(mNumberA);
mNumberB:=formatnum2(mNumberB);
if mNumberB= then
Result:=Err
else if mNumberA= then
Result:=0
else
begin
I:=0;
if Length(mNumberA)>Length(mNumberB) then
Len:=Length(mNumberB)
else
Len:=Length(mNumberA);
if Copy(mNumberA,1,Len)>=Copy(mNumberB,1,Len) then
J:=Length(mNumberB)
else
J:=Length(mNumberB)+1;
for y:=1 to J do
begin
if Length(mNumberA)>=y then
TemSub:=TemSub+mNumberA[y]
else
begin
TemSub:=TemSub+0;
v:=v+1;
end;
end;
while I<=n-1 do
begin
if TemSub[1]>mNumberB[1] then
t:=StrToInt(TemSub[1]) Div StrToInt(mNumberB[1])
else
t:=StrToInt(TemSub[1]+TemSub[2]) Div StrToInt(mNumberB[1]);
TemNum:=InfiniteMult(mNumberB,IntToStr(t));
while (Length(TemNum)>Length(TemSub)) or ((Length(TemNum)=Length(TemSub))and(TemNum>TemSub)) do
begin
t:=t-1;
TemNum:=InfiniteMult(mNumberB,IntToStr(t));
end;
Result:=Result+IntToStr(t);
I:=I+1;
TemSub:=InfiniteSub(TemSub,TemNum);
if (TemSub=0) and (Length(mNumberA)<J) then
begin
v:=v+1;
Break;
end;
if TemSub=0 then TemSub:=;
J:=J+1;
if Length(mNumberA)>=J then
begin
TemSub:=TemSub+mNumberA[J];
end
else
begin
TemSub:=TemSub+0;
v:=v+1;
end;
end;
if Length(mNumberA)>=J then
v:=v-(Length(mNumberA)-J)-1
else
v:=v-1;
while Copy(Result, Length(Result), 1) = 0 do
begin
v:=v-1;
Delete(Result, Length(Result), 1);
end;
if v>Length(Result) then
Result:=.+DupeString(0,v-Length(Result)) + Result
else if v>0 then
Insert(., Result, Length(Result) – v +1); //插入小数点
if v<0 then Result:=Result+DupeString(0,0-v);
if Copy(Result, 1, 1)=. then Result:=0+Result; //小数前面补0
end;
end; { InfiniteDiv}