C/C++项目之大数据的加减乘除求模以及括号四则运算

BigData.h

#pragma  once

#include<string>
#include<iostream>
using namespace std;
#include<sstream>
#include<cassert>
#include <stack>

typedef long long INT64;

class BigData
{
public:
	BigData(INT64  value);
	BigData(const string & strData);

	friend  ostream& operator<<(ostream & out,const BigData & bigdata);

	BigData operator+(const BigData & b);
	BigData operator-(const BigData & b);
	BigData operator*(const BigData & b);
	BigData operator/(const BigData & b);
	BigData operator%(const BigData & b);

public:
	static BigData Calculate(const string & str);//计算四则运算表达式

private:
	string Add(string left,string right);
	string Sub(string left,string right);
	string Mul(string left,string right);
	string Div(string left, string right);
	bool IsINT64OverFlow()const;
	bool IsLeftStrBig(const char* left,int LSize,const char* right,int RSize);
	char SubLoop(char *&pLeft,int &LSize,char *pRight,int RSize); //除法时每次求商运算。
	string Mod(string left,string right);
	
四则运算的函数//
	static string GetSuffixExpression(string str); //得到后缀表达式
	 static string GetData( char *& ptr);
	static bool IsOperator(char c);
	//比较两个操作符的优先级,op1比op2高返回1,一样返回0,低返回-1
	static int CompareOperatorPriority(char op1,char op2);
	static BigData CalPostExp(string str);  //计算后缀表达式。

private:
	INT64 _value;
	string _strData;

};


BigData.cpp

(1)构造函数、判断溢出、重载<<

#include "BigData.h"

const INT64 UN_INT = 0xcccccccccccccccc;
const INT64 MaxValue = 9223372036854775807;
const INT64 MinValue = -9223372036854775808;

BigData::BigData(INT64 value = UN_INT):_value(value)
{
	stringstream stream;
	stream << value;
	stream >> _strData;
	if (isdigit(_strData[0]))
	{
		_strData = '+' + _strData;
	}
}

BigData:: BigData(const string & strData):_value(0),_strData("+0")
{
	/*if (_strData.empty())
	{
	return ;
	}*/
	//
	"         " "       1234533"
	//第一步跳过空白字符
	//
	char *pData = (char*)strData.c_str();
	while (isspace(*pData))
	{
		pData++;
	}
	if (*pData == '\0')
	{
		return ;
	}
	//
	// + -
	// 0~9
	// 非数字字符
	//
	char symbol ;  //符号位。
	if (*pData == '+' || *pData == '-')
	{
		symbol = *pData;
		pData++;
	}
	else if (isdigit(*pData))
	{
		symbol = '+';
	}
	else
		return ;
	//
	// 跳过前置0  "000012345678"  "00000000000000"
	//
	while (*pData == '0')
	{
		pData++;
	}
	if (*pData == '\0')
	{
		return ;
	}
	//
	// "123456asdf123456"
	//

	_strData.resize(strData.length()+1); //+1是只保留符号位,覆盖刚开始的0.

	int idx = 1;
	while (*pData != '\0')
	{
		if (isdigit(*pData))
		{
			_value = _value * 10 + *pData - '0';     //这里可能会溢出,所以_value不为真。
			_strData[idx++] = *pData;
		}
		else 
			break;
		pData++;
	}
	_strData.resize(idx);
	_strData[0] = symbol;

	if (symbol == '-')
	{
		_value = 0 - _value;
	}

}


ostream& operator<<(ostream & _out,const BigData & bigdata)
{
	char *pData = (char*)bigdata._strData.c_str();
	if (*pData == '+') //如果是正数,不需要输出符号。
	{
		pData++;
	}
	_out << pData;
	return _out;
}



bool BigData:: IsINT64OverFlow()const
{
	string strTemp("+9223372036854775807");  //long long所能保存的最大值。
	if (_strData[0]  == '-' )
	{
		strTemp = "-9223372036854775808"; // long long 所能保存的最小值。
	}
	if (_strData.size() < strTemp.size() )
	{
		return false;   //没有溢出。
	}
	else if (_strData.size() == strTemp.size() && _strData <= strTemp)
	{
		return false;
	}
	return true;
}


(2)加法:

