高精度算法

基本思想——小学的竖式运算

决定了加,减,乘从低位运算到高位

除从高位到低位

一,高精度加法

#include <bits/stdc++.h>
using namespace std;
#define ll     long long
const int INF = 0x3f3f3f3f;
const int N = 2e5 + 100;

vector<int> addi(vector<int>&A, vector<int>&B)//使用&,可以直接引用,不然需要先复制才能用,如果这个容器太大,使用该函数次数过多,会被TLE,另一个意思,引用会修改原来的,没引用只是对形参操作
{
	vector<int>C;
	int t = 0;//用于进位
	for (int i = 0; i < (int)A.size() || i < (int)B.size(); ++i)//i < (int)A.size() || i < (int)B.size()只要还有一个数的位还有,就进入
		{
			if (i < (int)A.size())t += A[i];//你有数,我就加
			if (i < (int)B.size())t += B[i];
			C.push_back(t % 10);
			t /= 10;
		}
	if (t)C.push_back(t);//这里标志是否进位,有则存入
	return C;
}

int main()
{
	string a, b;
	cin >> a >> b;
	vector<int>A, B;
	for (int i = (int)a.size() - 1; i >= 0; --i)A.push_back(a[i] - '0');//倒位存储
	for (int i = (int)b.size() - 1; i >= 0; --i)B.push_back(b[i] - '0');
	auto C = addi(A, B);//auto自动识别类型,避免写麻烦的容器类型
	for (int i = (int)C.size() - 1; i >= 0; --i)cout << C[i];
	return 0;
}

二,高精度减法

#include <bits/stdc++.h>
using namespace std;
#define ll     long long
const int INF = 0x3f3f3f3f;
const int N = 2e5 + 100;

bool cmp(vector<int>&A, vector<int>&B)//比较A,B大小
{
	if ((int)A.size() != (int)B.size())return (int)A.size() > (int)B.size();
	else
		{
			for (int i = (int)A.size() - 1; i >= 0; --i)
				{
					if (A[i] != B[i])return A[i] > B[i];//比较这一位的a,b
				}
			return 1;//注意,可能A,B相等,所以出来还要补这个
		}
}

vector<int> sub(vector<int>&A, vector<int>&B)
{
	vector<int>C;
	int t = 0;//用于借位
	for (int i = 0; i < (int)A.size(); ++i)
		{
			t = A[i] - t;//如果前面借位了,t是1,
			if (i < (int)B.size())t -= B[i];//只要B还有位,减他
			C.push_back((t + 10) % 10);//t+10是因为可能t不够减B[i],需要借位,给你个10保证
			if (t < 0)t = 1;//t小于0,说明借位,赋值1,后面被减
			else t = 0;
		}
	while ((int)C.size() > 1 && C.back() == 0)C.pop_back();//除去前导0

	return C;
}

int main()
{
	string a, b;
	cin >> a >> b;
	vector<int>A, B;
	for (int i = (int)a.size() - 1; i >= 0; --i)A.push_back(a[i] - '0');
	for (int i = (int)b.size() - 1; i >= 0; --i)B.push_back(b[i] - '0');

	if (cmp(A, B))//我们保证一定是大的减去小的,返回真,那么A>=B
		{
			auto C = sub(A, B);
			for (int i = (int)C.size() - 1; i >= 0; --i)cout << C[i];
		}
	else
		{
			auto C = sub(B, A);
			cout << "-";//目标是A-B,但是为了方便,我们算法让他大数减小数,所以要补负号
			for (int i = (int)C.size() - 1; i >= 0; --i)cout << C[i];
		}
	return 0;
}

三,高精度乘法(高精*低精)

#include <bits/stdc++.h>
using namespace std;
#define ll     long long
const int INF = 0x3f3f3f3f;
const int N = 2e5 + 100;

vector<int> mul(vector<int>&A, ll b)
{
	vector<int>C;
	int t = 0;//每一位*b可能是好几位,所以t每次使用一位,/10,然后后面继续使用,也就是不能再以A的长度为结束为结束标志,只有同时t=0才可以结束
	for (int i = 0; i < (int)A.size() || t; ++i)
	{
		if (i < (int)A.size()) t += A[i] * b;//所以这里t是+=,不再是=     //+=A[i]*b,不要忘了*b
		C.push_back(t % 10);//要加之前不忘这一句if (i < (int)A.size()),A没有是不能加的
		t /= 10;
	}
	while (C.size() > 1 && !C.back())C.pop_back();//防止*0出现全0
	return C;
}

int main()
{
	string a;
	ll b;
	cin >> a >> b;
	vector<int>A;
	for (int i = (int)a.size() - 1; i >= 0; --i)A.push_back(a[i] - '0');
	auto C = mul(A, b);
	for (int i = (int)C.size() - 1; i >= 0; --i)cout << C[i];
	return 0;
}

四,高精度除法

#include <bits/stdc++.h>
using namespace std;
#define ll     long long
const int INF = 0x3f3f3f3f;
const int N = 2e5 + 100;

vector<int> div(vector<int>&A, ll b, ll&r) //原函数r,函数&r,这是c++引用的一种,与指针很像
{
	r = 0;
	vector<int>C;
	for (int i = (int)A.size() - 1; i >= 0; --i)
		{
			r = r * 10 + A[i];//r是余数,所以每次到下一位要先乘10再用
			C.push_back(r / b);//竖式除
			r %= b;//竖式取余
		}
	reverse(C.begin(), C.end());//因为我们是从高位正序存储到C中,所以用reverse全部逆序
	while ((int)C.size() > 1 && !C.back())C.pop_back();//去前导0
	return C;
}

int main()
{
	string a;
	ll b, r;
	cin >> a >> b;
	vector<int>A;
	for (int i = (int)a.size() - 1; i >= 0; --i)A.push_back(a[i] - '0');
	auto C = div(A, b, r); //r是余数,因为你可能最后除完还有剩
	for (int i = (int)C.size() - 1; i >= 0; --i)cout << C[i];
	cout << endl << r << endl;
	return 0;
}

五,高精*高精

#include <bits/stdc++.h>
using namespace std;
#define ll     long long
const int INF = 0x3f3f3f3f;
const int N = 2e5;
int C[N];//这里使用数组更容易操作
ll  mul(vector<int>&A, vector<int>&B)
{
	for (int i = 0; i < (int)A.size(); ++i)//遍历i,j
		{
			for (int j = 0; j < (int)B.size(); ++j)
				{
					C[i + j] += A[i] * B[j];//C是i+j位
				}
		}
	for (int i = 0; i < (int)A.size() + (int)B.size(); ++i)
		{
			if (C[i] > 9)C[i + 1] += C[i] / 10;//累积后再单独对C操作
			C[i] = C[i] % 10;
		}
	int len = (int)A.size() + (int)B.size();
	while (!C[len - 1] && len > 1)len--;//除去前导0
	return len;
}

int main()
{
	string a, b;
	vector<int>A, B;
	cin >> a >> b;
	for (int i = (int)a.size() - 1; i >= 0; --i)A.push_back(a[i] - '0');
	for (int i = (int)b.size() - 1; i >= 0; --i)B.push_back(b[i] - '0');
	ll len = mul(A, B);
	for (ll i = len - 1; i >= 0; --i)cout << C[i];

	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值