高精度的乘除法(C++实现)

前言:我们都熟知高精度的加减法可以用字符串来模拟实现,其实乘除法的高精度计算也和加减法类似却也略有不同,下面我们一起来看一下高精度的乘除法的模拟实现,希望可以帮助到大家。

目录

1.高精度乘法的实现

1.1原理重点难点解析

1.2代码实现

2.高精度除法的实现

2.1原理思路描述

2.2 代码实现

3.金句省身 


1.高精度乘法的实现

1.1原理重点难点解析

 原理上并不难,主要还是要注意代码实现的细节问题:

1.2代码实现

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
ll maxsize = 0;//用于记录最长的乘积位数
vector<vector<int>> mul(vector<int>& A, vector<int>& B)
{
	vector<vector<int>>ans;
	for (int i = 0; i < B.size(); i++)
	{
		vector<int> temp;
		for (int k = 0; k < i; k++)
			temp.push_back(0);
		int jinwei = 0;
		for (int j = 0; j < A.size(); j++)
		{
			jinwei += A[j] * B[i];
			temp.push_back(jinwei % 10);
			jinwei /= 10;
		}
		if (jinwei)
			temp.push_back(jinwei);
		ans.push_back(temp);
		maxsize = max(maxsize, (ll)temp.size());
		/*for (int l = temp.size()-1; l>=0; l--)
			cout << temp[l] << " ";
		cout << endl;
		*/
		temp.clear();
	}
	return ans;
}
vector<int> add(vector<vector<int>>& ans)
{
	vector<int> cot;
	int jinwei = 0;
	for (ll j = 0; j < maxsize||jinwei; j++)//最后一次进位有效时仍旧可以进入循环
	{
		for (int i = 0; i < ans.size(); i++)
		{
			if (j < ans[i].size())
				jinwei += ans[i][j];
		}
		cot.push_back(jinwei % 10);
		jinwei /= 10;
	}
	return cot;
}
int main()
{
	string s1, s2;
	cin >> s1 >> s2;
	if(s1=="0"||s2=="0")
	{
	    cout<<"0"<<endl;
	    return 0;
	}
	vector<int>a, b;
	for (int i = s1.size()-1; i >= 0; i--)
		a.push_back(s1[i] - '0');
	for (int i = s2.size()-1; i >= 0; i--)
		b.push_back(s2[i] - '0');
	auto c = mul(a, b);
	auto ans = add(c);
	for (int i = ans.size()-1; i>=0; i--)
		cout << ans[i];//结果为倒序输出的形式
	cout << endl;

	return 0;
}

2.高精度除法的实现

2.1原理思路描述

首先,我们这里应该是以高精度除高精度为条件,高精度除低精度的可以通过“弯道”超车,这里我们不予以讨论,只是以高精度除高精度为前提下的实现方式。

1.我们可以用循环减法模拟实现除法的商的计算,当我们的被减数减去减数还大于减数时,我们就可以让我们的该位上的商加1,直到该位上对应的被减数比减数小了,循环就停下来,此时的变量的累加值就是该位对应的商的结果。

 

2.在存储数组的时候是采取逆序还是正序存储呢,这里我用的是逆序存储,两者的区别在于,逆序存储时方便减法的计算,正序存储时方便除法的计算,其实除法的计算也包括了减法的计算,所以还是让减法运算更方便为好。

减法操作函数

3.如果我们的输入出现被除数比除数小的情况怎么办?

这个时候我们可以将其当做特殊情况进行处理即可,因为这种情况返回的结果不想要计算,直接返回被除数就好,商就是0了。

 

 剩下的就没什么难点了,重点是有很多的细节问题,我们在可以在心里模拟这个过程,包括移位啊,将被除数的下一位落下来等操作,都体现在代码中了,我也是改了很久并用一些注释标出加以解释,希望可以帮助你更好的理解高精度除法的相关实现及其细节问题。

2.2 代码实现

#include <bits/stdc++.h>

using namespace std;
bool cmp(vector<int>& A, vector<int>& B) //数组比较函数,目的是比较被除数和除数的大小
{
	if (A.size() != B.size()) return A.size() > B.size();
	for (int i = A.size() - 1; i >= 0; i--) {
		if (A[i] != B[i]) return A[i] > B[i];
	}
	return true;
}

vector<int> sub(vector<int>& A, vector<int>& B) //减法函数,模拟进行除法商的计算,倒序存储数字也是为了方便进行减法计算
{
	vector<int> C;
	int t = 0;
	for (int i = 0; i < A.size() || t; i++) {
		t = A[i] - t;
		if (i < B.size()) t -= B[i];
		C.push_back((t + 10) % 10);//加10起到了t小于0时可以进行进位操作
		if (t < 0) t = 1;
		else t = 0;
	}
	while (C.size() > 1 && C.back() == 0) C.pop_back();//去除前导0
	return C;
}

vector<int> div(vector<int>& A, vector<int>& B, vector<int>& r) 
{
	vector<int> C; //存储的是倒序的商数组
	//如果被除数比除数还小,那么直接返回0和被除数即可
	if (A.size() < B.size())
	{
		r = A;//一定注意余数是A不是B
		reverse(r.begin(), r.end());
		C.push_back(0);
		return C;
	}
	//注意我们的r数组此时一直处于倒序的状态
	int j = B.size();
	r.assign(max(A.begin(),A.end() - j), A.end());//有可能也会是小数除大数
	while (j <= A.size()) 
	{
		int k = 0;
		while (cmp(r, B))
		{
			vector<int> s = sub(r, B); //减法模拟除法
			r.clear();
			r.assign(s.begin(), s.end());//注意此时r数组还是倒序的
			k++;
		}
		C.push_back(k);//将商放入数组
		if (j < A.size()) 
			r.insert(r.begin(), A[A.size() - j - 1]);//再往后拿被除数一位和除数相除
		if (r.size() > 1 && r.back() == 0) 
			r.pop_back();//去除前导0,注意此时r数组还是倒序的,高位存储在末尾
		j++;
	}
	//reverse(C.begin(), C.end());
	while (C.size() > 1 && *(C.begin()) == 0) C.erase(C.begin());//去除前导0
	
	return C;
}

int main()
{
	string s1, s2;
	cin >> s1 >> s2;
	vector<int> a, b,r;//r表示余数,c表示商数组
	for (int i = s1.size()-1; i >=0; i--)//将数字逆序存入数组中
		a.push_back(s1[i] - '0');
	for (int i = s2.size()-1; i>=0; i--)
		b.push_back(s2[i] - '0');
	auto c = div(a, b, r);
	for (int i = 0; i < c.size(); i++)
		cout << c[i];
	cout << endl;
	for (int i = r.size()-1; i>=0; i--)
		cout << r[i];
	cout << endl;
	return 0;
}

3.金句省身 

       我永远喜欢那些优秀又谦逊的人,他们明明拥有吊打所有人的能力,却又毫无优越感,对人温和的就像傍晚的风,工作上坚定有主见,与人相处时又温和自谦。

      如果恰好喜欢的人也很优秀,那就狠狠的把自己变得优秀,无限去接近。别去害怕,也别去自卑,而是要尽快让你的能力跟得上你的眼光。当你足够优秀,才能散发光芒,自然有同样优秀的人追着光向你走来。

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值