加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

大数运算

发布时间:2020-12-14 01:54:10 所属栏目:大数据 来源:网络整理
导读:? ?本人在在写这个小项目的时候,首先考虑到数的存储问题。计算机能够表示的最大值为0x7FFFFFFFFFFFFFFF,最小值为0x8000000000000000,那么要运算比这个大的数字该怎么办呢?是否可以使用字符串来保存比计算机能够表示的最大的数呢?怎么初始化大数呢?字符

? ?本人在在写这个小项目的时候,首先考虑到数的存储问题。计算机能够表示的最大值为0x7FFFFFFFFFFFFFFF,最小值为0x8000000000000000,那么要运算比这个大的数字该怎么办呢?是否可以使用字符串来保存比计算机能够表示的最大的数呢?怎么初始化大数呢?字符串的加减乘除该怎么实现呢?成员变量需要怎么定义呢?

? ?1.是否可以使用字符串来保存比计算机能够表示的最大的数呢?

? ? 学过c++的同学肯定对string很熟悉,是c++用来维护字符串的一个类。可以用来维护字符串。

? ? ?1).加法:用字符串模仿加法,以此取到左右操作数的最低位相加模拟加法。

? ? ?2).减法:同样可以取到左右操作数的最低位进行模拟减法。

????3).乘法:同样可以取道左右操作数的最低位进行模拟乘法。

????4).除法:可以取到和右操作数相同的位数或者大一位进行模拟除法。

? ? 相同这些那么类的成员变量就不难得出了。

class?BigData
{

private:
?????long?long?_value;
?????string?_strData;
};

? ? 2.怎么初始化大数呢?

? ? ?初始化字符串是为了更好的支持,加减乘除的运算。那么初始化分为几个部分?显而易见分为两个部分---1.long long类型以内的整数 2.字符串类型。当然这里考虑的是字符串的初始化。

? ?eg:传入字符串"123456" "+123456" "-123456" " ? ?" "00000123456" "qwert123456" "1234567qwert" 该怎么样初始化呢?

????1).为了后面的计算,我们首先需要在字符串的前面设置一个符号位用了保存字符串的属性。那么首当其冲就是判断符号位了。

????2).接下来就要处理有效位前面有0的情况。

????分析上面的字符串现在变成什么样的情况--"123456"??"123456" "123456" "123456" "1234567qwert"??

????3).那么就很好确定思路处理"1234567qwert"的情况然后将字符串保存在string _strData中。

????4).会发现_strData中字符串是反序的 --- "654321",所以需要逆序字符串。

wKioL1cXlfijuTkMAABLd3V3IMU517.png

????

????BigData::BigData(INT64?x)
???????:_value(x)
????{
????	_INIT64ToString();
????}
????
????
????BigData::BigData(const?char*?cData)
????{
????	if?(cData?==?NULL)
????	{
????		assert(false);
????		return;
????	}
????
????	char*?ptr?=?(char*)cData;
????	char?cSymbol?=?cData[0];???//“0000”??""
????
????	if?(cSymbol?==?'-'?||?cSymbol?==?'+')
????	{
????		ptr++;
????	}
????	else?if?(cSymbol?>=?'0'?&&?cSymbol?<=?'9')
????	{
????		cSymbol?=?'+';
????	}
????	else
????	{
????		return;
????	}
????
????	while?(*ptr?==?'0')
????	{
????		++ptr;
????	}
????
????	_strData.resize(strlen(cData)?+?1);
????	_strData[0]?=?cSymbol;
????
????	_value?=?0;
????	int?iCount?=?1;
????
????	while?(*ptr?>=?'0'?&&?*ptr?<=?'9')
????	{
????		_value?=?_value?*?10?+?(*ptr?-?'0');
????		_strData[iCount++]?=?*ptr;
????		++ptr;
????	}
????
????	_strData.resize(iCount);
????
????	if?(cSymbol?==?'-')
????	{
????		_value?=?0?-?_value;
????	}
????}
????
????void?BigData::_INIT64ToString()
????{
????	char?cSymbol?=?'+';
????	if?(_value?<?0)
????	{
????		cSymbol?=?'-';
????		//----------------------------------------------------
????	}
????
????	INT64?tmp?=?_value;
????	_strData.append(1,?cSymbol);
????
????	while?(tmp)
????	{
????		_strData.append(1,?tmp?%?10?+?'0');
????		tmp?/=?10;
????	}
????
????	char*?pLeft?=?(char*)_strData.c_str()?+?1;
????	char*?pRight?=?pLeft?+?_strData.size()?-?2;
????
????	while?(pLeft?<?pRight)
????	{
????		char?cmp?=?*pLeft;
????		*pLeft?=?*pRight;
????		*pRight?=?cmp;
????		pLeft++;
????		pRight--;
????	}
????}

