【片段集】大数运算

大数就是很大很大的超出64位整数的表示范围的数。

使用竖式进行加减乘除运算,支持任意位数的整数。暂不支持小数。

上代码。


BigNumber.h

#pragma once
#include <iostream>
using namespace std;
#define DIGITS_OF_BIG_NUMBER 50


class CBigNumber
{
public:
	
	//operators
	friend ostream& operator <<(ostream &cout,CBigNumber& bignumber);
	friend istream& operator >>(istream &cin,CBigNumber& bignumber);
	
	friend bool operator >(CBigNumber &bgn1,CBigNumber &bgn2);
	friend bool operator >=(CBigNumber &bgn1,CBigNumber &bgn2);
	friend bool operator ==(CBigNumber &bgn1,CBigNumber &bgn2);
	friend bool operator <(CBigNumber &bgn1,CBigNumber &bgn2);
	friend bool operator <=(CBigNumber &bgn1,CBigNumber &bgn2);
	
	friend CBigNumber& operator +(CBigNumber &bgn1,CBigNumber &bgn2);
	friend CBigNumber& operator +(int n,CBigNumber &bgn2);
	friend CBigNumber& operator +(CBigNumber &bgn1,int n);
	
	friend CBigNumber& operator -(CBigNumber &bgn1,CBigNumber &bgn2);//没有进行符号处理
	
	friend CBigNumber& operator *(CBigNumber &bgn1,CBigNumber &bgn2);
	 
	friend CBigNumber& operator /(CBigNumber &bgn1,CBigNumber &bgn2);
	
public:
	CBigNumber();
	CBigNumber(char* number);
	CBigNumber(int n);
	CBigNumber(long n);
private:
	char m_cSign;//符号'+' or '-' 【未实现】
	int m_Number[DIGITS_OF_BIG_NUMBER];//存储数据,栈式存储
	int m_nDigits;//记录位数,由于数据是从高到低存储,初始值为DIGITS_OF_BIG_NUMBER,表示没有数位。
};

ostream& operator <<(ostream &cout,CBigNumber& bignumber);
istream& operator >>(istream &cin,CBigNumber& bignumber);

bool operator >(CBigNumber &bgn1,CBigNumber &bgn2);
bool operator >=(CBigNumber &bgn1,CBigNumber &bgn2);
bool operator ==(CBigNumber &bgn1,CBigNumber &bgn2);
bool operator <(CBigNumber &bgn1,CBigNumber &bgn2);
bool operator <=(CBigNumber &bgn1,CBigNumber &bgn2);

CBigNumber& operator +(CBigNumber &bgn1,CBigNumber &bgn2);
CBigNumber& operator +(int n,CBigNumber &bgn2);
CBigNumber& operator +(CBigNumber &bgn1,int n);

CBigNumber& operator -(CBigNumber &bgn1,CBigNumber &bgn2);

CBigNumber& operator *(CBigNumber &bgn1,CBigNumber &bgn2);//bgn1为被乘数,bgn2为乘数

CBigNumber& operator /(CBigNumber &bgn1,CBigNumber &bgn2);bgn1为被除数,bgn2为除数


BigNumber.cpp

#include <iostream>
#include "BigNumber.h"

using namespace std;

