大数的加减法__2018.06.01

BigNumber.h

#ifndef BIGNUMBER_H  
#define BIGNUMBER_H  

#include <iostream>  
#include <string>  

class BigNumber
{
public:
	BigNumber();
	BigNumber(std::string s_16);
	BigNumber(const BigNumber &number);
	/************************************************************************/
	/* 改变数值的操作                                  */
	/************************************************************************/
	void setMaxValue();
	void setMinValue();
	BigNumber& operator++();//前缀重载  
	const BigNumber operator++(int);//后缀重载  
	BigNumber& operator--();//前缀重载  
	const BigNumber operator--(int);//后缀重载  
	const BigNumber& operator=(const BigNumber &number);
	const BigNumber& operator+=(const BigNumber &number);
	const BigNumber& operator-=(const BigNumber &number);

	/************************************************************************/
	/* 基本运算操作                                   */
	/************************************************************************/
	const BigNumber operator+(const BigNumber &number);
	const BigNumber operator-(const BigNumber &number);
	const BigNumber operator*(const BigNumber &number);//————————未完成  
	const BigNumber operator/(const BigNumber &number);//————————未完成  
	/************************************************************************/
	/* 大小比较操作                                           */
	/************************************************************************/
	bool operator>(const BigNumber &number);
	bool operator<(const BigNumber &number);
	bool operator==(const BigNumber &number);
	bool operator<=(const BigNumber &number);
	bool operator>=(const BigNumber &number);

	/************************************************************************/
	/* 输出操作                                     */
	/************************************************************************/
	friend std::ostream& operator<<(std::ostream &os, BigNumber &number);
	friend std::istream& operator>>(std::istream &is, BigNumber &number);

	const static unsigned int MaxValue = 0xFFFFFFFF;//一个无符号整数的最大值  
	const static unsigned int MinValue = 0x00000000;//一个无符号整数的最小值  
	const static unsigned int Size = 100;//存储区大小  
private:
	unsigned int data[Size];//存储区  

	void _add(unsigned int data[], unsigned int posion);//进位操作  
	void _sub(unsigned int data[], unsigned int posion);//借位操作  

	unsigned char toBit4(char c);//字符转数值  
	char fromBit4(unsigned char c);//数值转字符  

	void set_Bit16(std::string s_16);
	std::string get_Bit16();
};

#endif  

BigNumber.cpp

#include "BigNumber.h"  

/************************************************************************/
/* 默认构造函数,初始数值为0                                            */
/************************************************************************/
BigNumber::BigNumber()
{
	setMinValue();
}
/************************************************************************/
/* 以一个16进制表示的字符串初始化大数                                   */
/************************************************************************/
BigNumber::BigNumber(std::string s_16)
{
	this->set_Bit16(s_16);
}
/************************************************************************/
/* 拷贝构造函数                                           */
/************************************************************************/
BigNumber::BigNumber(const BigNumber &number)
{
	for (unsigned int index = 0; index < BigNumber::Size; index++)
	{
		this->data[index] = number.data[index];
	}
}
/************************************************************************/
/* 进位操作实际上是一个自加的过程,如果低位的数值自加后会溢出,则将     */
/*  高一位的数也自加,否则就直接将当前数值自加后退出        */
/************************************************************************/
void BigNumber::_add(unsigned int data[], unsigned int posion)
{
	if (this->data[posion] == 0xFFFFFFFF)//如果当前位的值为最大值  
	{
		if (posion == Size - 1)//如果到达最高位,则直接进行自加,不再进位  
		{
			this->data[posion]++;
			return;
		}
		_add(data, posion + 1);//通过将高位自加来表示进位  
		this->data[posion]++;
	}
	else//若不是最大值则进行自加  
	{
		this->data[posion]++;
	}
}

