高精度乘除运算优化
方案一:扩大进制
1 var s1,s2:string; 2 procedure multiply(s1,s2:string); 3 var a,b,c:array[1..500]of longint; 4 i,j,j1,j2,l,k,code:longint; 5 begin 6 fillchar(a,sizeof(a),0); 7 fillchar(b,sizeof(b),0); 8 fillchar(c,sizeof(c),0); 9 j1:=0; l:=length(s1); 10 while l>0 do begin 11 inc(j1); 12 val(copy(s1,l-3,4),a[j1],code); 13 s1:=copy(s1,1,l-4); l:=length(s1); 14 end; 15 j2:=0; l:=length(s2); 16 while l>0 do begin 17 inc(j2); 18 val(copy(s2,l-3,4),b[j2],code); 19 s2:=copy(s2,1,l-4); l:=length(s2); 20 end; 21 k:=0; 22 for i:=1 to j1 do 23 for j:=1 to j2+1 do begin 24 c[i+j-1]:=c[i+j-1]+a[i]*b[j]+k; 25 k:=c[i+j-1] div 10000; 26 c[i+j-1]:=c[i+j-1] mod 10000; 27 end; 28 if c[i+j]=0 then k:=j1+j2-1 else k:=j1+j2; 29 write(c[k]); 30 for i:=k-1 downto 1 do begin 31 if c[i]<10 then write('000',c[i]) else 32 if c[i]<100 then write('00',c[i]) else 33 if c[i]<1000 then write('0',c[i]) else 34 write(c[i]); 35 end; writeln; 36 end; 37 begin 38 readln(s1); 39 readln(s2); 40 multiply(s1,s2); 41 end.
方案二:建立质因子表
任何自然数都可以表示为,n=p1^k1×p2^k2,…,×pt^kt的形式,p1,p2,…,pt为质因子。设num数组为自然数n,其中num[i]为因子i的次幂数(1≤i≤k)。显然,num[k],num[k-1],…,num[2]构成了一个自然数,该自然数可以用十进制整数数组ans存储。
ans的计算过程如下:
ans[1] ←1; {将num转换为ans}
for i←2 to k do {枚举每一个因子}
for j←1 to num[i] do multiply(ans,i); {连乘num[i]个因子i}
multiply的过程为高精数乘普通数的乘法运算。
有了自然数n的因子表num,就可以十分方便地进行乘法或除法运算。例如整数x 含有k个因子i,
经过乘法或除法后,
我们按照上述方法依次处理x的每一个因子,得出的num即为积或商。
1 procedure add(x,ob:longint); {ob=1,num←num * x;ob=-1,nurn←num/x} 2 var i:longint; 3 begin 4 for i←2 to x do {搜索x的每一个因子i} 5 while(x mod i=0) do {计算x含因子i的个数k。 6 begin 7 inc(num[i],ob); 8 x←x div i; 9 end;{while} 10 end;{add}
显然,如果n1=xl*x2*,…,*xk,则可以通过连续调用add(x1,1);add(x2,1);…;add(xk,1); 得出nl对应的因子表num。
如果
则可以通过连续调用add(x1,-1); add(x2,-1); …; add(xk,-1); 得出n2对应的因子表num。注意,初始时num数组清零。
所以,该优化方法适用于普通数乘或者除普通数的高精运算。