码迷,mamicode.com
首页 > 其他好文 > 详细

模拟大数据的基本计算, 以解决常规计算器计算数据时位数的有限性

时间:2016-04-25 19:42:51      阅读:361      评论:0      收藏:0      [点我收藏+]

标签:大数据加减乘除

项目名称 大数计算器

*************************************************

大数计算的底层采用string对象存储, 将整型数据转换为字符型进行存储运算的加减;采用逐位进行加减, 设计标记位, 标记进位与借位的方式;乘除在加减的基础上控制循环的次数完成对数据的处理

#include<iostream>
#include<cassert>
#include<string>
using namespace std;
#define INT_64 long long
#define UN_INIT  0xcccccccccccccccc//不能分开
#define MIN_INT  0xffffffffffffffff
#define MAX_INT  0x7fffffffffffffff
class  BigData
{
public:
	BigData()
		:_data(0)
		, _pdata("")
	{}
	BigData(INT_64 data)
		:_data(data)
	{
		INT_64 tmp = _data;
		char cSymbol = ‘+‘;
		if (tmp<0)
		{
			tmp = 0 - tmp;
			cSymbol = ‘-‘;
		}
		_pdata.append(1, cSymbol);
		while (tmp)
		{
			_pdata.append(1, tmp % 10 + ‘0‘);
			tmp /= 10;
		}
		char* left = (char*)(_pdata.c_str() + 1);
		char* right = (char*)(_pdata.c_str() + _pdata.size() - 1);
		char temp;
		while (left < right)
		{
			temp = *left;
			*left++ = *right;
			*right-- = temp;
		}
	}
	BigData(const char* pData)
	{
		assert(pData);
		INT_64 ret = 0;
		char* source = (char*)pData;
		char cSymbol = ‘+‘;
		if (*source == ‘-‘ || *source == ‘+‘)
			cSymbol = *source;
		//while (*source == ‘0‘)
			//source++;
		_pdata.append(1, cSymbol);
		while (*source <= ‘9‘&&*source >= ‘0‘)
		{
			if (ret <= MAX_INT)
				ret = ret * 10 + *source;
			_pdata.append(1, *source);
			source++;
		}
		if (*source = ‘-‘)
			ret = 0 - ret;
		_data = ret;
	}
	BigData(const BigData& bigData)
	{
		_data = bigData._data;
		_pdata = bigData._pdata;
	}
	BigData operator+(BigData& bigData)
	{
		if (!IsINT64OverFlow() && !bigData.IsINT64OverFlow())
		{
			if (_pdata[0] != bigData._pdata[0])
				return BigData(_data + bigData._data);
			else
			{
				if (‘+‘ == _pdata[0] && MAX_INT - _data <= bigData._data || ‘-‘ == _pdata[0] && _data >= MIN_INT - bigData._data)
					return  BigData(_data + bigData._data);
			}
		}
		return BigData(Add(_pdata, bigData._pdata).c_str());
	}
	BigData operator-(BigData& bigData)
	{
		if (!IsINT64OverFlow() && !bigData.IsINT64OverFlow())
		{
			if (_pdata[0] == bigData._pdata[0])
				return BigData(_data - bigData._data);
			else
			{
				if (‘+‘ == _pdata[0] && _data <= MAX_INT + bigData._data || ‘-‘ == _pdata[0] && _data >= MIN_INT + bigData._data)
					return  BigData(_data - bigData._data);
			}
		}
		string ret;
		if (_pdata[0] == bigData._pdata[0])
			ret = Sub(_pdata, bigData._pdata);
		else
		{
			ret = Add(_pdata, bigData._pdata);
			ret[0] = _pdata[0];
		}
		return BigData(ret.c_str());
	}
	BigData operator*(BigData& bigData)
	{
		if (!IsINT64OverFlow() && !bigData.IsINT64OverFlow())
		{
			if (_pdata[0] == bigData._pdata[0])
			{
				if (‘+‘ == _pdata[0] && _data <= MAX_INT / bigData._data || ‘-‘ == _pdata[0] && _data >= MAX_INT / bigData._data)
					return  BigData(_data *bigData._data);
			}
			else
			{
				if (‘+‘ == _pdata[0] && _data <= MIN_INT / bigData._data || ‘-‘ == _pdata[0] && _data >= MIN_INT / bigData._data)
					return  BigData(_data * bigData._data);
			}
		}
		return BigData(Mul(_pdata, bigData._pdata).c_str());
	}
	BigData operator/(BigData& bigData)
	{
		if (_data == 0 || bigData._data == 0)
			return BigData(INT_64(0));
		if (!IsINT64OverFlow() && !bigData.IsINT64OverFlow())
		{
			return BigData(_data / bigData._data);
		}
		return  BigData(Div(_pdata, bigData._pdata).c_str());
	}
	friend  ostream& operator<<(ostream& out, const BigData& b)
	{
		out << b._pdata;
		return out;
	}
	friend  istream& operator>>(istream& in, BigData& b)
	{
		in >> b._pdata;
		return in;
	}
protected:
	bool  IsINT64OverFlow()
	{
		if (_data <= MAX_INT&&_data >= MIN_INT)
			return false;
		return true;
	}
	string Add(string s1, string s2)
	{
		int leftSize = s1.size();
		int rightSize = s2.size();
		string ret;
		char cSymbol = ‘+‘;
		if (s1[0] == s2[0])
		{
			if (s1[0] == ‘-‘)
				cSymbol = ‘-‘;
		}
		else
		{
			if (s1[0] == ‘+‘&&strcmp(s1.c_str() + 1, s2.c_str() + 1) < 0 || s1[0] == ‘-‘&&strcmp(s1.c_str() + 1, s2.c_str() + 1)>0)
				cSymbol = ‘-‘;
		}
		if (leftSize < rightSize)
		{
			swap(s1, s2);
			swap(leftSize, rightSize);
		}
		ret.resize(leftSize + 1);
		ret[0] = cSymbol;
		char cRes, cStep = 0;
		for (int idx = 1; idx < leftSize; ++idx)
		{
			cRes = s1[leftSize - idx] - ‘0‘ + cStep;
			if (idx<rightSize)
				cRes += (s2[rightSize - idx] - ‘0‘);
			cStep = cRes / 10;
			ret[leftSize - idx + 1] = cRes % 10 + ‘0‘;
		}
		ret[1] = cStep + ‘0‘;
		return ret;
	}
	string Sub(string s1, string s2)
	{
		int leftSize = s1.size();
		int rightSize = s2.size();
		char cSymbol = s1[0];
		//leftSize == rightSize &&(cSymbol == ‘+‘&&strcmp(s1.c_str() + 1, s2.c_str() + 1) < 0 || cSymbol == ‘-‘&&strcmp(s1.c_str() + 1, s2.c_str() + 1) > 0)
		if (leftSize < rightSize || leftSize == rightSize &&strcmp(s1.c_str() + 1, s2.c_str() + 1) < 0)
		{
			swap(s1, s2);
			swap(leftSize, rightSize);
			if (‘+‘ == cSymbol)
				cSymbol = ‘-‘;
			else
				cSymbol = ‘+‘;
		}
		string ret;
		ret.resize(leftSize);
		ret[0] = cSymbol;
		char cRet;
		for (int idx = 1; idx < leftSize; ++idx)
		{
			cRet = s1[leftSize - idx] - ‘0‘;
			if (idx < rightSize)
				cRet -= (s2[rightSize - idx] - ‘0‘);

			if (cRet < 0)
			{
				s1[leftSize - idx - 1] -= 1;
				cRet += 10;
			}
			ret[leftSize - idx] = cRet + ‘0‘;
		}
		return ret;
	}
	string Mul(string s1, string s2)
	{
		int leftSize = s1.size();
		int rightSize = s2.size();
		if (leftSize < rightSize)
		{
			swap(leftSize, rightSize);
			swap(s1, s2);
		}
		char cSymbol = ‘+‘;
		if (s1[0] != s2[0])
			cSymbol = ‘-‘;
		string ret;
		ret.resize(leftSize + rightSize - 1);
		ret[0] = cSymbol;
		int iDataLen = ret.size();
		int offSet = 0;
		for (int idx = 1; idx < rightSize; ++idx)
		{
			char cLeft = s2[rightSize - idx] - ‘0‘;
			char cStep = 0;
			if (cLeft == 0)
			{
				++offSet;
				continue;
			}
			for (int iLdx = 1; iLdx < leftSize; ++iLdx)
			{
				char cRet = cLeft*(s1[leftSize - iLdx] - ‘0‘);
				cRet += (cStep + ret[iDataLen - iLdx - offSet] - ‘0‘);
				ret[iDataLen - iLdx - offSet] = cRet % 10 + ‘0‘;
				cStep = cRet / 10;
			}
			ret[iDataLen - offSet - leftSize] += cStep;
			++offSet;
		}
		return ret;
	}
	string Div(string s1, string s2)
	{
		int leftSize = s1.size();
		int rightSize = s2.size();
		char cSymbol = ‘+‘;
		if (s1[0] != s2[0])
		{
			cSymbol = ‘-‘;
		}
		if (leftSize < rightSize || (leftSize == rightSize&&strcmp(s1.c_str() + 1, s2.c_str() + 1)))
		{
			return "0";
		}
		else
		{
			if ("1" == s2 || "-1" == s2)
			{
				s1[0] = cSymbol;
				return s1;
			}
		}
		char *left = (char*)(s1.c_str() + 1);
		char* right = (char*)(s2.c_str() + 1);
		int iDataLen = rightSize - 1;
		string ret;
		for (int idx = 0; idx < leftSize - 1; ++idx)
		{
			if (!IsLeftStrRight(left, iDataLen, right, rightSize - 1))
			{
				iDataLen++;
				ret.append(1, ‘0‘);
				continue;
			}
			else
			{
				ret.append(1, SubLoop(left, iDataLen, right, rightSize - 1));
				iDataLen = rightSize - 1;
			}
		}
	}
	char SubLoop(char*& left, int lSize, char* right, int rSize)
	{
		assert(left&&right);
		char cRet = ‘0‘;
		while (1)
		{
			if (!IsLeftStrRight(left, lSize, right, rSize))
				break;
			int lDataLen = lSize;
			int rDataLen = rSize;
			while (lDataLen >= 0 && rDataLen >= 0)
			{
				if (left[lDataLen] < right[rDataLen])
				{
					left[lDataLen - 1] -= 1;
					left[lDataLen] += 10;
				}
				left[lDataLen] -= right[rDataLen];
				lDataLen--;
				rDataLen--;
			}
			while (‘0‘ == *left)
			{
				left++;
				lSize--;
			}
			cRet++;
		}
	}
	bool  IsLeftStrRight(char* left, int lSize, char* right, const int rSize)
	{
		assert(left&&right);
		if (lSize>rSize || lSize == rSize&&strncmp(left, right, lSize) >= 0)
			return true;
		return false;
	}
private:
	INT_64 _data;
	string _pdata;
};
void Test1()
{
	BigData b1(1234);
	BigData b2(123456789);
	BigData  b3= b1 + b2;
	cout << b3 << endl;
}


本文出自 “小止” 博客,请务必保留此出处http://10541556.blog.51cto.com/10531556/1767620

模拟大数据的基本计算, 以解决常规计算器计算数据时位数的有限性

标签:大数据加减乘除

原文地址:http://10541556.blog.51cto.com/10531556/1767620

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!