/************************************************************************/
/* 借位操作实际上是一个自减的过程,如果低位的数值自减后会溢出,则将     */
/*  高一位的数也自减,否则就直接将当前数值自减后退出        */
/************************************************************************/
void BigNumber::_sub(unsigned int data[], unsigned int posion)
{
	if (this->data[posion] == 0x00000000)//如果当前位的值为最小值  
	{
		if (posion == BigNumber::Size - 1)//如果到达最高位,则直接进行自减,不再借位  
		{
			this->data[posion]--;
			return;
		}
		_sub(data, posion + 1);//通过将高位自减来表示借位  
		this->data[posion]--;
	}
	else//若不是最小值则进行自减  
	{
		this->data[posion]--;
	}
}
/************************************************************************/
/* 将一个16进制表示的字符转为数值                                       */
/************************************************************************/
unsigned char BigNumber::toBit4(char c)
{
	if (c <= '9'&&c >= '0')
	{
		return c - '0';
	}
	else if (c <= 'F'&&c >= 'A')
	{
		return c - 'A' + 10;
	}
	else if (c <= 'f'&&c >= 'a')
	{
		return c - 'a' + 10;
	}
	else
	{
		return 0xf0;
	}
}

/************************************************************************/
/* 将一个0~15之内的数值转为16进制表示的字符                             */
/************************************************************************/
char BigNumber::fromBit4(unsigned char n)
{
	if (n <= 9 && n >= 0)
	{
		return n + '0';
	}
	if (n <= 15 && n >= 10)
	{
		return n + 'A' - 10;
	}
	return '\0';
}

/************************************************************************/
/* 将数值转为一个16进制表示的字符串,并返回该字符串                     */
/************************************************************************/
std::string BigNumber::get_Bit16()
{
	unsigned int index1 = BigNumber::Size - 1;
	while (this->data[index1] == 0) //指向最高有效位  
	{
		if (index1 == 0)
		{
			break;
		}
		index1--;
	}
	std::string s_16;
	for (unsigned int i = index1 + 1; i > 0; i--)
	{
		unsigned char bit7, bit6, bit5, bit4, bit3, bit2, bit1, bit0;
		unsigned int temp = this->data[i - 1];//取出一个32位  
											  /*
											  从高到低得到每一个4bit
											  */
		bit7 = (temp >> 28) & 0xf;
		bit6 = (temp >> 24) & 0xf;
		bit5 = (temp >> 20) & 0xf;
		bit4 = (temp >> 16) & 0xf;
		bit3 = (temp >> 12) & 0xf;
		bit2 = (temp >> 8) & 0xf;
		bit1 = (temp >> 4) & 0xf;
		bit0 = temp & 0xf;
		s_16 += fromBit4(bit7);
		s_16 += fromBit4(bit6);
		s_16 += fromBit4(bit5);
		s_16 += fromBit4(bit4);
		s_16 += fromBit4(bit3);
		s_16 += fromBit4(bit2);
		s_16 += fromBit4(bit1);
		s_16 += fromBit4(bit0);
	}
	return s_16;
}

/************************************************************************/
/* 接受一个16进制数的字符串,将其存入转为BigNumber                      */
/************************************************************************/
void BigNumber::set_Bit16(std::string s_16)
{
	this->setMinValue();//置零  
	unsigned int size = s_16.size();//补位,不够32位则高位补零  
	if (size % 8 == 7)
	{
		s_16 = "0" + s_16;
	}
	else if (size % 8 == 6)
	{
		s_16 = "00" + s_16;
	}
	else if (size % 8 == 5)
	{
		s_16 = "000" + s_16;
	}
	else if (size % 8 == 4)
	{
		s_16 = "0000" + s_16;
	}
	else if (size % 8 == 3)
	{
		s_16 = "00000" + s_16;
	}
	else if (size % 8 == 2)
	{
		s_16 = "000000" + s_16;
	}
	else if (size % 8 == 1)
	{
		s_16 = "0000000" + s_16;
	}
	/************************************************************************/
	/* 一次取8个字符,将其转为32位无符号整数存入                            */
	/************************************************************************/
	for (unsigned int i = 0; i < s_16.size() / 8; ++i)
	{
		std::string c4 = s_16.substr(8 * i, 8 * i + 8);
		unsigned int bit7, bit6, bit5, bit4, bit3, bit2, bit1, bit0;
		bit7 = toBit4(c4[0]);
		bit6 = toBit4(c4[1]);
		bit5 = toBit4(c4[2]);
		bit4 = toBit4(c4[3]);
		bit3 = toBit4(c4[4]);
		bit2 = toBit4(c4[5]);
		bit1 = toBit4(c4[6]);
		bit0 = toBit4(c4[7]);
		this->data[s_16.size() / 8 - i - 1] |= bit7;
		this->data[s_16.size() / 8 - i - 1] <<= 4;
		this->data[s_16.size() / 8 - i - 1] |= bit6;
		this->data[s_16.size() / 8 - i - 1] <<= 4;
		this->data[s_16.size() / 8 - i - 1] |= bit5;
		this->data[s_16.size() / 8 - i - 1] <<= 4;
		this->data[s_16.size() / 8 - i - 1] |= bit4;
		this->data[s_16.size() / 8 - i - 1] <<= 4;
		this->data[s_16.size() / 8 - i - 1] |= bit3;
		this->data[s_16.size() / 8 - i - 1] <<= 4;
		this->data[s_16.size() / 8 - i - 1] |= bit2;
		this->data[s_16.size() / 8 - i - 1] <<= 4;
		this->data[s_16.size() / 8 - i - 1] |= bit1;
		this->data[s_16.size() / 8 - i - 1] <<= 4;
		this->data[s_16.size() / 8 - i - 1] |= bit0;
	}
}