CBigNumber::CBigNumber()
{
	m_cSign='+';
	m_nDigits=DIGITS_OF_BIG_NUMBER;
	memset(m_Number,0,DIGITS_OF_BIG_NUMBER*4);
}
CBigNumber::CBigNumber(char* number)
{
	m_nDigits=DIGITS_OF_BIG_NUMBER;
	memset(m_Number,0,DIGITS_OF_BIG_NUMBER*4);
	char c=*number;
	if(c!='-') m_cSign='+';//如果以'-'开头就认为是负数,否则都认为是正数
	else m_cSign='-';
	while(c!='\0')
	{
		if(c>='0'&&c<='9')
		{
			m_nDigits--;
			m_Number[m_nDigits]=c-'0';
			if(m_nDigits==0)
				break;
		}
		number++;
		c=*number;
	}
	//翻转成从低到高的阅读顺序
	int d=(DIGITS_OF_BIG_NUMBER-1-m_nDigits)/2;
	for(int i=0;i<=d;i++)
	{
		char c=m_Number[m_nDigits+i];
		m_Number[m_nDigits+i]=m_Number[DIGITS_OF_BIG_NUMBER-1-i];
		m_Number[DIGITS_OF_BIG_NUMBER-1-i]=c;
	}
}
CBigNumber::CBigNumber(long n)
{
	m_nDigits=DIGITS_OF_BIG_NUMBER;
	memset(m_Number,0,DIGITS_OF_BIG_NUMBER*4);
	while(n>0)//n=0时不用操作,因为BigNumber初始化就是0
	{
		m_nDigits--;
		m_Number[m_nDigits]=n%10;
		n=n/10;
	}
}
CBigNumber::CBigNumber(int n)
{
	m_nDigits=DIGITS_OF_BIG_NUMBER;
	memset(m_Number,0,DIGITS_OF_BIG_NUMBER*4);
	while(n>0)//n=0时不用操作,因为BigNumber初始化就是0
	{
		m_nDigits--;
		m_Number[m_nDigits]=n%10;
		n=n/10;
	}
}
ostream& operator <<(ostream& cout,CBigNumber &bignumber)
{
	if(bignumber.m_nDigits==DIGITS_OF_BIG_NUMBER)
		cout<<0;
	for(int i=bignumber.m_nDigits;i<DIGITS_OF_BIG_NUMBER;i++)
		cout<<bignumber.m_Number[i];
	return cout;
}
istream& operator >>(istream &cin,CBigNumber &bignumber)
{
	char c;
	c=getchar();
	while(c>='0'||c<=9)
	{
		bignumber.m_nDigits--;
		bignumber.m_Number[bignumber.m_nDigits]=c-'0';
		c=getchar();
		if(bignumber.m_nDigits==0) break;
	}
	return cin;
}
bool operator >(CBigNumber &bgn1,CBigNumber &bgn2)
{
	if(bgn1.m_nDigits<bgn2.m_nDigits)//bgn1的位数多
		return true;
	else if(bgn1.m_nDigits>bgn2.m_nDigits)//bgn1的位数少
		return false;
	for(int i=bgn1.m_nDigits;i<DIGITS_OF_BIG_NUMBER;i++)//二者位数相同
	{
		if(bgn1.m_Number[i]>bgn2.m_Number[i])//
		{
			return true;
		}
		else if(bgn1.m_Number[i]<bgn2.m_Number[i])
		{
			return false;
		}
	}
	//执行到这里说明是等于
	return false;
}
bool operator >=(CBigNumber &bgn1,CBigNumber &bgn2)
{
	if(bgn1.m_nDigits<bgn2.m_nDigits)//bgn1的位数多
		return true;
	else if(bgn1.m_nDigits>bgn2.m_nDigits)//bgn1的位数少
		return false;
	for(int i=bgn1.m_nDigits;i<DIGITS_OF_BIG_NUMBER;i++)//二者位数相同
	{
		if(bgn1.m_Number[i]>bgn2.m_Number[i])//
		{
			return true;
		}
		else if(bgn1.m_Number[i]<bgn2.m_Number[i])
		{
			return false;
		}
	}
	//执行到这里说明是等于
	return true;
}
bool operator ==(CBigNumber &bgn1,CBigNumber &bgn2)
{
	if(bgn1.m_nDigits!=bgn2.m_nDigits)//二者位数不相同
		return false;
	for(int i=bgn1.m_nDigits;i<DIGITS_OF_BIG_NUMBER;i++)//二者位数相同
	{
		if(bgn1.m_Number[i]!=bgn2.m_Number[i])
		{
			return false;
		}
	}
	//执行到这里说明是等于
	return true;
}
bool operator <(CBigNumber &bgn1,CBigNumber &bgn2)
{
	if(bgn1.m_nDigits<bgn2.m_nDigits)//bgn1的位数多
		return false;
	else if(bgn1.m_nDigits>bgn2.m_nDigits)//bgn1的位数少
		return true;
	for(int i=bgn1.m_nDigits;i<DIGITS_OF_BIG_NUMBER;i++)//二者位数相同
	{
		if(bgn1.m_Number[i]<bgn2.m_Number[i])//
		{
			return true;
		}
		else if(bgn1.m_Number[i]>bgn2.m_Number[i])
		{
			return false;
		}
	}
	//执行到这里说明是等于
	return false;
}
bool operator <=(CBigNumber &bgn1,CBigNumber &bgn2)
{
	if(bgn1.m_nDigits<bgn2.m_nDigits)//bgn1的位数多
		return false;
	else if(bgn1.m_nDigits>bgn2.m_nDigits)//bgn1的位数少
		return true;
	for(int i=bgn1.m_nDigits;i<DIGITS_OF_BIG_NUMBER;i++)//二者位数相同
	{
		if(bgn1.m_Number[i]<bgn2.m_Number[i])//
		{
			return true;
		}
		else if(bgn1.m_Number[i]>bgn2.m_Number[i])
		{
			return false;
		}
	}
	//执行到这里说明是等于
	return true;
}


