分享
 
 
 

“无限”位四则运算

王朝delphi·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

由于标准的数字变量类型取值有限,如果需要进行运算的数字超过了范围,用标准的数字变量类型就显得无能为力了!下面的四个函数利用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}

一时消遣娱乐之作~~~

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有