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

实现大数四则运算

发布时间:2021-05-27 11:39:35 所属栏目:大数据 来源:网络整理
导读:副标题#e# ? ? ? ? 由于编程语言提供的基本数值数据类型表示的数值范围有限,不能满足较大规模的高精度数值计算,因此需要利用其他方法实现高精度数值的计算,于是产生了大数运算。大数运算主要有加、减、乘三种方法。那么大数到底如何进行运算呢,学习过数

大数的减法运算:

BigData?BigData::operator-(const?BigData&?bigdata)
{
	//两个数都没溢出,结果也没溢出,直接进行相加
	if?(IsINT64OverFlow()?&&?bigdata.IsINT64OverFlow())
	{
		if?(_strData[0]?==?bigdata._strData[0])
		{
			return?_value?+?bigdata._value;
		}
		else
		{
			//两个数异号,相减没溢出
			//-10?+?3?=?-7?<=?-6(减式:3-(-6));10+(-3)=?7?>=?6(减式:-3-(6))
			if?(_value?>=?0?&&?(MIN_INT64?+?_value?<=?bigdata._value)?||
				_value?<?0?&&?(MAX_INT64?+?_value?>=?bigdata._value))
			{
				return?_value?+?bigdata._value;
			}
			else
			{//不用使bigdata._strData[0]设为'-',Add符号随左边数字即被减数(-9999-1?=?-10000)
				BigData(Add(_strData,?bigdata._strData).c_str());
			}
		}
	}
	//两个数至少一个溢出,
	//同号调用减法
	if?(_strData[0]?==?bigdata._strData[0])
	{
		return?BigData(Sub(_strData,?bigdata._strData).c_str());
	}
	else
	{
		return?BigData(Add(_strData,?bigdata._strData).c_str());
	}
	return?BigData(INT64(0));
}
std::string?BigData::Sub(std::string?left,?std::string?right)
{
	int?iLsize?=?left.size();
	int?iRsize?=?right.size();
	char?cSymbol?=?left[0];//保存所得差的符号位
	if?(iLsize?<?iRsize?||?(iLsize==iRsize?&&?left?<?right))//左边小于右边都进行交换
	{//-12-(-21)=9,21-34=-13发现两数的差与减数的相反
		std::swap(left,right);
		std::swap(iLsize,?iRsize);
		if?(cSymbol?==?'-')
		{
			cSymbol?=?'+';
		}
		else
		{
			cSymbol?=?'-';
		}
	}
	std::string?sRet;
	sRet.resize(iLsize);
	sRet[0]?=?cSymbol;//保存符号位
	for?(int?iIdx?=?1;?iIdx?<?iLsize;?iIdx++)//结束标志为iLsize-1,不是iLsize
	{
		//从低到高,取left每一位;
		char?cRet?=?left[iLsize?-?iIdx]?-?'0';
		//在right范围内从低到高,取right每一位,然后相减;
		if?(iIdx?<?iRsize)
		{
			cRet?-=?right[iRsize?-?iIdx]?-?'0';
		}
		//判断是否借位
		if?(cRet?<?0)
		{
			left[iLsize?-?iIdx?-?1]?-=?1;
			cRet?+=?10;
		}
		sRet[iLsize?-?iIdx]?=?cRet?+?'0';
	}
	return?sRet;
}

大数的乘法运算:

BigData?BigData::operator*(const?BigData&?bigdata)
{
	if?(IsINT64OverFlow()?&&?bigdata.IsINT64OverFlow())
	{
		if?(_strData[0]?==?bigdata._strData[0])
		{
		????//例如:边界是10,10?/?2?=?5?>?4;?10?/?-2?=?-5?<?-4;
			if?(_value?>?0?&&?MAX_INT64?/?_value?>=?bigdata._value?||
				_value?<?0?&&?MAX_INT64?/?_value?<=?bigdata._value)
			{
				return?_value*bigdata._value;
			}
		}
		else
		{
			//例如:边界是-10,-10?/?2?=?-5?<?-4;?-10?/?-2?=?5?>?4;
			if?(_value>0?&&?MIN_INT64?/?_value?<=?bigdata._value?||
				_value?<?0?&&?MIN_INT64?/?_value?>=?bigdata._value)
			{
				return?_value*bigdata._value;
			}
		}
	}
	//两数至少有一个溢出
	if?(_value?!=?0?&&?bigdata._value?!=?0)
	{
		return?BigData(Mul(_strData,?bigdata._strData).c_str());
	}
	return?BigData(INT64(0));
}
std::string?BigData::Mul(std::string?left,?std::string?right)
{
	int?iLsize?=?left.size();
	int?iRsize?=?right.size();
	char?cSymbol?=?'+';//确认符号位
	if?(left[0]?!=?right[0])
	{
		cSymbol?=?'-';
	}
	if?(iLsize?>?iRsize)//使较小的数为left,提高效率。eg:99*12345678
	{
		swap(left,?right);
		swap(iLsize,?iRsize);
	}
	std::string?sRet;
	//两个数相乘最大位数为两个数位数的和,left和right中有符号位故减1
	sRet.assign(iLsize?+?iRsize?-?1,?'0');//assign()为字符串赋新值'0'
	sRet[0]?=?cSymbol;
	int?iDataLen?=?iLsize?+?iRsize?-?1;
	int?ioffset?=?0;//移位
	//先取左边一位和右边相乘;再考虑移位可得到左边每位与右边相乘的结果
	for?(int?iLdx?=?1;?iLdx?<?iLsize;?iLdx++)
	{
		char?cLeft?=?left[iLsize?-?iLdx]?-?'0';
		if?(cLeft?==?0)//如果left中含有0,偏移量加1
		{
			ioffset++;
			continue;
		}
		char?Step?=?0;
		//99*999=89910+8991;
		for?(int?iRdx?=?1;?iRdx?<?iRsize;?iRdx++)
		{
			char?cRet?=?cLeft?*?(right[iRsize?-?iRdx]?-?'0')?+?Step;
			cRet?+=?sRet[iDataLen?-?iRdx?-?ioffset]?-?'0';//cRet存放当前位最终乘加的结果
			sRet[iDataLen?-?iRdx?-?ioffset]?=?cRet?%?10?+?'0';//存放字符+'0'
			Step?=?cRet?/?10;
		}
		sRet[iDataLen?-?iRsize?-?ioffset]?+=?Step;
		ioffset++;
	}
	return?sRet;
}

(编辑:大连站长网)

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