加法///
BigData BigData:: operator+(const BigData & b)
{
	if (!IsINT64OverFlow() && !b.IsINT64OverFlow())
	{
		if (_strData[0] != b._strData[0]) //如果两个数没有溢出,且两个数是异号,直接相加没有问题。
		{
			return BigData(_value+b._value);
		}
		else  //两个没溢出的数同号可能溢出。
		{  //max = 10,num1 = 4,num2 = 7,num1+num2 > max 溢出。也就是num1<max-num2没溢出
			if ( (_strData[0] == '+' && MaxValue - _value >= b._value  )
				||(_strData[0] == '-' && MinValue -_value <= b._value))
			{
				return BigData(_value+b._value);  //没有溢出的处理。
			}

		}
	}

	//至少有一个超出或者两个相加的结果超出。999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 + 9999999999999999999999999
	if (_strData[0] == b._strData[0])
	{
		return BigData(Add(_strData,b._strData));
	}
	//9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 + (-2222222222222)
	//-9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 + 22222222222222222222
//	return BigData(Sub(_strData,b._strData));  //这个地方有坑?  不能直接这么写。减法也是处理的是同号。
	if (_strData[0] == '+')
	{
		string temp = b._strData;
		temp[0] = '+';
		return BigData(Sub(_strData,temp));
	}
	else
	{
		string temp = b._strData;
		temp[0] = '-';
		return BigData(Sub(_strData,temp));
	}

}

//这个Add函数和Sub函数都是处理左右两边同号的情况。
string BigData:: Add(string left,string right)
{
	int LSize = left.size();
	int RSize = right.size();
	if (LSize < RSize)   //左边的数大
	{
		swap(left, right);
		swap(LSize, RSize);
	}

	string strRet;
	strRet.resize(LSize+1);  //可能有进位
	strRet[0] = left[0];  //左边的数大,结果的符号随大数

	char step = 0;  //进位
	for (size_t idx = 1; idx < LSize; ++idx)  //跳过符号位
	{
		char temp = left[LSize - idx] - '0' + step;  //取最右边的位。也就是最小位。
		if(RSize > idx )//不能Rsize-idx > 0这么写,idx是size_t,相减还是size_t。一直大于0.这里不能等于。等于的话,right[0]为符号位,乱码。
			temp += right[RSize - idx] - '0';

		step = temp/10;
		strRet[LSize + 1 - idx] = temp%10+'0';  //最右边的位数
	}

	strRet[1] = step + '0';   //可能有进位。

	return strRet;
}


(3)减法:

//减法///
BigData BigData:: operator-(const BigData & b)
{

	if (!IsINT64OverFlow() && !b.IsINT64OverFlow())
	{
		//-999999999999999 - (-5555555555)  不可能溢出。
		if (_strData[0] == b._strData[0]) //两个没有溢出的数同号相减,不可能溢出。
		{
			return BigData(_value - b._value);
		}
		else
		{    //-999999999999999999999999 - 55555555555555555555555555555)  异号可能溢出,超出最小范围了。
			//99999999999999999999999999 - (-444444444444444444444444444)  异号可能溢出,超过最大范围了。
			if ( (_strData[0] == '+' && _value > b._value-MaxValue)
				|| (_strData[0] == '-'&& _value < b._value-MinValue)          )
			{
				return BigData(_value-b._value);  //处理异号没有溢出的情况。
			}
		}
	}

	//至少有一个超出或者两个数相减超出。
	//999999999999999999999999999999999999999999999999999999999999999999- 2222
	//-99999999999999999999999999999999999999999999999999999999999999 - (-222)

	if (_strData[0] == b._strData[0])
	{
		return BigData(Sub(_strData,b._strData));
	}

	//99999999999999999999999999999999999999999999999999 -(-222222222222)
	//-9999999999999999999999999999999999999999999999999 - 2222222222222222
	//return BigData(Add(_strData,b._strData));   //我觉得加法也是有坑的,但是实验发现没有坑。
	if (_strData[0] == '+')
	{
		string temp = b._strData;
		temp[0] = '+';
		return BigData(Add(_strData,temp));
	}
	else
	{
		string temp = b._strData;
		temp[0] = '-';
		return BigData(Add(_strData,temp));
	}
}


