大数运算,队列实现大数 加法、乘法、除法、模除

以下代码可进行大数加法、减法、乘法、除法、余除,和比较大小的计算(队列实现)包括负数

【代码】:

#include<cstdio>         
#include<cstring>         
#include<iostream>       
#include<string>        
#include<queue>          
#include<stack>          
using namespace std;     
const int mod=1e9;
typedef long long ll;
const int M=1e8;//亿进制
class BigNum{
private:
	queue<ll> q;
	bool sign;//0 for positive , 1 for negetive;
public:
	BigNum(ll);//构造函数
	BigNum(char*);
	
	friend BigNum operator+(BigNum,BigNum);
	friend BigNum operator-(BigNum,BigNum);
	friend BigNum operator*(BigNum,BigNum);
	friend BigNum operator/(BigNum,ll);
	friend ll operator%(BigNum,ll);
	
	friend int mycmp(BigNum,BigNum);//比较大小 1 for >,-1 for <,0 for == 
    friend ostream& operator<<(ostream&,BigNum&);
    friend istream& operator>>(istream&,BigNum&);
};
BigNum::BigNum(ll n=0)
{
	while(!q.empty())q.pop();
	sign=0;
	if(n<0){
		sign=true;
		n=-n;
	}
    do{  
        q.push(n%M);
        n/=M;
    }while(n);
}
BigNum::BigNum(char *str)//把字符串转化成队列型大数        
{
	while(!q.empty())q.pop();
	sign=0;//默认正数
    ll len=strlen(str),num=0,k=1;  
    for(int i=len-1;i>=0;i--)       
    {
    	if(i==0){
    		if(str[i]=='+')break;
    		if(str[i]=='-'){
    			sign=1;break;
			}
		}
        num+=k*(str[i]-'0');
        k*=10;
        if(k>=M)
        {
            q.push(num);
            num=0;k=1;
        }
    }
    if(num!=0||q.empty())q.push(num);
    if(q.size()==1&&q.front()==0)sign=0;//-0 == 0 
}
void out(queue<ll> q)//递归输出队列大数
{
    if(q.size()==1){
        printf("%lld",q.front());
        return;
    }
    ll num=q.front();q.pop();
    out(q);
    printf("%08lld",num);
} 
ostream& operator<<(ostream& stream,BigNum& val)
{  
    if(val.sign)
        stream<<"-";
    out(val.q);
    return stream;
}
istream& operator>>(istream& stream, BigNum& val)
{
    char s[10101];
    scanf("%s",s);
    val=BigNum(s);
    return stream;
}
int mycmp(BigNum a,BigNum b)
{
	if(a.sign&&!b.sign)return -1;//<
	if(!a.sign&&b.sign)return 1;
	int k=1;//记两个都正
	if(a.sign&&b.sign)k=-1;
    if(a.q.size()==b.q.size())
    {  
        ll num1,num2,flag=0;  
        while(!a.q.empty())
        {  
            num1=a.q.front();a.q.pop();  
            num2=b.q.front();b.q.pop();  
            if(num1!=num2)  
                flag=num1-num2;
        }
        if(!flag)return 0;
        return k*(flag>0?1:(-1));
    }
    int t=a.q.size()-b.q.size();
    return k*( t>0?1:(-1) );
}
BigNum operator+(BigNum a,BigNum b)//加
{
    ll flag=0;//进位
    if(a.sign&&!b.sign)//转化为两正数相减 
	{
		a.sign=0;
		return b-a;
	}
    if(!a.sign&&b.sign)
	{
		b.sign=0;
		return a-b;
	}
    BigNum sum;
    while(!sum.q.empty())sum.q.pop();
    if(a.sign&&b.sign)sum.sign=1;//negetive
    while(!a.q.empty()||!b.q.empty())        
    {          
        ll num1=0,num2=0;
        if(!a.q.empty()){          
            num1=a.q.front();          
            a.q.pop();          
        }          
        if(!b.q.empty()){
            num2=b.q.front();
            b.q.pop();
        }
        sum.q.push((flag+num1+num2)%M);
        flag=(num1+num2+flag)/M;
    }          
    if(flag)        
        sum.q.push(flag);   
    return sum;        
}

