高精度算法二

文章介绍了如何使用算法处理大整数乘以小整数以及大整数除以小整数的问题。乘法算法通过逐位相乘并处理进位来避免溢出,而除法算法从最高位开始计算,最后逆置结果数组。这两种方法都涉及到大整数的特殊处理和存储策略。
摘要由CSDN通过智能技术生成

1. 大整数 * 小整数

大整数 * 小整数的算法与我们平时计算乘法不完全相同。他是用小整数这个整体与大整数的每一位相乘,将结果保存到一个变量,例如 t 中,然后将 t % 10 即可得到结果的一位。然后将 t / 10 就可以得到进位,这里的进位不同于加法,加法的进位只可能是 1 ,而乘法的进位是多种多样的。当大整数的最高位乘上这个小整数后如果有进位,则将进位由低位到高位依次push_back到保存结果的数组中即可。

分析到这里我们也能够理解为啥是大整数 * 小整数,而不是大整数 * 大整数了:这里的算法是将一个整数看作整体,依次去和另一个整数的每一位相乘,然后将得到的结果保存在一个中间变量中,如果这是一个大整数,他去和另一个大整数相乘时,结果可能溢出,即超过中间变量的存储范围。

vector<int> mul(vector<int>& A, int b)
{
	vector<int> C;

	int t = 0;
	//这里将每一位的乘法和最高位产生进位的循环合并到一起了
	for (int i = 0; i < A.size()|| t; i++)
	{
		if (i < A.size())
		{
			t += A[i] * b;
		}
		C.push_back(t % 10);
		t /= 10;
		
	}
	return C;
}

void test03()
{
	string a;
	int b;
	
	cout << "请输入两个整数,以回车键结束" << endl;

	cin >> a >> b;

	vector<int> A;
	for (int i = a.size() - 1; i >= 0; i--)
		A.push_back(a[i] - '0');

	vector<int> C = mul(A, b);

	for (int i = C.size() - 1; i >= 0; i--)
	{
		cout << C[i];
	}
	cout << endl;
}

int main()
{

	//大整数的乘法
	test03();

	system("pause");
	return 0;
}

2. 大整数 / 小整数

该算法要求我们计算出最终的商和余数,同理如果是大整数 / 大整数的话,最终的余数可能无法用简单的数据类型来存储,所以这里我们计算的是大整数 / 小整数。

该算法和人类计算除法是相似的,只是人类会根据被除数的位数,直接判断出可能有结果的位,显然计算机是无法直接这么做的,只能对每一位进行计算。

 有一点与其他三种大整数的算法不同:除法是从最高位开始算的,这意味着,我们将结果保存到数组中时,下标为0的位置是存的最高位。显然,仅针对除法来说这是完全没有什么大的问题的,但是,在实际运算过程中,并不可能只进行除法运算,所以需要将大整数的存储方式统一。在完成计算后将数组逆序即可。

讲了这么多,除法该怎么算呢?从大整数的最高位开始,将每一位去和小整数(除数)相除得到的结果就是该位最终的结果,然后再将该位与小整数(除数)取模,在对下一位进行计算时,将取模得到的结果乘以 10 ,在加上这一位的数字。然后重复上述操作,直到算完大整数的每一位。如果说最后一位对小整数取模不为 0 ,得到的结果便是最终结果的余数啦。

 

//参数r用来接收余数
vector<int> div(vector<int>& A, int b, int& r)
{
	vector<int> C;

	r = 0;
	//不同于前三种,这是从最高位开始算
	for (int i = A.size() - 1; i >= 0; i--)
	{
		r = A[i] + r * 10;
		C.push_back(r / b);
		r = r % b;
	}

	//逆置数组
	reverse(C.begin(), C.end());

	//去掉前导0
	while (C.size() > 1 && C.back() == 0)
	{
		C.pop_back();
	}

	return C;


}

void test04()
{
	string a;
	int b;

	cout << "请输入两个整数,以回车键结束" << endl;

	cin >> a >> b;

	vector<int> A;
	for (int i = a.size() - 1; i >= 0; i--)
		A.push_back(a[i] - '0');


	int r;
	vector<int> C = div(A, b, r);

	cout << "结果:";
	for (int i = C.size() - 1; i >= 0;i--)
	{
		cout << C[i];
	}
	cout << endl;
	//输出余数
	cout << "余数:" << r << endl;

}


int main()
{

	//大整数的除法
	test04();

	system("pause");
	return 0;
}

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

姬如祎

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值