string  BigData::Sub(string left,string right)                // +55555555555555555555555555555555555555555555555555555555555555  left
{                                                            //  +66666666666666666666666666666666666666666666666666666666666666  right
	int LSize = left.size();                                //    两个正数相减,答案为负数,交换后变成下列。       
	int RSize = right.size();                              //    +66666666666666666666666666666666666666666666666666666666666666  left
															//    +55555555555555555555555555555555555555555555555555555555555555  right
	//+号的时候左边的数小,-号的时候左边的数大就交换。      //   此时答案变成了正数,所以得把符号位改了。
	char symbol = left[0];  //
	if (LSize < RSize || LSize== RSize && left < right)    //        -5555555555555555555555555555555555555555555555555555555555555555  left
	{//减法也是处理同号,所以不会出现位数相等,一个正一个负的情况  //  -6666666666666666666666666666666666666666666666666666666666666666   right
		swap(left, right);                                 //   两个相减,答案为正数,交换后变成下列
		swap(LSize,RSize);                                 //   -6666666666666666666666666666666666666666666666666666666666666666  left
															//   -55555555555555555555555555555555555555555555555555555555555555555  right
		//符号                                             //    此时答案变成负数了,所以得把符号位改了。
		if (left[0] == '+')  
		{
			symbol = '-'; //交换后左边的数为正数,此时结果就应该为负数。
		}
		else
		{
			symbol = '+';
		}
	}

	string strRet;
	strRet.resize(LSize); //结果最多和左边的数一样的位数。
	strRet[0] = symbol;

	char step = 0;

	for (size_t idx = 1; idx < LSize; ++idx)
	{
		char temp = left[LSize-idx] - '0';
		if (RSize > idx)
		{
			temp -= right[RSize-idx] - '0';
		}

		if (temp < 0)  //借位
		{
			left[LSize - idx-1] -= 1;
			temp += 10;
		}
		strRet[LSize-idx] = temp + '0';

	}
	return strRet;
}

(4)乘法

/乘法
BigData BigData:: operator*(const BigData & b)
{
	if ('0' == _strData[1] || '0' == b._strData[1])//其中一个操作数为0结果为0不需要操作
	{
		return BigData(0);
	}

	if (!IsINT64OverFlow() && !b.IsINT64OverFlow()) //两个数都没有溢出。
	{
		if (_strData[0] == b._strData[0])  //同号相乘,结果为正。可能超过最大值
		{
			if ((_value > 0 && MaxValue/_value >= b._value)
				||(_value < 0 && MaxValue /_value <= b._value))
			{
				return BigData(_value*b._value);
			}
		}
		else  //异号相乘,结果为父,可能超过最小值
		{
			if ((_value > 0 && MinValue/_value <= b._value)
				||(_value < 0 && MaxValue /_value >= b._value))
			{
				return BigData(_value*b._value);
			}
		}
	}


	if (b._strData == "+1" )
	{
		return BigData(_strData);
	}
	if (_strData == "+1")
	{
		return BigData(b._strData);
	}
	return BigData(Mul(_strData,b._strData));
}

string BigData:: Mul(string left,string right)
{
	char symbol = '+';
	int LSize = left.size();
	int RSize = right.size();

	if (left[0] != right[0]) //两个数异号,结果肯定是负数。
	{
		symbol = '-';
	}
	if ( LSize < RSize /*|| (LSize == RSize && left < right)*/ ) //乘法只要保证左边的位数多就可以了。
	{
		swap(left,right);
		swap(LSize,RSize);
	}

	string ret;
	ret.resize(LSize+RSize-1,'0'); //相乘后位数最多两个数的位数相加再减去一个多余的符号位。比如+9 * +9 = +81
	ret[0] = symbol;

	char offset = 0; //乘法要错位,这就是错位标志。

	for (int i = 1; i < RSize; ++i)
	{
		char step = 0; //进位
		int j = 1;
		for (; j < LSize; ++j)
		{
			char value = (left[LSize-j] -'0') *( right[RSize-i] - '0') + step;
			char temp = ret[ret.size()-j-offset] - '0'; //拿出原来这个位的数。
			char num = (temp+value) % 10 ;  //这个地方很关键,先把原来的数+原来的进位+这次value得到的结果求余。不会出现连环进位情况。

			step = (value+temp) / 10;
			ret[ret.size()-j-offset] = num +'0';
		}
		//还要考虑进位标志符是不是还有数据。
		ret[ret.size()-j-offset] = step+'0';

		offset++;  //内部乘完一次乘完,就错位一次。
	}

	return ret;
}


