1. 程式人生 > >過載“+-*/”實現高精度運算

過載“+-*/”實現高精度運算

       在只進行加法和減法時,我們可以壓八位來加快速度,當有乘法時,壓八位會爆int所以我們壓四位。 高精度除法壓位比較難寫,所以我們不選擇壓位。在程式的前端宣告一個變數P來記錄壓位的位數,M記錄壓N位時對應的最小的數,即可使程式更容易除錯。

const int M=100000000,
               P=8;
//輸出可以這樣寫
printf("%*d",P,n[i]);


加減,壓八位,輸出補零

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int M=100000000,
		  P=8; 	//壓位

struct bignum 
{
	int n[5000],l; 	//n陣列存放每個結構體中的"大數",l記錄長度。
	bignum(){l=1,memset(n,0,sizeof(n));}
//-----------------------------------------------
	void init() 	//輸入過程
	{
		string s;
		cin>>s;
		int now=0,ct=0,c1=1; //now記錄當前是n陣列的第幾位,ct記錄已經讀入多少字元了,滿八進一,c1是輔助變數,因為我們是倒著讀入,所以每次要乘10 
		for(int i=s.length()-1;i>=0;i--)  //從s的長度-1開始 
		{
			n[now]+=(s[i]-'0')*c1;
			c1*=10;
			ct++;
			if(ct==P&&i!=0)  // 如果i=0了就沒有必要now++; 
			{
				now++;
				ct=0;
				c1=1;
			}		
		}
		l=now+1;   //l的長度為now+1; 
	}
	void print()
	{
		printf("%d",n[l-1]);
		for(int i=l-2;i>=0;i--)	
		printf("%0*d",P,n[i]);  //補零輸出 
		printf("\n");
	}
//-----------------------------------------------
	bignum operator + (bignum x) const 	//過載加號
	{
		bignum t=*this;
		if(x.l>t.l)t.l=x.l;
		for(int i=0;i<t.l;i++)
		{
			t.n[i]+=x.n[i];
			if(t.n[i]>=M)
			{
				t.n[i+1]+=t.n[i]/M;
				t.n[i]%=M;
			}
		}
		return t;			//  注意:將t的值返回 
	} 
//------------------------------------------------
	bool operator < (bignum x) const  	//過載小於號 
	{
		bignum t=*this;
		if(t.l!=x.l)return t.l<x.l;
		for(int i=t.l-1;i>=0;i--)
		{
			if(t.n[i]!=x.n[i]) return t.n[i]<x.n[i];
		}
		return 0;
	}
	bignum operator -(bignum x) const	//過載減號 
	{
		bignum t=*this;
		if(t<x){printf("-");swap(t,x);}
		int jie =0;
		for(int i=0;i<t.l;i++)
		{
			t.n[i]-=x.n[i];
			while(t.n[i]<0)
			{
				t.n[i]+=M;
				jie++;		
			}
			t.n[i+1]-=jie;
			jie=0;
		}
		while(!t.n[t.l-1] && t.l>1)t.l--;  // 相減後有可能出現前面有0的情況,所以t.l--; 
		return t;
	}
//----------------------------------------------
}a,b,c;

int main()
{
	a.init();		//讀入字串a和b 
	b.init();
	
	c=a+b;				
	c.print();

	c=a-b;
	c.print();
	
	c=a*b;
	c.print();
		 
	return 0;
} 

加減乘,壓四位,輸出補零

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int M=10000,
		  P=4; 	//壓位