BigNum operator-(BigNum a,BigNum b)//a-b
{
    if(!a.sign&&b.sign)
    {
    	b.sign=0;
    	return a+b;
	}
	if(a.sign&&!b.sign)
    {
    	b.sign=1;
    	return a+b;
	}
    BigNum less;
    int ship=mycmp(a,b);//同正或同负 
	if(ship==0)return less;
    else if(ship<0)
    {
    	less.sign=1;//a-b<0
    	if(!a.sign&&!b.sign)//两个正数
    	{
    		BigNum c=a;a=b;b=c;
		}
	}
	else if(a.sign&&b.sign)
	{
		BigNum c=a;a=b;b=c;
	}
    while(!less.q.empty())less.q.pop();
    while(!a.q.empty())
    {          
        ll num1=0,num2=0;  
        num1=a.q.front();
        a.q.pop();
        if(!b.q.empty()){
            num2=b.q.front();
            b.q.pop();
        }
        if(num1<num2){
            a.q.front()-=1;
            num1+=M;//从q1高位借1,当M  
        }
        less.q.push(num1-num2);
    }
    return less;
}      

BigNum operator*(BigNum a,BigNum b)//大数乘大数
{          
    BigNum ans;
    while(!ans.q.empty())ans.q.pop();
    ll k=0;
    while(!b.q.empty())//模拟手工运算      
    {
        ll n=b.q.front();b.q.pop();
        BigNum temp,re=a;//re暂存a
        while(!temp.q.empty())temp.q.pop();
        for(int i=0;i<k;i++)
            temp.q.push(0);//后置0         
        k++;
        ll flag=0;//进位    
        while(!re.q.empty())
        {  
            temp.q.push(flag+(n*re.q.front())%M);
            flag=(n*re.q.front())/M;
            re.q.pop();
        }
        if(flag)
            temp.q.push(flag);
        ans=ans+temp;//累加
    }
    if(a.sign+b.sign==1)ans.sign=1;
    return ans;
}
BigNum operator/(BigNum a,ll m)//大数q整除以m(注,m+M<ll)    
{
	int signm=0;
	if(m<0){
		m=-m;
		signm=1;
	}
    stack<ll> s,ans;
    while(!a.q.empty()){  //压入栈     
        s.push(a.q.front());
        a.q.pop();        
    }    
    ll flag=0;//flag移位         
    while(!s.empty())        
    {    
        ll top=s.top()+flag*M;    
        if(top>=m||!ans.empty())//排除最高位是0     
            ans.push(top/m);    
        flag=top%m;    
        s.pop();    
    }//最后的flag为余数    
    while(!ans.empty()){    
        a.q.push(ans.top());    
        ans.pop();    
    }    
    if(a.q.empty())a.q.push(0);
    if(a.sign+signm==1)a.sign=1;
    return a;
}
ll operator%(BigNum a,ll m)//只能正数 
{
    stack<ll> s;
    while(!a.q.empty()){
        s.push(a.q.front());
        a.q.pop();
    }
    ll flag=0;//flag移位
    while(!s.empty())        
    {        
        ll top=s.top()+flag*M;    
        flag=top%m;
        s.pop();
    }
    return flag;
}
int main()   
{
	BigNum a,b,c;
	ll m;
	cin>>a>>b;
	c=a+b;
	cout<<"a+b="<<c<<endl;
	c=a-b;
	cout<<"a-b="<<c<<endl;
	c=a*b;
	cout<<"a-b="<<c<<endl;
	cin>>a>>m;
	c=a/m;
	ll d=a%m;
	cout<<"a/m="<<c<<"..."<<d<<endl;
    return 0;
}

    原文作者:大整数乘法问题
    原文地址: https://blog.csdn.net/winter2121/article/details/72902556
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