「疯狂的高精度」高精度大模板

来源:互联网 发布:期刊数据库 编辑:程序博客网 时间:2024/05/17 08:07

高精度都应该很熟练了,原理什么的也就不用多说。

当你把高精度加减乘除都摞在一起,就会有很神奇的事情发生——大模板诞生:

Pascal代码:

program High_Precision;var  os1,os2,os,md:ansistring;  ch:char;  u,v,l:integer;function High_Precision_Addition(s1,s2:ansistring):ansistring;    //高精度加法  var    a,b:array[1..1000000] of integer;    la,lb,k:integer;    i:integer;    s:ansistring;  begin    High_Precision_Addition:='';    la:=length(s1);    lb:=length(s2);    fillchar(a,sizeof(a),0);    fillchar(b,sizeof(b),0);    for i:=1 to la do a[i]:=ord(s1[la-i+1])-48;      for i:=1 to lb do b[i]:=ord(s2[lb-i+1])-48;    if la>lb then k:=la else k:=lb;    for i:=1 to k do      begin        a[i+1]:=a[i+1]+(a[i]+b[i]) div 10;        a[i]:=(a[i]+b[i]) mod 10;      end;    if a[k+1]>0 then k:=k+1;    for i:=k downto 1 do      begin        str(a[i],s);        High_Precision_Addition:=High_Precision_Addition+s;      end;  end;function High_Precision_Subtraction(s1,s2:ansistring):ansistring;//高精度减法  var    a,b:array[1..1000000] of integer;    s,p:ansistring;    la,lb,k:integer;    i:integer;    symbol:char;   begin    High_Precision_Subtraction:='';    fillchar(a,sizeof(a),0);    fillchar(b,sizeof(b),0);    if s1=s2 then begin writeln(0) ;halt; end;    if (length(s1)<length(s2)) or ((length(s1)=length(s2)) and(s1<s2)) then      begin        symbol:='-';        s:=s1; s1:=s2; s2:=s;      end;    la:=length(s1); lb:=length(s2);    for i:=1 to la do a[i]:=ord(s1[la-i+1])-48;    for i:=1 to lb do b[i]:=ord(s2[lb-i+1])-48;    k:=la;    for i:=1 to k do      begin        if a[i]<b[i] then          begin            a[i+1]:=a[i+1]-1;            a[i]:=a[i]+10;          end;        a[i]:=a[i]-b[i];      end;    while a[k]=0 do k:=k-1;    if symbol='-' then High_Precision_Subtraction:=symbol+High_Precision_Subtraction;    for i:=k downto 1 do      begin        str(a[i],p);        High_Precision_Subtraction:=High_Precision_Subtraction+p;      end;   end;function High_Precision_Multiplication(s1,s2:ansistring):ansistring;//高精度乘法  var    la,lb,lc,x,i,j:longint;    a,b,c:array [1..1000000] of longint;    s:ansistring;  begin    la:=length(s1);lb:=length(s2);    for i:=1 to la do a[la-i+1]:=ord(s1[i])-48;    for i:=1 to lb do b[lb-i+1]:=ord(s2[i])-48;    for i:=1 to la do      begin        x:=0;        for j:=1 to lb do          begin            x:=a[i]*b[j]+x div 10+c[i+j-1];            c[i+j-1]:=x mod 10;          end;        c[i+j]:=x div 10;      end;    lc:=i+j;    while (c[lc]=0)and(lc>1) do lc:=lc-1;    for i:=lc downto 1 do      begin        str(c[i],s);        High_Precision_Multiplication:=High_Precision_Multiplication+s;      end;  end;  function High_Precision_Division(s1,s2:ansistring;temp:integer):ansistring;//高精度除法(temp:{‘0’:相除保留10位小数;‘1’:取模;‘2’:求商})  type    hp=record         len:integer;         s:array[1..1000000] of integer;       end;  var    x:array[1..2] of hp;      y,w:hp;       s:ansistring;  procedure out(const p:hp);    var      i:integer;    begin      for i:=p.len downto 1 do        begin          str(p.s[i],s);          High_Precision_Division:=High_Precision_Division+s;        end;    end;  procedure init;    var      j,i:integer;    begin      if temp=0 then s1:=s1+'0000000000';             //提前加长保留10位小数      x[1].len:=length(s1);      for i:=1 to x[1].len do          x[1].s[i]:=ord(s1[x[1].len+1-i])-48;      x[2].len:=length(s2);      for i:=1 to x[2].len do                 x[2].s[i]:=ord(s2[x[2].len+1-i])-48;    end;  procedure subtract(a,b:hp;var c:hp);     var      i,len:integer;    begin      fillchar(c,sizeof(c),0);      if a.len>b.len then len:=a.len else len:=b.len;      for i:=1 to len do        begin          inc(c.s[i],a.s[i]-b.s[i]);          if c.s[i]<0 then            begin              inc(c.s[i],10);              dec(c.s[i+1]);            end;        end;      while (len>1) and (c.s[len]=0) do dec(len);       c.len:=len;    end;  function compare(const a,b:hp):integer;     var      len:integer;    begin      if a.len>b.len then len:=a.len else len:=b.len;      while (len>0) and (a.s[len]=b.s[len]) do dec(len);      if len=0 then compare:=0      else compare:=a.s[len]-b.s[len];    end;  procedure multiply10(var a:hp);         var      i:integer;    begin      for i:=a.len downto 1 do a.s[i+1]:=a.s[i];      a.s[1]:=0;                                   inc(a.len);      while (a.len>1) and (a.s[a.len]=0) do dec(a.len);    end;  procedure divide(a,b:hp;var c,d:hp);        var      i,j,len:integer;    begin      fillchar(c,sizeof(c),0);                   len:=a.len;      fillchar(d,sizeof(d),0);       d.len:=1;      for i:=len downto 1 do        begin          multiply10(d);                      d.s[1]:=a.s[i];           while (compare(d,b)>=0) do             begin              subtract(d,b,d);              inc(c.s[i]);                          end;        end;      while (len>1) and (c.s[len]=0) do dec(len);      c.len:=len;    end;  begin    init;                               divide(x[1],x[2],y,w);       if temp=0 then       begin         out(y);        insert('.',High_Precision_Division,length(High_Precision_Division)-9); //加上小数点      end;      if temp=1 then out(w);     if temp=2 then out(y);       end;function Quick_Power(s1,s2,modulus:ansistring):ansistring;  //高精度快速幂  var    t,y:ansistring;    x,l:integer;  begin    t:='1'; y:=s1;    while s2<>'0' do      begin        val(s2[length(s2)],x,l);        if odd(x)=true then t:= High_Precision_Multiplication(High_Precision_Division(t,modulus,1) , High_Precision_Division(y,modulus,1)); //t:=(t mod modulus)*(y mod modulus)        y:=High_Precision_Multiplication(High_Precision_Division(y,modulus,1) , High_Precision_Division(y,modulus,1));  //y:=(y mod modulus)^2;  这里如果模数很大,就先不再加大代码长度,在外面套一个取模了(按理应该加上的)        s2:=High_Precision_Division(s2,'2',2);       end;    exit(High_Precision_Division(t,modulus,1));  end;begin  readln(os1);  readln(ch);  readln(os2);  case ch of                                                 //在主过程里处理运算符问题及符号问题    '+':begin   {加法}           if (os1[1]='-')and(os2[1]='-') then              begin               delete(os1,1,1);               delete(os2,1,1);               writeln(High_Precision_Addition(os1,os2));               halt;            end;           if (os1[1]='-')and(os2[1]<>'-') then             begin                delete(os1,1,1);                writeln('-',High_Precision_Subtraction(os2,os1));                halt;             end;           if (os1[1]<>'-')and(os2[1]<>'-') then              begin               writeln(High_Precision_Addition(os1,os2));               halt;             end;           if (os1[1]<>'-')and(os2[1]='-') then             begin               delete(os2,1,1);               writeln(High_Precision_Subtraction(os1,os2));               halt;             end;         end;    '-':begin  {减法}           if (os1[1]='-')and(os2[1]='-') then             begin               delete(os1,1,1);               delete(os2,1,1);               writeln(High_Precision_Subtraction(os2,os1));               halt;            end;           if (os1[1]='-')and(os2[1]<>'-') then             begin               delete(os1,1,1);               writeln('-',High_Precision_Addition(os1,os2));               halt;             end;           if (os1[1]<>'-')and(os2[1]<>'-') then              begin               writeln(High_Precision_Subtraction(os1,os2));               halt;             end;           if (os1[1]<>'-')and(os2[1]='-') then              begin               delete(os2,1,1);               writeln(High_Precision_Addition(os1,os2));               halt;             end;         end;    '*':begin  {乘法}           if (os1[1]='-')and(os2[1]='-') then             begin               delete(os1,1,1);               delete(os2,1,1);               writeln(High_Precision_Multiplication(os1,os2));               halt;             end;           if (os1[1]<>'-')and(os2[1]<>'-') then             begin               writeln(High_Precision_Multiplication(os1,os2));               halt;             end;           if (os1[1]='-')and(os2[1]<>'-')then             begin               delete(os1,1,1);               writeln('-',High_Precision_Multiplication(os1,os2));               halt;             end;           if (os1[1]<>'-')and(os2[1]='-') then             begin               delete(os2,1,1);               writeln('-',High_Precision_Multiplication(os1,os2));               halt;             end;         end;    '/':begin  {除法}           if (os1[1]='-')and(os2[1]='-') then             begin               delete(os1,1,1);               delete(os2,1,1);               writeln(High_Precision_Division(os1,os2,0));               halt;             end;           if (os1[1]<>'-')and(os2[1]<>'-') then              begin               writeln(High_Precision_Division(os1,os2,0));               halt;             end;           if (os1[1]<>'-')and(os2[1]='-') then              begin               delete(os2,1,1);               writeln('-',High_Precision_Division(os1,os2,0));               halt;             end;           if (os1[1]='-')and(os2[1]<>'-') then             begin               delete(os1,1,1);               writeln('-',High_Precision_Division(os1,os2,0));               halt;             end;         end;    '%':begin  {取模}            if (os1[1]='-')and(os2[1]='-') then              begin                delete(os1,1,1);                delete(os2,1,1);                writeln('-',High_Precision_Division(os1,os2,1));                halt;              end;            if (os1[1]='-')and(os2[1]<>'-') then              begin                delete(os1,1,1);                writeln(High_Precision_Division(os1,os2,1));                halt;              end;            if (os1[1]<>'-')and(os2[1]='-') then              begin                 delete(os2,1,1);                writeln('-',High_Precision_Division(os1,os2,1));                halt;              end;            if (os1[1]<>'-')and(os2[1]<>'-') then               begin                writeln(High_Precision_Division(os1,os2,1));                halt;              end;          end;    '^':begin  {乘方}            readln(md);              //由于乘方会炸,这里建议再读入一个模数            val(os2[length(os2)],v,l);            if (os1[1]='-')and(odd(v)=true) then              begin                delete(os1,1,1);                if (os2[1]='-') then                   begin                    delete(os2,1,1);                    writeln('-',High_Precision_Division('1',Quick_Power(os1,os2,md),0));                  end                else                  writeln('-',Quick_Power(os1,os2,md));                halt;              end;            if (os1[1]<>'-')and(odd(v)=true) then              begin                if (os2[1]='-') then                  begin                    delete(os2,1,1);                    writeln(High_Precision_Division('1',Quick_Power(os1,os2,md),0));                  end                else                  writeln(Quick_Power(os1,os2,md));                halt;              end;            if (os1[1]='-')and(odd(v)=false) then              begin                delete(os1,1,1);                if (os2[1]='-') then                  begin                    delete(os2,1,1);                    writeln(High_Precision_Division('1',Quick_Power(os1,os2,md),0));                  end                else                  writeln(Quick_Power(os1,os2,md));                halt;              end;            if (os1[1]<>'-')and(odd(v)=false) then              begin                if (os2[1]='-') then                  begin                    delete(os2,1,1);                    writeln(High_Precision_Division('1',Quick_Power(os1,os2,md),0));                  end                else                  writeln(Quick_Power(os1,os2,md));                halt;              end;      end;  end;end.

0 0
原创粉丝点击