struct bignum 
{
	int n[5000],l; 	//n陣列存放每個結構體中的"大數",l記錄長度。
	bignum(){l=1,memset(n,0,sizeof(n));}
//-----------------------------------------------
	void init() 	//輸入過程
	{
		string s;
		cin>>s;
		int now=0,ct=0,c1=1; //now記錄當前是n陣列的第幾位,ct記錄已經讀入多少字元了,滿八進一,c1是輔助變數,因為我們是倒著讀入,所以每次要乘10 
		for(int i=s.length()-1;i>=0;i--)  //從s的長度-1開始 
		{
			n[now]+=(s[i]-'0')*c1;
			c1*=10;
			ct++;
			if(ct==P&&i!=0)  // 如果i=0了就沒有必要now++; 
			{
				now++;
				ct=0;
				c1=1;
			}		
		}
		l=now+1;   //l的長度為now+1; 
	}
	void print()
	{
		printf("%d",n[l-1]);
		for(int i=l-2;i>=0;i--)	
		printf("%0*d",P,n[i]);  //補零輸出 
		printf("\n");
	}
//-----------------------------------------------
	bignum operator + (bignum x) const 	//過載加號
	{
		bignum t=*this;
		if(x.l>t.l)t.l=x.l;
		for(int i=0;i<t.l;i++)
		{
			t.n[i]+=x.n[i];
			if(t.n[i]>=M)
			{
				t.n[i+1]+=t.n[i]/M;
				t.n[i]%=M;
			}
		}
		return t;			//  注意:將t的值返回 
	} 
//------------------------------------------------
	bool operator < (bignum x) const  	//過載小於號 
	{
		bignum t=*this;
		if(t.l!=x.l)return t.l<x.l;
		for(int i=t.l-1;i>=0;i--)
		{
			if(t.n[i]!=x.n[i]) return t.n[i]<x.n[i];
		}
		return 0;
	}
	bignum operator -(bignum x) const	//過載減號 
	{
		bignum t=*this;
		if(t<x){printf("-");swap(t,x);}
		int jie =0;
		for(int i=0;i<t.l;i++)
		{
			t.n[i]-=x.n[i];
			while(t.n[i]<0)
			{
				t.n[i]+=M;
				jie++;		
			}
			t.n[i+1]-=jie;
			jie=0;
		}
		while(!t.n[t.l-1] && t.l>1)t.l--;  // 相減後有可能出現前面有0的情況,所以t.l--; 
		return t;
	}
//------------------------------------------------
	bignum operator *(bignum x) const //過載乘號 
	{
		bignum t=*this,tep;
		tep.l=t.l+x.l-1;
		for(int i=0;i<t.l;i++)
		for(int j=0;j<x.l;j++)
		{
			tep.n[i+j]+=t.n[i]*x.n[j];
			if(tep.n[i+j]>=M)
			{
				tep.n[i+j+1]+=tep.n[i+j]/M;
				tep.n[i+j]%=M;
			}
		}
		while(tep.n[tep.l])
		{
			tep.n[tep.l+1]+=tep.n[tep.l]/M;
			tep.n[tep.l++]%=M;
		}
		return tep;
	}
//-----------------------------------------
}a,b,c;

int main()
{
	a.init();		//讀入字串a和b 
	b.init();
	
	c=a+b;				
	c.print();

	c=a-b;
	c.print();
	
	c=a*b;
	c.print();
		 
	return 0;
} 
	

加減乘除,不壓位

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int M=10,
		  P=1; 	//壓位

