C++ 高精度减法及模板

高精度减法

在数据范围超过long long 的范围时,就要考虑到高精度,对于高精度减法而言,本文介绍的两个数均 >= 0, 高精度减法的实质是用代码去模拟我们的减法运算,包括借位…正负号种种问题,这里用vector 来模拟两个大数相减,先贴代码:

#pragma GCC optimize(2)
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <sstream>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#define pm make_pair
using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
const int N = 1e4 + 50;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const double eps = 1e-8;
vector<int > A, B;

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;
	for (int i = 0, t = 0; i < a.size(); i ++)
	{
		t = a[i] - t;//当前位实质上是a[i] - t - b[i],因为要减去借位的 t 值
		if (i < b.size()) t -= b[i];
		c.push_back((t + 10) % 10);
		if (t < 0) t = 1;
		else t = 0;
	}
	while (!c.back() && c.size() > 1) c.pop_back();
	return c;
}

int main()
{
	string a, b;
	cin >> a >> b;
	for (int i = a.size() - 1; i >= 0; i --) A.push_back(a[i] ^ 48);
	for (int i = b.size() - 1; i >= 0; i --) B.push_back(b[i] ^ 48);
	if (cmp(A, B))//判两数大小
	{
		auto c = sub(A, B);
		for (int i = c.size() - 1; i >= 0; i --) cout << c[i];
		cout << endl;
	}
	else
	{
		auto c = sub(B, A);
		putchar('-');
		for (int i = c.size() - 1; i >= 0; i --) cout << c[i];
		cout << endl;
	}
	return 0;
}

模拟过程和高精度加法是类似的,具体可以移步C++ 高精度加法,这里不再具体介绍,首先,如果a >= b 则直接a - b 即可,如果a < b ,实质上就是- (b - a), 所以要视情况判断是否带符号和交换。在模拟借位时,实际上就是在下一位多减一个1,在当前位 + 10,用 t 来描述借位。假设该位两个数为a[i], b[i] 如果a[i] - b[i] >= 0, 则 t 此时应该 = 0,因为不用借位。反之,t 应该等于 1,在下一位时应该把这个 1 减掉,>=0 时,当前位的答案就是 t ,当 < 0 时,当前的答案是 a[i] - b[i] + 10,我们可以用一个表达式涵盖这两种情况:t = (t + 10) % 10,可以思考一下为什么这样写,很好理解。

原文地址:https://www.cnblogs.com/Hayasaka/p/14294148.html