/************************************************************************/
/* 设置数值为最小值                                         */
/************************************************************************/
void BigNumber::setMaxValue()
{
	for (unsigned int index = 0; index < BigNumber::Size; index++)
	{
		data[index] = 0xFFFFFFFF;
	}
}

/************************************************************************/
/* 设置数值为最大值                                         */
/************************************************************************/
void BigNumber::setMinValue()
{
	for (unsigned int index = 0; index < BigNumber::Size; index++)
	{
		data[index] = 0x00000000;
	}
}

const BigNumber& BigNumber::operator=(const BigNumber &number)
{
	for (unsigned int index = 0; index < BigNumber::Size; index++)
	{
		this->data[index] = number.data[index];
	}
	return *this;
}

const BigNumber& BigNumber::operator+=(const BigNumber &number)
{
	*this = *this + number;
	return *this;
}

const BigNumber& BigNumber::operator-=(const BigNumber &number)
{
	*this = *this - number;
	return *this;
}

BigNumber& BigNumber::operator++()//前缀重载,返回自加之后的值  
{
	_add(this->data, 0);
	return *this;
}

const BigNumber BigNumber::operator++(int)//后缀重载,返回自加之前的值  
{
	BigNumber n = *this;
	_add(this->data, 0);
	return n;
}

BigNumber& BigNumber::operator--()//前缀重载,返回自减之后的值  
{
	_sub(this->data, 0);
	return *this;
}

const BigNumber BigNumber::operator--(int)//后缀重载,返回自减之前的值  
{
	BigNumber n = *this;
	_sub(this->data, 0);
	return n;
}

/******************************************************************************/
/* 加法操作并不会改变两个操作数本身的值,所以这里保存第一个加数的值到变量n    */
/* 中,并将最终的和保存到变量n中,返回变量n的值                    */
/******************************************************************************/
const BigNumber BigNumber::operator+(const BigNumber &number)
{
	BigNumber n = *this;
	for (unsigned int index = 0; index < BigNumber::Size - 1; ++index)
	{
		if (BigNumber::MaxValue - this->data[index] < number.data[index])//如果需要进位则执行进位操作  
		{
			n._add(n.data, index + 1);
		}
		n.data[index] = n.data[index] + number.data[index];//执行加法  
	}
	n.data[BigNumber::Size - 1] = n.data[BigNumber::Size - 1] + number.data[BigNumber::Size - 1];//最高位不用进行进位  
	return n;
}

