高精度算法集合
引用来源:
高精度加法
12345678910111213 + 1111111111111111111
开两个数组存储:
a[]={3,1,2,1,1,1,0,1,9,8,7,6,5,4,3,2,1};
b[]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
两个数组分别把数值倒存,在一位一位的加,每位加后判断是否大于10,在进位(注:如果太大的数值,可以考虑4位一存哦.) 注意下面的a1,b1,c1 为 数组的长度
View Code
1 if a1>b1 then
2 c1:=a1
3 else
4 c1:=b1;
5 for i:=1 to c1 do
6 begin
7 c[i]:=a[i]+b[i];
8 c[i+1]:=c[i+1]+c[i]div 10;
9 c[i]:=c[i] mod 10;
10 end;
11 while c[c1+1]>0 do
12 begin
13 inc(c1);
14 c[c1+1]:=c[c1+1]+c[c1]div 10;
15 c[c1]:=c[c1] mod 10;
16 end;
四位一存:
View Code
1 var s:ansistring;
2 a,b:array[1..11000]of int64;
3 x:array[1..51000]of int64;
4 c:array[1..35000]of int64;
5 i,j,a1,b1,c1,d,x1:longint;
6 begin
7 while not eof do
8 begin
9 fillchar(c,sizeof(c),0);
10 readln(s);
11 x1:=length(s);
12 for i:=1 to x1 do x[i]:=ord(s[x1-i+1])-48;
13 for i:=1 to (x1 div 5) do
14 a[i]:=x[5*i]*10000+x[5*i-1]*1000+x[5*i-2]*100+x[5*i-3]*10+x[5*i-4];
15 a1:=x1 div 5;
16 if x1 mod 5<>0 then
17 begin
18 d:=0;
19 for i:=1 to x1 mod 5 do
20 d:=d*10+x[x1-i+1];
21 a1:=a1+1;
22 a[a1]:=d;
23 end;
24 readln(s);
25 fillchar(x,sizeof(x),0);
26 x1:=length(s);
27 for i:=1 to x1 do x[i]:=ord(s[x1-i+1])-48;
28 for i:=1 to (x1 div 5) do
29 b[i]:=x[5*i]*10000+x[5*i-1]*1000+x[5*i-2]*100+x[5*i-3]*10+x[5*i-4];
30 b1:=x1 div 5;
31 if x1 mod 5<>0 then
32 begin
33 d:=0;
34 for i:=1 to x1 mod 5 do
35 d:=d*10+x[x1-i+1];
36 b1:=b1+1;
37 b[b1]:=d;
38 end;
39 for i:=1 to a1 do
40 for j:=1 to b1 do
41 c[i+j-1]:=c[i+j-1]+a[i]*b[j];
42 c1:=a1+b1-1;
43 for i:=1 to c1 do
44 if c[i]>99999 then
45 begin
46 c[i+1]:=c[i+1]+c[i] div 100000;
47 c[i]:=c[i] mod 100000;
48 end;
49 while c[c1+1]>0 do
50 begin
51 inc(c1);
52 c[c1+1]:=c[c1+1] + c[c1] div 100000;
53 c[c1]:=c[c1] mod 100000;
54 end;
55 write(c[c1]);
56 for i:=c1-1 downto 1 do
57 begin
58 if c[i]=0 then write('00000')
59 else if c[i]<10 then write('0000',c[i])
60 else if c[i]<100 then write('000',c[i])
61 else if c[i]<1000 then write('00',c[i])
62 else if c[i]<10000 then write('0',c[i])
63 else write(c[i]);
64 end;
65 writeln;
66 end;
67 end.
高精度减法
View Code
1 var
2 x,y,r:string;
3 la,lb,i,t:integer;
4 a,b:array[1..1000] of integer;
5 begin
6 readln(x);
7 readln(y);
8 la:=length(x);
9 lb:=length(y);
10 if (lb>la) or (lb=la) and (y>x) then
11 begin
12 r:=x;
13 x:=y;
14 y:=r;
15 write('-');
16 t:=la;
17 la:=lb;
18 lb:=t;
19 end;
20 for i:=1 to la do
21 a[i]:=ord(x[la+1-i])-48;
22 for i:=1 to lb do
23 b[i]:=ord(y[lb+1-i])-48;
24 for i:=1 to la do
25 begin
26 a[i]:=a[i]-b[i];
27 a[i+1]:=a[i+1]+ord(a[i]>=0)-1;
28 a[i]:=a[i]+ord(a[i]<0)*10;
29 end;
30 t:=la;
31 while (a[t]=0)and(t<>1) do t:=t-1;
32 for i:=t downto 1 do
33 write(a[i]);
34 writeln;
35 end.
--SepHiRoTH 18:59 2009年5月17日 (CST)
高精度乘法
四位一计算:
View Code
高精度除法
只提供程序段,未处理循环小数。
View Code
1 procedure highdevide(a,b:hp; var c,d:hp); //高精度除法 高精度/高精度
2 var
3 i,len:integer;
4 begin
5 fillchar(c,sizeof(c),0);
6 fillchar(d,sizeof(d),0);
7 len:=a[0];d[0]:=1;
8 for i:=len downto 1 do begin
9 multiply(d,10,d);
10 d[1]:=a[i];
11 while(compare(d,b)>=0) do {即d>=b}
12 begin
13 Subtract(d,b,d);
14 inc(c[i]);
15 end;
16 end;
17 while(len>1)and(c.s[len]=0) do dec(len);
18 c.len:=len;
19 end;
解释: hp为数组定义 type hp:array[1..max] of integer; a[0],b[0],c[0],d[0]为数组的长度 再在主程序里打出来 如:for i:=x[0] downto 1 do write(x[i]); write('.'); for i:=1 to y[0] do write(y[i]); writeln; x为商的整数部分,y为商的小数部分。
--Taophee 22:24 2011年8月20日
请看到这个问题的OIers注意并及时给出正确解法,最近忙于琐事,拜托了,这个网站很久无人管理了。--SepHiRoTH 23:02 2011年7月30日 (CST)
算法已改。 --Taophee 22:24 2011年8月20日
做一下循环小数,这需要加一段,既然做了就把 它做好怎样?--SepHiRoTH 08:20 2011年8月21日 (CST)
高精度阶乘
作为一种高精度乘法的扩展算法,实质为高精度乘低精度,算法如下:
View Code
1 var
2 a:array[1..10000] of longint;
3 i,j,k,l,p,o,q,x,y,w:integer;
4 begin
5 read(i);
6 a[1]:=1;
7 w:=1;
8 for j:=1 to i do
9 begin
10 y:=0; //到“For”前可省,但改为for k:=1 to 10000 do
11 x:=j;
12 while x>0 do
13 begin
14 y:=y+1;
15 x:=x div 10;
16 end;
17 o:=0;
18 for k:=w to l+y+1 do
19 begin
20 q:=a[k]*j+o;
21 o:=q div 10;
22 a[k]:=q mod 10;
23 end;
24 l:=10000;
25 while (a[l]=0) and (l>1) do l:=l-1;
26 w:=1;
27 while (a[w]=0) and (w<9999) do w:=w+1;
28 end;
29 for p:=l downto 1 do
30 write(a[p]);
31 writeln;
32 end.
--SepHiRoTH 18:59 2009年5月17日 (CST)
高精度快速幂
主要用了二分的手段。中间的乘法就看上面的吧。 --By Clarkok
View Code
1 function Power(a:high;b:longint):high;
2 begin
3 power:=power(a,b shr 1);
4 power:=mult(power,power);
5 if odd(b) then
6 power:=mult(power,a);
7 end;
顺便附送个高精度的单元,FPC可用:高精度单元