高精度(万进制,加减乘,比较,转换)
高精度(万进制,加减乘,比较,转换)
http://hi.baidu.com/mfs666/blog/item/4512bc38bec5b5c4d56225bc.html
复赛前,我会把需要的基本算法自己写一遍,以保证自己“真的会写”,省去基本算法出问题在调试的问题。本系列保证都是新鲜的自写代码。。。
今天先发高精度。因为貌似06,07年都用到了高精度(2^k进制数,矩阵取数游戏),虽然说连着考的东西靠的概率就会大大降低,但是还是要写的。因为我现在要做这两个题,所以就先把高精度写了。
希望神牛们看到的话,花一两分钟帮忙看一下有没有什么BUG,十分感谢,预先Orz。。。
program gaojing;
type
bn=array[0..500] of longint;// 高精数字类型
var
a,b,p,s,m:bn;
s:string;
t,l:longint;
f,d:boolean;
function max(x,y:longint):longint;
begin
if x>y then
max:=x
else
max:=y;
end;
function sn(q:string):bn;// 数字串转换为高精度数
var
i,ls:longint;
begin
fillchar(sn,sizeof(sn),0);
ls:=length(q);
sn[0]:=(ls+3) div 4;// 由串长度计算高精度数长度
for i:=1 to sn[0]-1 do
val(copy(q,ls+1-i*4,4),sn[i]); // 从串尾开始分割,4位一个,位置到时候一看就知道了
val(copy(q,1,ls-(sn[0]-1)*4),sn[sn[0]]);// 最后一位高精数,也就是数串的首部,可能长度不足4,要单独处理
end;
function ns(q:bn):string; // 高精度数转换为数字串
var
i,j:longint;
t:string;
begin
str(q[q[0]],t);// 最后一位高精数不能加0,同样需单独处理
ns:=t;
for i:=q[0]-1 downto 1 do
begin
str(q[i],t);
for j:=1 to 4-length(t) do
t:='0'+t;// 其他高精位要补零
ns:=ns+t;
end;
end;
function da(x,y:bn):boolean;// 高精比较 之前的版本不对,必须优先比较长度,位数多的一定大。。。
var
i,l:longint;
begin
if x[0]>y[0] then begin
da:=true;
exit;
end;
if x[0]<y[0] then begin
da:=false;
exit;
end;
l:=x[0];
for i:=l downto 1 do
begin
if x[i]>y[i] then begin
da:=true;
exit;
end;
if x[i]<y[i] then begin
da:=false;
exit;
end;
end;
da:=false;
f:=true;
end;
function ap(x,y:bn):bn;// 高精加
var
i:longint;
begin
fillchar(ap,sizeof(ap),0);
ap[0]:=max(y[0],x[0]); //长度等于较大的那个
for i:=1 to ap[0] do begin
inc(ap[i],x[i]+y[i]); // 进位已记录,所以用inc
if ap[i]>9999 then begin //这样效率会稍高,特别是只加的话可以压到8个数字每位,加减会比取mod快
inc(ap[i+1]);
ap[i]:=ap[i]-10000;
end;
end;
if ap[ap[0]+1]<>0 then
inc(ap[0]);// 增加位数
end;
function ad(x,y:bn):bn;// 高精减,已保证x>y
var
i:longint;
begin
fillchar(ad,sizeof(ad),0);
ad[0]:=x[0];// 长度一定是大的那个的长度(大于等于小的)
for i:=1 to ad[0] do begin
if x[i]<y[i] then begin
dec(ad[i+1]);
inc(ad[i],10000);
end;
ad[i]:= ad[i]+x[i]-y[i];// 借位已记录,所以加ad[i]
end;
while (ad[ad[0]]=0) and (ad[0]>1) do // 除去变成0的位,注意那个>1必须有!!
dec(ad[0]);
end;
function am(x,y:bn):bn;// 高精乘
var
i,j:longint;
begin
fillchar(am,sizeof(am),0);
am[0]:=x[0]+y[0];// 位数计算
for i:=1 to x[0] do
for j:=1 to y[0] do begin
inc(am[i+j-1],x[i]*y[j]); // i+j-1定位 进位已记录,故用inc 注意,在这个地方要看清楚i,j。。。!!
inc(am[i+j],am[i+j-1] div 10000);
am[i+j-1]:=am[i+j-1] mod 10000;
end;
while (am[am[0]]=0) and (am[0]>1) do // 除去无效位
dec(am[0]);
end;
begin
readln(s);
a:=sn(s);
readln(s);
b:=sn(s);
p:=ap(a,b);
m:=am(a,b);
s:=ad(a,b);
d:=da(a,b);
s:=ns(p);
writeln(s,' ',d);
end.