(5)除法:

/// -- 除法-- ///
BigData BigData:: operator/(const BigData & b)
{
	int LSize = _strData.size(); //被除数。
	int RSize = b._strData.size();//除数
	char *pLeft = (char*)_strData.c_str()+1; //跳过符号位。
	char *pRight = (char*)b._strData.c_str()+1; //跳过符号位。
	char symbol = '+';

	if (b._strData[1] == '0')  //除数为0
	{
		cout << "除数为 0 "<<endl;
		assert(0);
	}

	//if (!IsINT64OverFlow() && !b.IsINT64OverFlow()) //两个数不溢出。除法肯定不溢出。
	//{
	//	return BigData(_value / b._value);
	//}

	if (_strData == "+0") //被除数为0.
	{
		return BigData(0);
	}

	if (LSize < RSize || (LSize==RSize && strcmp(pLeft,pRight) < 0)) //抛弃符号位后,比较大小,如果被除数小,直接返回0.
	{
		return BigData(0);
	}

	if (strcmp(pLeft,pRight) == 0) //两个数跳过符号位相等
	{
		BigData ret(1);
		if (_strData[0] != b._strData[0]) //符号位不同
		{
			ret._value = -1;
			ret._strData[0] = '-';   //这个地方应该要修改字符串中的符号位的,老师的没改,我觉得是错的。
		}
	
		return ret;
	}

	if (strcmp(pRight,"1") == 0)  //除数的数值为1,结果可能为正负被除数。
	{
		BigData ret(_strData);
		
		if (b._strData[0] == '-') //除数为-1
		{
			if (_strData[0] == '+')  //被除数为正数
			{
				ret._strData[0] = '-';
				ret._value = 0- _value;
			}
			else  //被除数为负数。
			{
				ret._strData[0] = '+';
				ret._value = 0- _value;
			}
		}

		return ret;  //除数为正,
	}

	return BigData(Div(_strData,b._strData)); //调用构造函数。
}

string BigData::Div(string left, string right)
{
	//第一步先保存符号位。
	char symbol = '+';
	if (left[0] != right[0])
	{
		symbol = '-';
	}
	string ret;
	ret += symbol; 

	char *pLeft = (char*)(left.c_str()+1);
	char *pRight = (char*)(right.c_str()+1);  //跳过各自的符号位。
	int RSize = right.size()-1; //把符号位减去。
	int Len = RSize;    // 2222/33   第一步先拿出和33相同的位数的22,看22能整除33不,

	while (*(pLeft+Len-1)  != '\0') //[pLeft,pLeft+Len) 左闭右开的区间,pLeft+Len是取不到的,所以这里得-1.
	{
		if (*pLeft == '0') //990000000 / 33 当pLeft后面都指向0的时候就没有必要再除了,直接把后面的0搬到结果里就可以了。
		{
			ret.append(1,'0');
			continue;
		}

		if (!IsLeftStrBig(pLeft,Len,pRight,RSize)) //2222 / 33  先拿22/33,左边小,所以拿出222来
		{
			Len++;
			ret.append(1,'0');
			continue;
		}
		else
		{
			ret.append(1,SubLoop(pLeft,Len,pRight,RSize));  //SubLoop(pLeft,Len,pRight,RSize)的结果就是一次商。
			Len++;
		}
	}
	return ret;
}

//这IsLeftBig和SubLoop两个函数left和right都是跳过符号位指向数据位的。
bool BigData::IsLeftStrBig(const char* left,int LSize,const char* right,int RSize)
{
	if (LSize > RSize ||(LSize==RSize && strncmp(left,right,RSize) >= 0)  )
	{                                         // 222   33   刚开始要比较的是222中的22 和33比较,所以这里是ncmp比较。
		return true;
	}
	return false;
}