CBigNumber& operator +(CBigNumber &bgn1,CBigNumber &bgn2)
{
	static CBigNumber bgnSum;//较大的数作为被加数,和放在较大的数里
	static CBigNumber *pBgnAddend;//较小的数作为加数
	if(bgn1.m_nDigits<bgn2.m_nDigits)
	{
		bgnSum=bgn1;
		pBgnAddend=&bgn2;
	}
	else
	{
		bgnSum=bgn2;
		pBgnAddend=&bgn1;
	}
	
	int carry=0;
	for(int i=DIGITS_OF_BIG_NUMBER-1;i>=bgnSum.m_nDigits;i--)
	{
		carry+=bgnSum.m_Number[i]+pBgnAddend->m_Number[i];
		if(carry>=10)//如果大于10的话向前进位
		{
			bgnSum.m_Number[i]=carry-10;
			carry=1;
		}
		else
		{
			bgnSum.m_Number[i]=carry;
			carry=0;
		}
		if(carry==0&&pBgnAddend->m_nDigits>=i)//加数加完了且没有进位就结束加法
			break;
	}
	//bgnSum.m_nDigits=t;
	if(carry&&bgnSum.m_nDigits>0)//加完了还有进位且不会溢出(被加数加完了),就补上
	{
		bgnSum.m_nDigits--;
		bgnSum.m_Number[bgnSum.m_nDigits]=1;	
	}
	return bgnSum;
}

CBigNumber& operator +(int n,CBigNumber &bgn2)
{
	CBigNumber bgn1(n);
	return bgn1+bgn2;
}
CBigNumber& operator +(CBigNumber &bgn1,int n)
{
	CBigNumber bgn2(n);
	return bgn1+bgn2;
}

CBigNumber& operator -(CBigNumber &bgn1,CBigNumber &bgn2)
{
	static CBigNumber bgnDif;//较大的数作为被减数,差放在被减数中
	static CBigNumber *pBgnSubtractor;//较小的数作为减数
	if(bgn1>bgn2)
	{
		bgnDif=bgn1;
		pBgnSubtractor=&bgn2;
	}
	else
	{
		bgnDif=bgn2;
		pBgnSubtractor=&bgn1;
	}
	int carry=0;
	for(int i=DIGITS_OF_BIG_NUMBER-1;i>=bgnDif.m_nDigits;i--)
	{
		bgnDif.m_Number[i]-=carry;
		carry=0;
		if(bgnDif.m_Number[i]<pBgnSubtractor->m_Number[i])
		{
			carry=1;
			bgnDif.m_Number[i]=bgnDif.m_Number[i]+10-pBgnSubtractor->m_Number[i];
		}
		else
		{
			bgnDif.m_Number[i]=bgnDif.m_Number[i]-pBgnSubtractor->m_Number[i];
		}
		if(carry==0&&pBgnSubtractor->m_nDigits>=i)//如果进位为0且减数减完了就结束
			break;
	}
	//被减数减到头了还没减完,这种情况不存在
	carry=0;
	while(!bgnDif.m_Number[carry]) carry++;//重新计算位数
	bgnDif.m_nDigits=carry;
	
	return bgnDif;
}

CBigNumber& operator *(CBigNumber &bgn1,CBigNumber &bgn2)
{
	static CBigNumber bgnProduct;//积放在这里面
	static CBigNumber *pBgn;
	memset(&bgnProduct,0,sizeof(CBigNumber));
	int carry=0;
	int i,j;
	for(i=DIGITS_OF_BIG_NUMBER-1;i>=bgn2.m_nDigits;i--)//乘数去成被乘数,循环的次数是乘数的位数
	{
		carry=0;
		for(j=DIGITS_OF_BIG_NUMBER-1;j>=bgn1.m_nDigits;j--)//乘以被乘数的每一位
		{
			carry=bgn2.m_Number[i]*bgn1.m_Number[j]+carry+bgnProduct.m_Number[j-(DIGITS_OF_BIG_NUMBER-1-i)];
			if(carry>=10)
			{
				bgnProduct.m_Number[j-(DIGITS_OF_BIG_NUMBER-1-i)]+=carry%10;
				carry/=10;
			}
			else
			{
				bgnProduct.m_Number[j-(DIGITS_OF_BIG_NUMBER-1-i)]=carry;
				carry=0;
			}
		}
		if(carry!=0)//被乘数乘空了还有进位
		{
			bgnProduct.m_Number[j-(DIGITS_OF_BIG_NUMBER-1-i)]=carry;
		}
	}
	i=0;
	while(bgnProduct.m_Number[i]==0) i++;
	bgnProduct.m_nDigits=i;
	return bgnProduct;
}

