高精度(万进制,加减乘,比较,转换)

高精度(万进制,加减乘,比较,转换)

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.

0
0
(请您对文章做出评价)
posted @ 2010-04-08 10:21  jesonpeng  阅读(489)  评论(0编辑  收藏  举报