char BigData:: SubLoop(char *&pLeft,int &LSize,char *pRight,int RSize) //除法时每次求商运算。
{
	assert(pLeft);
	assert(pRight);
	char count = '0';
	//这个while循环就是试除,比如222 /33  = 6, 我们可以让222一直减去33,减一次count++,最终减去6次后,剩下24小于33,6就是我们要的商。
	//   222   33
	while (IsLeftStrBig(pLeft,LSize,pRight,RSize))  
	{
		for (int i = 0; i < LSize; ++i)
		{
			char temp = pLeft[LSize-1-i] - '0';  //拿到被除数的最低位
			if(RSize > i)
				temp -= (pRight[RSize-1-i] - '0');  //最低位相减。
			if (temp < 0)
			{
				pLeft[LSize-2-i] -= 1;  //次高位减1.
				temp += 10;
			}
			pLeft[LSize-1-i] = temp + '0';  //写回去。
		} //for循环完了就减去一次33.
		count++;

		while (*pLeft == '0' && LSize > 0) //当有前置0的时候需要跳过去。比如222 -33 某一个过程会减到090,本来90比33大,但是090字典排序小于33,不会进循环了。
		{
			pLeft++;  //这里pLeft和LSize都移动了,要影响到外面,得用引用。
			LSize--;
		}

	} //当减去后剩下的数比33大就一直减。

	return count;
}


(6)求模:

///        求模          ///


 //求模只和左侧符号相关,我们可以先把两个数都换成正数,模 = 被除数-除数*商,再看被除数的符号决定模的符号。
BigData BigData:: operator%(const BigData & b) 
{
	if (b._strData[1] == '0')
	{
		cout << "除数为0或对0求模: ";
		return BigData(0);
	}
	if (_strData == "+0") //被除数为0
	{
		return BigData(0);
	}

	if (!IsINT64OverFlow() && !b.IsINT64OverFlow()) //两个数不溢出。模肯定不溢出。
	{
		return BigData(_value % b._value);
	}

	if (_strData.size() < b._strData.size())
	{
		 return BigData(_strData);  //模只和左侧符号位相关。
		
	}
	else if (_strData.size() == b._strData.size())
	{
		if (strcmp(_strData.c_str()+1,b._strData.c_str()+1) < 0) //比较数据部分
		{
			return BigData (_strData); //模只和左侧符号位相关。
		}
		if (strcmp(_strData.c_str()+1,b._strData.c_str()+1) == 0) //比较数据部分
		{
				return BigData(0);
		}
	}

	return BigData(Mod(_strData,b._strData));

}

string BigData::Mod(string left,string right)			
{
	BigData n1(left.c_str()+1);  //实验发现80%(-30) = 20,(-80)%(-30) = -20; (-80)%30 = -20  ,只是和左边的符号有关,和右边符号无法。
	BigData n2(right.c_str()+1);
	BigData n3 = n1 / n2;  //商
	BigData ret = n1 - n2*n3;
	ret._strData[0] = left[0];
	return ret._strData;
}


(7)四则运算

/* 以下是四则运算之表达式 */
/*
	1.遇到操作数:直接输出(添加到后缀表达式中)
	2.栈为空时,遇到运算符,直接入栈
	3.遇到左括号:将其入栈
	4.遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出。
	5.遇到其他运算符:加减乘除:弹出  所有优先级大于或者等于该运算符的  栈顶元素,然后将该运算符入栈
	6.最终将栈中的元素依次出栈,输出。
*/
//得到后缀表达式