struct bignum 
{
	int n[5000],l; 	//n陣列存放每個結構體中的"大數",l記錄長度。
	bignum(){l=1,memset(n,0,sizeof(n));}
//-----------------------------------------------
	void init() 	//輸入過程
	{
		string s;
		cin>>s;
		int now=0,ct=0,c1=1; //now記錄當前是n陣列的第幾位,ct記錄已經讀入多少字元了,滿八進一,c1是輔助變數,因為我們是倒著讀入,所以每次要乘10 
		for(int i=s.length()-1;i>=0;i--)  //從s的長度-1開始 
		{
			n[now]+=(s[i]-'0')*c1;
			c1*=10;
			ct++;
			if(ct==P&&i!=0)  // 如果i=0了就沒有必要now++; 
			{
				now++;
				ct=0;
				c1=1;
			}		
		}
		l=now+1;   //l的長度為now+1; 
	}
	void print()
	{
		printf("%d",n[l-1]);
		for(int i=l-2;i>=0;i--)	
		printf("%0*d",P,n[i]);  //補零輸出 
		printf("\n");
	}
//-----------------------------------------------
	bignum operator + (bignum x) const 	//過載加號
	{
		bignum t=*this;
		if(x.l>t.l)t.l=x.l;
		for(int i=0;i<t.l;i++)
		{
			t.n[i]+=x.n[i];
			if(t.n[i]>=M)
			{
				t.n[i+1]+=t.n[i]/M;
				t.n[i]%=M;
			}
		}
		return t;			//  注意:將t的值返回 
	} 
//------------------------------------------------
	bool operator < (bignum x) const  	//過載小於號 
	{
		bignum t=*this;
		if(t.l!=x.l)return t.l<x.l;
		for(int i=t.l-1;i>=0;i--)
		{
			if(t.n[i]!=x.n[i]) return t.n[i]<x.n[i];
		}
		return 0;
	}
	bignum operator -(bignum x) const	//過載減號 
	{
		bignum t=*this;
		if(t<x){printf("-");swap(t,x);}
		int jie =0;
		for(int i=0;i<t.l;i++)
		{
			t.n[i]-=x.n[i];
			while(t.n[i]<0)
			{
				t.n[i]+=M;
				jie++;		
			}
			t.n[i+1]-=jie;
			jie=0;
		}
		while(!t.n[t.l-1] && t.l>1)t.l--;  // 相減後有可能出現前面有0的情況,所以t.l--; 
		return t;
	}
//------------------------------------------------
	bignum operator *(bignum x) const //過載乘號 
	{
		bignum t=*this,tep;
		tep.l=t.l+x.l-1;
		for(int i=0;i<t.l;i++)
		for(int j=0;j<x.l;j++)
		{
			tep.n[i+j]+=t.n[i]*x.n[j];
			if(tep.n[i+j]>=M)
			{
				tep.n[i+j+1]+=tep.n[i+j]/M;
				tep.n[i+j]%=M;
			}
		}
		while(tep.n[tep.l])
		{
			tep.n[tep.l+1]+=tep.n[tep.l]/M;
			tep.n[tep.l++]%=M;
		}
		return tep;
	}
//-----------------------------------------
	void Add(int x){if(x||l)n[l++]=x;}  //除法 
	void Re(){reverse(n,n+l);}          //高精度除以高精度
	bignum operator /(const bignum &x)const
	{
		bignum t=*this,r,y;
		y.l=0,r.l=t.l;
		for(int i=t.l-1;i>=0;--i)
		{
			y.Add(t.n[i]);
			y.Re();
			while(!(y<x))y=y-x,r.n[i]++;
			while(!y.n[y.l-1] && y.l>=1)--y.l;
            y.Re();
		}
		while(!r.n[r.l-1] && r.l>1)--r.l;
		return r;
	}bignum operator /(const int &x)const        //高精度除以單精度
         {
             bignum t=*this,r;
             r.l=t.l;
  	    int tmp=0;
  	    for(int i=t.l-1;i>=0;--i)
   	    {
   		tmp+=t.n[i];
   		if(tmp>=x)
    		r.n[i]+=tmp/x,tmp%=x;
   		tmp*=M;
  	    }
  	    while(!r.n[r.l-1] && r.l>1)--r.l;
  	    return r;
         }
}a,b,c;

int main()
{
	a.init();		//讀入字串a和b 
	b.init();
	
	c=a+b;				
	c.print();

	c=a-b;
	c.print();
	
	c=a*b;
	c.print();
	
	c=a/b;
	c.print();	 
	return 0;
} 
			


最後剽竊一個功能更豐富的- - 

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
const int M=10,P=1; 