????3.字符串的加减乘除该怎么实现呢?

wKioL1cXlnSS5VS5AABVxZZfYnk950.png

wKioL1cXlnSjko5-AAA6ceJMGPg574.png

bool?BigData::isOverFlowINT64()const????
????{
????	string?tmp("9223372036854775807");
????
????	if?(_strData[0]?==?'-')
????	{
????		tmp?=?"-9223372036854775808";
????	}
????
????	if?(_strData.size()?<?tmp.size())
????	{
????		return?true;
????	}
????	else?if?(_strData.size()?==?tmp.size()?&&?_strData<tmp)
????	{
????		return?true;
????	}
????
????	return?false;
????}
????
????
????ostream&?operator<<(ostream&?out,?const?BigData&?bigdata)
????{
????
????	if?(bigdata.isOverFlowINT64())
????	{
????		out?<<?bigdata._value;
????		return?out;
????	}
????	else
????	{
????		char*?pstr?=?(char*)bigdata._strData.c_str();
????
????		if?(pstr[0]?==?'+')
????		{
????			pstr++;
????		}
????		out?<<?pstr;
????	}
????	return?out;
????}
????
????
????BigData?BigData::operator+(const?BigData&?bigdata)
????{
????	if?(isOverFlowINT64()?&&?bigdata.isOverFlowINT64())
????	{
????		if?(_strData[0]?!=?bigdata._strData[0])
????		{
????			return?(_value?+?bigdata._value);
????		}
????		else
????		{
????			INT64?tmp?=?MIN_INT64;
????			if?(_value?>?0?&&?MAX_INT64?-?_value?>=?bigdata._value
????				||?_value?<?0?&&?tmp?-?_value?<=?bigdata._value)????//--------------
????			{
????				return?(_value?+?bigdata._value);
????			}
????		}
????	}
????
????	if?(_strData[0]?==?bigdata._strData[0])????//同号溢出的情况,调用jianfa------------------------------
????	{
????		return?BigData(Add(_strData,?bigdata._strData).c_str());???
????	}
????
????	return?BigData(Sub(_strData,?bigdata._strData).c_str());?//异号溢出的情况,调用jiafa
????}
????
????BigData?BigData::operator-(const?BigData&?bigdata)
????{
????	if?(isOverFlowINT64()?&&?bigdata.isOverFlowINT64())
????	{
????		if?(_strData[0]?==?bigdata._strData[0])
????		{
????			return?BigData(_value?-?bigdata._value);
????		}
????		else
????		{
????			if?((_value?>?0?&&?MAX_INT64?+?bigdata._value?>=?_value)?||
????				(_value?<?0?&&?MIN_INT64?+?bigdata._value?<=?_value))
????			{
????				return?BigData(_value?-?bigdata._value);
????			}
????		}
????	}
????
????	if?(_strData[0]?!=?bigdata._strData[0])
????	{
????		return?BigData(Add(_strData,bigdata._strData).c_str());
????	}
????
????	return?BigData(Sub(_strData,?bigdata._strData).c_str());
????}
????
????BigData?BigData::operator*(const?BigData&?bigdata)
????{
????	if?(_value?==?0?||?bigdata._value?==?0)
????	{
????		return?BigData(INT64(0));
????	}
????	if?(isOverFlowINT64()?&&?bigdata.isOverFlowINT64())
????	{
????		if?(_strData[0]?==?bigdata._strData[0])
????		{
????			if?((_value?>?0?&&?MAX_INT64?/?_value?>=?bigdata._value)?||
????				(_value?<?0?&&?MIN_INT64?/?_value?<=?bigdata._value))????//??-10?-2?=?5?
????			{
????				return?BigData(_value?*?bigdata._value);
????			}
????		}
????		else
????		{
????			//-10?2?-5
????			if?((_value?>?0?&&?MIN_INT64?/?_value?<=?bigdata._value)?||??????//-10??2??=?-5?<=?-3?
????				(_value?<?0?&&?MIN_INT64?/?_value?>=?bigdata._value))????????//-10?-2??=??5??>=?3
????			{
????				return?BigData(_value?*?bigdata._value);
????			}
????		}
????	}
????
????	return?BigData(Mul(_strData,?bigdata._strData).c_str());
????}
????
????
????BigData?BigData::operator/(const?BigData&?bigdata)
????{
????	if?(bigdata._strData[1]?==?'0')??????//处理除数为0的情况
????	{
????		assert(false);
????	}
????
????	if?(isOverFlowINT64()?&&?bigdata.isOverFlowINT64())???//处理不溢出的情况
????	{
????		return?BigData(_value?/?bigdata._value);
????	}
????
????	if?(_strData.size()?<?bigdata._strData.size()?||????//左边小于右边的情况
????		(_strData.size()?==?bigdata._strData.size()
????		&&?strcmp(_strData.c_str()?+?1,?bigdata._strData.c_str()?+?1)?<?0))
????	{
????		return?BigData(INT64(0));
????	}
????
????	if?(bigdata._strData?==?"-1"?||?bigdata._strData?==?"+1")????//处理除数为+1?-1的情况
????	{
????		string?ret?=?_strData;
????
????		if?(_strData[0]?!=?bigdata._strData[0])
????		{
????			ret[0]?=?'-';
????		}
????		return?BigData(ret.c_str());
????	}
????
????	if?(_strData.size()?==?bigdata._strData.size()??????????????//处理除数与被除数一样的情况(除过符号位)
????		&&?strcmp(_strData.c_str()?+?1,?bigdata._strData.c_str()?+?1)?==?0)
????	{
????		string?ret?=?"+1";
????
????		if?(_strData[0]?!=?bigdata._strData[0])
????		{
????			ret[0]?=?'-';
????		}
????
????		return?BigData(ret.c_str());
????	}
????
????	return?BigData(Div(_strData,?bigdata._strData).c_str());
????}
????
????
????string?BigData::Add(string?left,?string?right)
????{
????
????	int?leftsize?=?left.size();
????	int?rightsize?=?right.size();
????
????	if?(leftsize?<?rightsize)
????	{
????		swap(left,?right);
????		swap(leftsize,?rightsize);
????	}
????
????	string?iRet;
????	iRet.resize(leftsize?+?1);
????	iRet[0]?=?left[0];
????????int?step?=?0;
????
????	for?(int?i?=?1;?i?<?leftsize;?i++)
????	{
????		char?cRet?=?left[leftsize?-?i]?-?'0'?+?step;
????
????		if?(i?<?rightsize)
????		{
????			cRet?+=?right[rightsize?-?i]?-?'0';
????		}
????
????		iRet[leftsize?-?i?+?1]?=?cRet?%?10?+?'0';
????
????		step?=?cRet/10;
????	}
????	iRet[1]?=?step?+?'0';
????
????	return?iRet;
????
????}
????
????
????string?BigData::Sub(string?left,?string?right)
????{
????	int?leftsize?=?left.size();
????	int?rightsize?=?right.size();
????
????	char?cSymbol?=?'+';
????	//10?-?11?=?-1
????	//-3?-?-7?=?4
????	if?(leftsize?<?rightsize?||?leftsize?==?rightsize?&&?left<right)
????	{
????		swap(left,?rightsize);
????		if?(cSymbol?==?'+')
????		{
????			cSymbol?=?'-';
????		}
????		else
????		{
????			cSymbol?=?'+';
????		}
????	}
????
????	string?strRet;
????	strRet.resize(left.size());
????	strRet[0]?=?cSymbol;
????
????
????	for?(int?Idx?=?1;?Idx?<?leftsize;?++Idx)
????	{
????		char?cRet?=?left[leftsize?-?Idx]?-?'0';
????		if?(Idx?<?rightsize)
????		{
????			cRet?-=?right[rightsize?-?Idx]?-?'0';
????		}
????
????		if?(cRet?<?0)
????		{
????			left[leftsize?-?Idx?-?1]?-=?1;
????			cRet?+=?10;
????		}
????
????		strRet[leftsize?-?Idx]?=?cRet?+?'0';
????	}
????
????	return?strRet;
????}
????
????
????string?BigData::Mul(string?left,?string?right)
????{
????	char?cSymbol?=?'+';
????	if?(left[0]?!=?right[0])
????	{
????		cSymbol?=?'-';
????	}
????	int?leftsize?=?left.size();
????	int?rightsize?=?right.size();
????
????	if?(leftsize?<?rightsize)
????	{
????		swap(left,?rightsize);
????	}
????
????	string?sRet;
????	sRet.assign(leftsize?+?rightsize?-?1,'0');
????	sRet[0]?=?cSymbol;
????	int?iDataLen?=?sRet.size();
????	int?ioffset?=?0;
????
????	for?(int?iLIdx?=?1;?iLIdx?<?leftsize;?iLIdx++)
????	{
????		char?cLeft?=?left[leftsize?-?iLIdx]?-?'0';
????		char?cStep?=?0;
????		if?(cLeft?==?'0')
????		{
????			ioffset++;
????			continue;
????		}
????
????		for?(int?iRIdx?=?1;?iRIdx?<?rightsize;?iRIdx++)
????		{
????			char?cRet?=?cLeft*(right[rightsize?-?iRIdx]?-?'0')?+?cStep;
????			cRet?+=?sRet[iDataLen?-?iRIdx?-?ioffset]?-?'0';
????			sRet[iDataLen?-?iRIdx?-?ioffset]?=?(cRet?%?10?+?'0');
????			cStep?=?cRet/10;
????		}
????		sRet[iDataLen?-?rightsize?-?ioffset]?+=?cStep;
????		ioffset++;
????	}
????	return?sRet;
????}
????
????string?BigData::Div(string?left,?string?right)
????{
????	string?sRet;
????	sRet.append(1,?'+');
????	if?(left[0]?!=?right[0])
????	{
????		sRet[0]?=?'-';
????	}
????
????	char*?pLeft?=?(char*)(left.c_str()?+?1);
????	char*?pRight?=?(char*)(right.c_str()?+?1);
????	int?DataLen?=?right.size()?-?1;
????	int?Lsize?=?left.size()?-?1;
????
????	for?(int?iIdx?=?0;?iIdx?<?Lsize;)
????	{
????		if?(*pLeft?==?'0')
????		{
????			sRet.append(1,?'0');
????			pLeft++;
????			iIdx++;
????			continue;
????		}
????
????		if?(!IsLeftStrBig(pLeft,?DataLen,?pRight,?right.size()?-?1))
????		{
????			sRet.append(1,?'0');
????			DataLen++;
????			if?(DataLen?+?iIdx?>?Lsize)
????			{
????				break;
????			}
????		}
????		else
????		{
????			sRet.append(1,?subloop(pLeft,?right.size()?-?1));
????
????			while?(*pLeft?==?'0'?&&?DataLen?>?0)
????			{
????				pLeft++;
????				iIdx++;
????				DataLen--;
????			}
????
????			DataLen++;
????			if?(DataLen?+?iIdx?>?Lsize)
????			{
????				break;
????			}
????		}
????	}
????	return?sRet;
????}
????
????
????bool?BigData::IsLeftStrBig(const?char*?pLeft,?int?Lsize,?const?char*?pRight,?int?Rsize)
????{
????	if?(Lsize?>?Rsize?||?(Lsize?==?Rsize?&&?strcmp(pLeft,?pRight)?>=?0))
????	{
????		return?true;
????	}
????	else
????	{
????		return?false;
????	}
????}
????
????char?BigData::subloop(char*?pLeft,?char*?pRight,?int?Rsize)
????{
????	assert(pLeft?&&?pRight);
????
????	char?cRet?=?'0';
????
????	while?(1)
????	{
????		if?(!IsLeftStrBig(pLeft,?Lsize,?Rsize))
????		{
????			break;
????		}
????
????		int?LDataLen?=?Lsize?-?1;
????		int?RDataLen?=?Rsize?-?1;
????
????		while?(LDataLen?>=?0?&&?RDataLen?>=?0)
????		{
????			char?ret?=?pLeft[LDataLen]?-?'0';
????			ret?-=?pRight[RDataLen]?-?'0';
????
????			if?(ret?<?0)
????			{
????				pLeft[LDataLen?-?1]?-=?1;
????				ret?+=?10;
????			}
????
????			pLeft[LDataLen]?=?ret?+?'0';
????			LDataLen--;
????			RDataLen--;
????		}
????
????		while?(*pLeft?==?'0'?&&?Lsize?>?0?)
????		{
????			pLeft++;
????			Lsize--;
????		}
????		cRet++;
????	}
????	return?cRet;
????}