string BigData::GetSuffixExpression(string str) 
{

	stack<char> operatorstack; //操作符栈
	string postresult;

	char *pst = (char*)str.c_str();
	string data ;
	while (*pst != '\0')
	{
		if (isdigit(*pst)) //如果是数据 1.遇到操作数:直接输出(添加到后缀表达式中)
		{
			//得到数据。
			data = GetData(pst);
			postresult += data;
			postresult += '#'; //这个是标记,没什么意义
		}
		else if (IsOperator(*pst)) //如果是操作符,
		{
			//5.遇到其他运算符:加减乘除:弹出 所有优先级大于或者等于该运算符的  栈顶元素,然后将该运算符入栈
			while ( !operatorstack.empty() &&CompareOperatorPriority(operatorstack.top(),*pst) >= 0)//栈顶元素大于等于该运算符
			{
				postresult += operatorstack.top();
				operatorstack.pop();
			}
			operatorstack.push(*pst);     // 2.栈为空时,遇到运算符,直接入栈

		}
		else if (*pst == '(') //如果是左括号(     3.遇到左括号:将其入栈
		{
			operatorstack.push(*pst);
		}
		else if (*pst == ')')    //4.遇到右括号:执行出栈操作,并将出栈的元素添加到后缀表达式,直到弹出栈的是左括号,左括号不输出。
		{
			while (operatorstack.top() != '(')
			{
				postresult += operatorstack.top();
				operatorstack.pop();
			}
			operatorstack.pop();  //将左括号弹出。
		}
		pst++;
	}

	while (!operatorstack.empty() ) // 6.最终将栈中的元素依次出栈,输出。
	{
		postresult += operatorstack.top();
		operatorstack.pop();
	}

	return postresult;
}



//根据后缀表达式计算
BigData BigData::CalPostExp(string str)
{
	char* pStart = (char*)str.c_str();
	stack<BigData> stackData;
	string tempStr;

	while(*pStart != '\0')
	{
		if ( isdigit(*pStart) )
		{
			tempStr = GetData(pStart);
			BigData temp(tempStr); 
			stackData.push(temp);
		}
		if(IsOperator(*pStart))
		{
			BigData right(stackData.top()); //这里要注意,栈顶的是右操作数
			stackData.pop();
			BigData left(stackData.top());
			stackData.pop();
			switch(*pStart)
			{
			case '+':
				stackData.push(left+right);
				break;
			case '-':
				stackData.push(left-right);
				break;
			case '*':
				stackData.push(left*right);
				break;
			case '/':
				stackData.push(left/right);
				break;
			default:
				cout << "后缀表达式中出现非法字符!" << endl;
				return BigData(0);
			}

		}
		pStart++;
	}	
	return BigData(stackData.top());
}


string BigData::GetData( char *& ptr)
{
	string ret;
	while (isdigit(*ptr))
	{
		ret += *ptr;
		ptr++;
	}
	ptr--;  //这里减回去,在被调用函数中会有ptr++,
	return ret;
}
bool BigData:: IsOperator(char c)
{
	if( c == '+' || c == '-' || c == '*' || c == '/')
	{
		return true;
	}else
	{
		return false;
	}
}
int  BigData::CompareOperatorPriority(char op1,char op2)
{

	if (op1 == '(')  //
	{
		return -1;
	}
	switch (op1)
	{
	case '+':
	case '-':
		return (op2 == '*' || op2 == '/'  ? -1:0);
	case '*':
	case '/':
		return (op2 == '-' || op2 == '+'? 1:0);
	}
	return -1;
}

BigData BigData:: Calculate(const string & str)//计算四则运算表达式
{
	/* 检查是否合法*/

	// 1. 中缀转后缀
	string post = GetSuffixExpression(str);
	// 2. 计算结果 
	return CalPostExp(post);
}



测试函数:

(1)数据的合法性:

void test()
{
	BigData b1("");
	BigData b2("123456789");
	BigData b3("-123456789");
	BigData b4("-000001234567");
	BigData b5("12345asdfg123456");
	BigData b6("aa12345689");
	BigData b7(+123);

	cout<<b1<<endl;
	cout<<b2<<endl;
	cout<<b3<<endl;
	cout<<b4<<endl;
	cout<<b5<<endl;
	cout<<b6<<endl;
	cout << b7 <<endl;

}




(2)加法和减法:

void testAddAndSub()
{
	BigData a("999999999999999999999999999999999999999999999999999999999999999999");
	BigData b("-2222");
	cout << a+b <<endl;
	BigData a1("2222");
	BigData b1("-99999999999999999999999999999999999999999999");
	cout << a1+b1 <<endl;


	BigData c("9999999999999999999999999999999999999999999977777777777");
	BigData d("-2222");
	cout << c-d <<endl;
	
	BigData c1("-9999999999999999999999999999999999999999999977777777777");
	BigData d1("2222");
	cout << c1-d1 <<endl;

	BigData c3("-22222");
	BigData c4("7777777777777777777777777777777777777777777777777777777");
	cout << c3- c4<<endl;

	BigData c2("-9999999999999999999999999999999999999999999999999999999");
	BigData d2("2222222222222222222222222222222222222222222222222222222");
	cout << d2 - c2 <<endl;

	

	BigData d5("9223372036854775807");
	BigData d6("-2");
	BigData d7(88);
	d7 = d5 - d6;
	cout << d7 << endl;


}