CBigNumber& operator /(CBigNumber &bgn1,CBigNumber &bgn2)
{
	static CBigNumber bgnQuotient;//商
	static CBigNumber bgnTemp;//除法的中间量
	memset(&bgnQuotient,0,sizeof(CBigNumber));
	memset(&bgnTemp,0,sizeof(CBigNumber));
	bgnQuotient.m_nDigits=DIGITS_OF_BIG_NUMBER;
	if(bgn1<bgn2)//小于的话结果为0
		return bgnQuotient;
	
	int nIndex=bgn1.m_nDigits-1;//当前取到除数的第几位,指向上一次读的位置
	
	//取被除数的前n个数放进temp,n为除数的位数
	for(int i=DIGITS_OF_BIG_NUMBER-bgn2.m_nDigits;i>0;i--)
	{
		nIndex++;
		bgnTemp.m_Number[DIGITS_OF_BIG_NUMBER-i]=bgn1.m_Number[nIndex];
	}
	bgnTemp.m_nDigits=bgn2.m_nDigits;
	//cout<<bgnTemp<<endl;
	
	bgnQuotient.m_nDigits=0;
	while(nIndex<DIGITS_OF_BIG_NUMBER-1)//被除数的所有位都取完结束运算
	{
		//如果temp小于除数,再取一个数放进去
		while(bgnTemp<bgn2&&nIndex<DIGITS_OF_BIG_NUMBER-1)
		{
			for(int i=bgnTemp.m_nDigits;i<DIGITS_OF_BIG_NUMBER;i++)//temp中数据左移
				bgnTemp.m_Number[i-1]=bgnTemp.m_Number[i];

			bgnTemp.m_nDigits--;
			nIndex++;
			bgnTemp.m_Number[DIGITS_OF_BIG_NUMBER-1]=bgn1.m_Number[nIndex];
			bgnQuotient.m_nDigits++;//准备迎接下一个商,如果是继续去数放进temp,那么商中会增加一个0
		}
		
		//计算temp/除数的结果,以及余数放进temp
		while(bgnTemp>=bgn2)
		{
			bgnQuotient.m_Number[bgnQuotient.m_nDigits]++;
			bgnTemp=bgnTemp-bgn2;
			//cout<<"/.."<<bgnTemp<<"\t"<<bgnQuotient.m_Number[bgnQuotient.m_nDigits]<<endl;
		}
	}
	
	//左移
	for(int i=bgnQuotient.m_nDigits;i>=0;i--)
	{
		bgnQuotient.m_Number[DIGITS_OF_BIG_NUMBER-1-bgnQuotient.m_nDigits+i]=bgnQuotient.m_Number[i];
	}
	bgnQuotient.m_nDigits=DIGITS_OF_BIG_NUMBER-1-bgnQuotient.m_nDigits;
	return bgnQuotient;
}


main.cpp

#include <iostream>
#include "BigNumber.h"
using namespace std;


int main(int argc, char* argv[])
{
	CBigNumber bignumber1("123456789123456789");
	CBigNumber bignumber2("123456789123456780");
	
	cout<<"条件运算:"<<endl;
	cout<<"> "<<(bignumber1>bignumber2)<<endl;
	cout<<">="<<(bignumber1>=bignumber2)<<endl;
	cout<<"=="<<(bignumber1==bignumber2)<<endl;
	cout<<"< "<<(bignumber1<bignumber2)<<endl;
	cout<<"<="<<(bignumber1<=bignumber2)<<endl;
	
	cout<<"\n四则运算:"<<endl;
	cout<<"+"<<bignumber1+bignumber2<<endl;
	cout<<"-"<<bignumber1-bignumber2<<endl;
	//cout<<"*"<<bignumber1*bignumber2<<endl;
	cout<<"*"<<CBigNumber("123456789")*CBigNumber("123456789")<<endl;
	cout<<"/"<<CBigNumber("78945613")/CBigNumber("123")<<endl;
	
	CBigNumber bgnI("1"),bgnJ("1");double n=1,m=1;
	cout<<1<<'\t'<<bgnI<<"\t\t\t"<<n<<endl;
	cout<<2<<'\t'<<bgnI<<"\t\t\t"<<endl;
	for(int i=2;i<200;i+=2)
	{
		bgnI=bgnI+bgnJ; n=m+n;
		bgnJ=bgnI+bgnJ; m=m+n;
		cout<<i<<'\t'<<bgnI<<"\t\t\t"<<n<<endl;
		cout<<i+1<<'\t'<<bgnJ<<"\t\t\t"<<m<<endl;
	}
	
	return 0;
}








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值