高精度算法

王朝百科·作者佚名  2010-01-22  
宽屏版  字体:   |    |    |  超大  

在一般的科学计算中,会经常算到小数点后几百位或者更多,当然也可能是几千亿几百亿的大数字.

一般这类数字我们统称为高精度数,高精度算法是用计算机对于超大数据的一种模拟加,减,乘,除,乘方,阶乘,开方等运算.

譬如一个很大的数字N >= 10^ 100, 很显然这样的数字无法在计算机中正常存储.

于是, 我们想到了办法,将这个数字拆开,拆成一位一位的 或者是四位四位的存储到一个数组中, 用一个数组去表示一个数字.这样这个数字就被称谓是高精度数.

对于高精度数,也要像平常数一样做加减乘除以及乘方的运算,于是就有了高精度算法:

下面提供了Pascal的高精度加法, 高精度乘以单精度, 高精度乘以高精度的代码, 其他版本请各位大牛添加进来吧!

Pascal代码如下(非完整); k为预定进制,加大进制以提高速度。

Procedure HPule(a, b: Arr; Var c:Arr); //高精度加法

Var

i: Integer;

Begin

FillChar(c, SizeOf(c), 0);

For i:= 1 To Maxn-1 Do Begin

c[i]:= c[i] + a[i] + b[i];

c[i + 1] := c[i] Div k;

c[i] := c[i] Mod k;

End;

End;

Procedure HPule(a: Arr; b:Integer; Var c:Arr); //高精度乘以单精度

Var

i: Integer;

Begin

FillChar(c, SizeOf(c), 0);

For i:= 1 To Maxn-1 Do Begin

c[i] := c[i] + a[i] * b;

c[i+1]:= c[i] Div k;

c[i]:= c[i] Mod k

End;

End;

Procedure HPule(a, b: Arr; ; Var c:Arr); //高精度乘以高精度

Var

i, j: Integer;

Begin

FillChar(c, SizeOf(c), 0);

For i:= 1 To Maxn Do

For j := 1 To Maxn Begin

c[i+j-1] := c[i+j-1] + a[i] * b[j];

c[i+j]:= c[i+j-1] Div k;

c[i+j-1]:= c[i+j-1] Mod k

End;

End;

Ps:为了防止王朝错误识别, 过程中有不少符号是全角状态输入.

高精度加法

var

a,b,c:array[1..201] of 0..9;

n:string;

lena,lenb,lenc,i,x:integer;

begin

write('Input augend:'); readln(n);lena:=length(n);

for i:=1 to lena do a[lena-i+1]:=ord(n)-ord('0');{加数放入a数组}

write('Input addend:'); readln(n); lenb:=length(n);

for i:=1 to lenb do b[lenb-i+1]:=ord(n)-ord('0');{被加数放入b数组}

i:=1;

while (i<=lena) or(i<=lenb) do

begin

x := a + b + x div 10; {两数相加,然后加前次进位}

c := x mod 10; {保存第i位的值}

i := i + 1

end;

if x>=10 {处理最高进位}

then begin lenc:=i; c:=1 end

else lenc:=i-1;

for i:=lenc downto 1 do write(c); writeln {输出结果}

end.

高精度乘法(低对高)

const max=100; n=20;

var a:array[1..max]of 0..9;

i,j,k;x:integer;

begin

k:=1; a[k]:=1;{a=1}

for i:=2 to n do{a*2*3….*n}

begin

x:=0;{进位初始化}

for j:=1 do k do{a=a*i}

begin

x:=x+a[j]*i; a[j]:=x mod 10;x:=x div 10

end;

while x>0 do {处理最高位的进位}

begin

k:=k+1;a[k]:=x mod 10;x:=x div 10

end

end;

writeln;

for i:=k dowento 1 write(a){输出a}

end.

高精度乘法(高对高)

var a,b,c:array[1..200] of 0..9;

n1,n2:string; lena,lenb,lenc,i,j,x:integer;

begin

write('Input multiplier:'); readln(n1);

write('Input multiplicand:'); readln(n2);

lena:=length(n1); lenb:=length(n2);

for i:=1 to lena do a[lena-i+1]:=ord(n1)-ord('0');

for i:=1 to lenb do b[lenb-i+1]:=ord(n2)-ord('0');

for i:=1 to lena do

begin

x:=0;

for j:=1 to lenb do{对乘数的每一位进行处理}

begin

x := a*b[j]+x div 10+c;{当前乘积+上次乘积进位+原数}

c:=x mod 10;

end;

c:= x div 10;{进位}

end;

lenc:=i+j;

while (c[lenc]=0) and (lenc>1) do dec(lenc); {最高位的0不输出}

for i:=lenc downto 1 do write(c); writeln

end.

高精度除法

fillchar(s,sizeof(s),0);{小数部分初始化}

fillchar(posi,sizeof(posi),0); {小数值的位序列初始化}

len←0;st←0; {小数部分的指针和循环节的首指针初始化}

read(x,y);{读被除数和除数}

write(x div y);{输出整数部分}

x←x mod y;{计算x除以y的余数}

if x=0 then exit;{若x除尽y,则成功退出}

while len<limit do{若小数位未达到上限,则循环}

begin

inc(len);posi[x]←len;{记下当前位小数,计算下一位小数和余数}

x←x*10; s[len]←x div y;x←x mod y;

if posi[x]<>0 {若下一位余数先前出现过,则先前出现的位置为循环节的开始}

then begin st←posi[x]; break;end;{then}

if x=0 then break; {若除尽,则成功退出}

end;{while}

if len=0

then begin writeln;exit;end;{若小数部分的位数为0,则成功退出;否则输出小数点}

write('.');

if st=0 {若无循环节,则输出小数部分,否则输出循环节前的小数和循环节}

then for i←1 to len do write(s)

else begin

for i←1 to st-1 do write(s);

write('(');

for i←st to len do write(s);

write(')');

end;{else}

 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝百科 版权所有