(3)乘法:

void testMul()  
{  
	BigData b1("-45353");  
	BigData b2("37353753");  
	BigData b3("-9223372036854775808");  
	BigData b4(" 9223372036854775800");  
	BigData b5("-9223372036854775810");  
	BigData b6(" 9223372036854775900");  
	//1、都在INT64范围内  
	cout << (BigData("999") * BigData("22222222222222222222222222222")) << endl;  

	cout << (b2 * b1) << endl;  
	cout << (b1 * b2) << endl;  
	cout << (b1 * BigData("0")) << endl;  
	cout << (BigData("0") * b2) << endl;  
	cout << endl;  
	cout << (b3 * b1) << endl;  
	cout << (b1 * b3) << endl;  
	cout << (b1 * b4) << endl;  
	cout << (b4 * b1) << endl;  
	cout << (b3 * b2) << endl;  
	cout << (b2 * b4) << endl;  
	cout << endl;  

	//2、一个在一个不在<运算后在范围内,运算后不在范围内>  

	cout << (BigData("0") * b6) << endl;  
	cout << (b5 * BigData("0")) << endl;  
	cout << (b5 * b1) << endl;  
	cout << (b1* b5) << endl;  
	cout << endl;  
	cout << (b6 * b2) << endl;  
	cout << (b2 * b6) << endl;  
	cout << endl;  
	cout << (b6 * b5) << endl;  
	cout << (b5 * b6) << endl;  
	cout << (b2 * b5) << endl;  
	cout << endl;  
	cout << (b1 * b6) << endl;  
	cout << (b6 * b1) << endl;  
}  


(4)除法

void testDiv()
{

	BigData b1("-45353");  
	BigData b2("37353753");  
	BigData b3("-9223372036854775808");  
	BigData b4(" 9223372036854775800");  
	BigData b5("-9223372036854775810");  
	BigData b6(" 9223372036854775900");  
	BigData b7("-1231123203367738338252");  


	//1、排除除数为0  
//	cout << (b1 / BigData(0)) << endl;  

	//2、在范围内  

	cout << (b1 / b2) << endl;  
	cout << (b2 / b1) << endl;  


	//3、不在范围内<左(被除数)比右(除数)小为0,左比右大>  
	cout << (b2 / b5) << endl;  
	cout << (b2 / b6) << endl;  

	cout << (b5 / b2) << endl;  
	cout << (b6 / b2) << endl;  
	cout << (b6 / b1) << endl;  
	cout << (b5 / b1) << endl;  

	cout << b7 / b1 << endl;  

	BigData a(222);
	BigData b(33);
	cout << a/b <<endl;
}


(5)求模:
void testMod()
{
	BigData b1("-45353");
	BigData b2("37353753");
	BigData b3("-9223372036854775808");  
	BigData b4(" 9223372036854775800");  
	BigData b5("-9223372036854775810");  
	BigData b6(" 9223372036854775900");  
	BigData b7("-1231123203367738338252");  

	//1、排除除数为0  
	//cout << (b1 / BigData(0)) << endl;  

	//2、在范围内  

	cout << (b1 % b2) << endl;  
	cout << (b2 % b1) << endl;  


	//3、不在范围内  
	cout << (b2 % b5) << endl;  
	cout << (b2 % b6) << endl;  

	cout << (b5 % b2) << endl;  

	cout << (b6 % b2) << endl;  
	cout << (b6 % b1) << endl;  
	cout << (b5 % b1) << endl;  

	cout << b7 % b1 << endl;  

}

(6)四则运算:

void testexpression()
{
	BigData ret  =  BigData::Calculate("989416326513+(547461030974961130-46113031)*46413031+1/2");
	cout << ret <<endl;
	BigData ret2  =  BigData::Calculate("12             * ( 3 + 4 )- 6 + 8 / 2");
	cout << ret2 <<endl;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值