高精度都应该很熟练了,原理什么的也就不用多说。
当你把高精度加减乘除都摞在一起,就会有很神奇的事情发生——大模板诞生:
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)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.