由于标准的数字变量类型取值有限,如果需要进行运算的数字超过了范围,用标准的数字变量类型就显得无能为力了!下面的四个函数利用Delphi中的字符串对象实现了大数运算。
加法、乘法由zswang编写
function StrLeft(const mStr: string; mDelimiter: string): string; begin Result := Copy(mStr, 1, Pos(mDelimiter, mStr) - 1); end; { StrLeft }
function StrRight(const mStr: string; mDelimiter: string): string; begin if Pos(mDelimiter, mStr) <= 0 then Result := '' else Result := Copy(mStr, Pos(mDelimiter, mStr) + Length(mDelimiter), MaxInt); end; { StrRight }
function formatnum(mNumber: string):string; 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;
function InfiniteAdd(mNumberA, mNumberB: string): string; { 无限位数加法 } 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 }
function InfiniteMult(mNumberA, mNumberB: string): string; { 无限位数乘法 }
function fMult(mNumber: string; mByte: Byte): string; { 无限位数乘法子函数 } 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 }
var 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 }
function InfiniteSub(mNumberA, mNumberB: string): string; { 无限位数减法 } 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}
function InfiniteDiv(mNumberA, mNumberB: string;n:integer): string; { 无限位数除法 } //n为有效数字个数
function vDecimal(mNumber: string):integer; 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;
function formatnum2(mNumber: string):string; 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;
var 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}
一时消遣娱乐之作~~~ 
|