????4.BigData类

#pragma?once
#include<iostream>
#include<string>
#include<assert.h>
using?namespace?std;


typedef?long?long?INT64;
#define?MIN_INT64?0x8000000000000000
#define?MAX_INT64?0x7FFFFFFFFFFFFFFF


class?BigData
{
public:
	BigData(INT64?x);
	BigData(const?char*?cData);

	BigData?operator+(const?BigData&?bigdata);
	BigData?operator-(const?BigData&?bigdata);
	BigData?operator*(const?BigData&?bigdata);
	BigData?operator/(const?BigData&?bigdata);

protected:
	string?Add(string?left,?string?right);
	string?Sub(string?left,?string?right);
	string?Mul(string?left,?string?right);
	string?Div(string?left,?string?right);

	friend?ostream&?operator<<(ostream&?out,?const?BigData&?bigdata);
	bool?isOverFlowINT64()const;
	bool?IsLeftStrBig(const?char*?pLeft,?int?Rsize);
	char?subloop(char*?pLeft,?int?Rsize);
	void?_INIT64ToString();

private:
	INT64?_value;
	string?_strData;
};



总结:分为两种思路,处理long long 类型的方法 && 处理溢出的情况。

? 以上就是本人在学习过程中的一些经验总结。当然,本人能力有限,难免会有纰漏,希望大家可以指正。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读