/******************************************************************************/
/* 减法操作并不会改变两个操作数本身的值,所以这里保存被减数的值到 变量n中     */
/* 并将最终的差保存到变量n中,返回变量n的值                                  */
/******************************************************************************/
const BigNumber BigNumber::operator - (const BigNumber &number)
{
	BigNumber n = *this;
	for (unsigned int index = 0; index < BigNumber::Size - 1; ++index)
	{
		if (n.data[index] < number.data[index])//如果不够减,就执行借位操作  
		{
			n._sub(n.data, index + 1);//借位  
		}
		n.data[index] = n.data[index] - number.data[index];//执行减法  
	}
	n.data[BigNumber::Size - 1] = n.data[BigNumber::Size - 1] - number.data[BigNumber::Size - 1];//最高位不需要借位  
	return n;
}

/************************************************************************/
/* 比较大小操作                                           */
/************************************************************************/
bool BigNumber::operator>(const BigNumber &number)
{
	unsigned int index1 = BigNumber::Size - 1;//分别指向最大下标  
	unsigned int index2 = BigNumber::Size - 1;
	while (this->data[index1] == 0) //指向最高有效位  
	{
		if (index1 == 0)
		{
			break;
		}
		index1--;
	}
	while (number.data[index2] == 0) //指向最高有效位  
	{
		if (index2 == 0)
		{
			break;
		}
		index2--;
	}
	if (index1 > index2)
	{
		return true;
	}
	else if (index1 <index2)
	{
		return false;
	}
	else//当最高有效位的存储区下标相同时,比较存储区内的数值  
	{
		if (this->data[index1] > number.data[index2])
		{
			return true;
		}
		else
		{
			return false;
		}
	}
}

bool BigNumber::operator<(const BigNumber &number)
{
	unsigned int index1 = BigNumber::Size - 1;//分别指向最大下标  
	unsigned int index2 = BigNumber::Size - 1;
	while (this->data[index1] == 0) //指向最高有效位  
	{
		if (index1 == 0)
		{
			break;
		}
		index1--;
	}
	while (number.data[index2] == 0) //指向最高有效位  
	{
		if (index2 == 0)
		{
			break;
		}
		index2--;
	}
	if (index1 < index2)
	{
		return true;
	}
	else if (index1 > index2)
	{
		return false;
	}
	else//当最高有效位的存储区下标相同时,比较存储区内的数值  
	{
		if (this->data[index1] < number.data[index2])
		{
			return true;
		}
		else
		{
			return false;
		}
	}
}

bool BigNumber::operator == (const BigNumber &number)
{
	for (unsigned int index = 0; index < BigNumber::Size; index++)
	{
		if (this->data[index] != number.data[index])//只要遇到存储的数值不一样就返回false  
		{
			return false;
		}
	}
	return true;
}

bool BigNumber::operator <= (const BigNumber &number)
{
	if (*this < number || *this == number)
	{
		return true;
	}
	return false;
}

bool BigNumber::operator >= (const BigNumber &number)
{
	if (*this > number || *this == number)
	{
		return true;
	}
	return false;
}

/************************************************************************/
/* 重载输出操作,输出一个16进制的字符串,以0x开头                       */
/************************************************************************/
//std::ostream& operator<<(std::ostream &os, BigNumber &number)
//{
//	std::string s_16; 
//	s_16 = number.get_Bit16();
//	os << "0x" << s_16;
//	return os;
//}
std::ostream& operator<<(std::ostream &os, BigNumber &number)
{
	std::string s_16;
	s_16 = number.get_Bit16();
	os << s_16;
	return os;
}
/************************************************************************/
/* 重载输入操作,接收一个16进制的字符串,不需要0x开头                   */
/************************************************************************/
std::istream& operator>>(std::istream &is, BigNumber &number)
{
	std::string s_16;
	is >> s_16;
	number.set_Bit16(s_16);
	return is;
}

main.cpp

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

int main()
{
	string Num0("2000000000000000000000000000000000000000100");/*1234567891011121314151617181920*/
	string Num1("1000000000000000000000000000000000000000200");/*21222324252627282930313233343536*/
	BigNumber MyBigNum0(Num0);
	

	BigNumber MyBigNum1(Num1);
	

	BigNumber MyBigNum2;
	MyBigNum2=MyBigNum0 + MyBigNum1;

	cout << MyBigNum0 << endl;
	cout << MyBigNum1 << endl;
	cout << MyBigNum2 << endl;

	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_40316053/article/details/80537785