struct BigNum
{
       int n[5000],l,Y;
       BigNum(){l=1,memset(n,0,sizeof(n));}
       //----------------------------------
       void init()
       {
            string s;
            cin>>s;
            int now=0,ct=0,c1=1;
            for(int i=s.length()-1;i>=0;i--)
            {
             n[now]+=(s[i]-'0')*c1;
             c1*=10;
             ct++;
             if(ct==P&&i!=0)
             {
              now++;
              c1=1;
              ct=0;
             }        
            }
            l=now+1;     
       }
       //-----------------------------------
       void print()
       {
            printf("%d",n[l-1]);
            for(int i=l-2;i>=0;i--)
            printf("%0*d",P,n[i]);
            printf("\n");
       }
       //------------------------------------
       BigNum operator +(BigNum x)const
       {
              BigNum t=*this;
              if(x.l>t.l)t.l=x.l;
              for(int i=0;i<t.l;i++)
              {
               t.n[i]+=x.n[i];
               if(t.n[i]>=M)
               {
                   t.n[i+1]+=t.n[i]/M;
                   t.n[i]%=M;             
               }        
              }
              while(t.n[t.l])
              {
                  t.n[t.l+1]+=t.n[t.l]/M;
                  t.n[t.l++]%=M;               
              }     
              return t;  
       }
       //--------------------------------------
       bool operator < (BigNum x) const
       {
           BigNum t=*this;
           if(t.l!=x.l)return t.l<x.l;
           for(int i=t.l-1;i>=0;i--)
           {
              if(t.n[i]!=x.n[i])return t.n[i]<x.n[i];        
           }
           return 0;       
       }
       BigNum operator -(BigNum x)const
       {
           BigNum t=*this;
           if(t<x){printf("-");swap(t,x);} 
           for(int i=0;i<t.l;i++)
           {
            t.n[i]-=x.n[i];
            if(t.n[i]<0)
            {
                t.n[i]+=M;
                --t.n[i+1];            
            }        
           } 
           while(!t.n[t.l-1]&&t.l>1)t.l--;
           return t;     
       }
       //--------------------------------------------
       BigNum operator * (BigNum x) const
       {
              BigNum c,t=*this;
              c.l=t.l+x.l-1;
              for(int i=0;i<t.l;i++)
              for(int j=0;j<x.l;j++)
              {
                  c.n[i+j]+=t.n[i]*x.n[j];
                  if(c.n[i+j]>=M)
                  {
                      c.n[i+j+1]+=c.n[i+j]/M;
                      c.n[i+j]%=M;               
                  }        
              }
              while(c.n[c.l])
              {
                   c.n[c.l+1]+=c.n[c.l]/M;
                   c.n[c.l++]%=M;               
              }       
              return c;
       }
       BigNum operator * (int x) const
       {
          BigNum t=*this,c;
          c.l=t.l;
          for(int i=0;i<t.l;i++)
          {
              c.n[i]+=t.n[i]*x;
              if(c.n[i]>=M)
              {
                   c.n[i+1]+=c.n[i]/M;
                   c.n[i]%=M;             
              }        
          }       
          while(c.n[c.l])
          {
                 c.n[c.l+1]+=c.n[c.l]/M;
                 c.n[c.l++]%=M;               
          }
          return c;
       }
       //--------------------------------------------
    void Add(int x){if(x||l)n[l++]=x;}
    void Re(){reverse(n,n+l);}
    BigNum operator /(const BigNum &x)const
    {
        BigNum t=*this,r,y;
        y.l=0,r.l=t.l;
        for(int i=t.l-1;i>=0;--i)
        {
            y.Add(t.n[i]);
            y.Re();
            while(!(y<x))y=y-x,r.n[i]++;
            while(!y.n[y.l-1] && y.l>1)--y.l;
            y.Re();
        }
        while(!r.n[r.l-1] && r.l>1)--r.l;
        return r;
    }
    BigNum operator /(const int &x)const
    {
        BigNum t=*this,r;
        r.l=t.l;
        int tmp=0;
        for(int i=t.l-1;i>=0;--i)
        {
            tmp+=t.n[i];
            if(tmp>=x)
                r.n[i]+=tmp/x,tmp%=x;
            tmp*=M;
        }
        while(!r.n[r.l-1] && r.l>1)--r.l;
        return r;
    }
       //---------------------------------------
       
}a,b,c;


int main()
{
    a.init();
    b.init();
    
    c=a+b;
    c.print();
    
    c=a-b;
    c.print();
    
    c=a*b;
    c.print();
    
    c=a/b;
    c.print();
    return 0;        
}