BIGNUM - Xử lý số nguyên lớn

Tác giả: flashmt

Ngôn ngữ: Pascal

const base=100000000;
      digit=8;
      maxk=130000;
type bignum=array[0..maxk] of int64;
var a,b,c,d,re:bignum;
    e:array[1..1000] of char;
    bg:boolean;


procedure rf(var a:bignum);
var s:string; i,m,j:longint; c:char; code:integer; t:int64;
begin
     fillchar(a,sizeof(a),0);
     while not eoln do
     begin
          inc(a[0]);
          read(e[a[0]]);
     end;
     m:=a[0] mod digit;
     if m=0 then m:=digit;
     a[0]:=(a[0]+digit-1) div digit;
     s:='';
     for i:=1 to m do s:=s+e[i];
     val(s,t,code);
     a[a[0]]:=t;
     for i:=0 to a[0]-2 do
     begin
          s:='';
          for j:=1 to digit do s:=s+e[m+j+i*digit];
          val(s,t,code);
          a[a[0]-i-1]:=t;
     end;
end;

function big:boolean;
var i:longint;
begin
     big:=a[0]>b[0];
     if a[0]=b[0] then
     begin
          big:=true;
          for i:=a[0] downto 1 do
              if a[i]>b[i] then break
              else
              begin
                   if a[i]<b[i] then
                   begin
                        big:=false;
                        break;
                   end;
              end;
     end;
end;

procedure wr(var k:bignum);
var s:string; t,j,i:longint;
begin
     for i:=k[0] downto 1 do
     begin
          if i<k[0] then
          begin
               str(k[i],s);
               t:=length(s);
               for j:=t+1 to digit do write(0);
          end;
          write(k[i]);
     end;
     writeln;
end;

procedure plus;
var i,max:longint; mem:int64;
begin
     fillchar(c,sizeof(c),0);
     mem:=0;
     if a[0]>b[0] then max:=a[0] else max:=b[0];
     for i:=1 to max do
     begin
          c[i]:=(a[i]+b[i]+mem) mod base;
          mem:=(a[i]+b[i]+mem) div base;
     end;
     if mem>0 then
     begin
          inc(max);
          c[max]:=mem;
     end;
     c[0]:=max;
     wr(c);
end;

procedure minus;
var i,max:longint; mem:int64;
begin
     fillchar(c,sizeof(c),0);
     mem:=0;
     if not bg then
     begin
          write('-');
          d:=a; a:=b; b:=d;
     end;
     max:=a[0];
     for i:=1 to a[0] do
     begin
          if a[i]<b[i]+mem then
          begin
               c[i]:=a[i]+base-b[i]-mem;
               mem:=1;
          end
          else
          begin
               c[i]:=a[i]-b[i]-mem;
               mem:=0;
          end;
     end;
     while (c[max]=0) and (max>1) do dec(max);
     c[0]:=max;
     wr(c);
end;

procedure multi;
var i,j,max,maxr:longint; mem,t:int64;
begin
     fillchar(re,sizeof(re),0);
     maxr:=a[0];
     for i:=1 to b[0] do
     begin
          mem:=0;
          fillchar(c,sizeof(c),0);
          c[0]:=a[0];
          for j:=1 to a[0] do
          begin
               c[j]:=(a[j]*b[i]+mem) mod base;
               mem:=(a[j]*b[i]+mem) div base;
          end;
          if mem>0 then
          begin
               inc(c[0]);
               c[c[0]]:=mem;
          end;
          mem:=0;
          for j:=1 to c[0] do
          begin
               t:=c[j]+re[j+i-1]+mem;
               re[j+i-1]:=t mod base;
               mem:=t div base;
          end;
          j:=c[0]+i-1;
          if j>maxr then maxr:=j;
          while mem>0 do
          begin
               inc(j);
               if j>maxr then maxr:=j;
               t:=mem+re[j];
               re[j]:=t mod base;
               mem:=t div base;
          end;
     end;
     re[0]:=maxr;
     wr(re);
end;

begin
     rf(a);
     readln;
     rf(b);
     bg:=big;
     plus;
     minus;
     multi;
end.

Download