高精度(加法 减法 乘法 除法)

目录

一、高精度加法

1. 算法原理

2.应用

二、高精度减法

三、高精度乘法

四、高精度除法


一、高精度加法

1. 算法原理

  1. 当输入的数很大时,可采用字符串方式接收。

  2. 拆成一位一位的数字,把它们存在一个数组中,一个数组元素表示一位数字。

数组中是这样存储的:

倒序存储原因

这是因为加法可能会产生进位,而数组在最前面加上数字是不可能的,但在尾巴处加上数字是好做的,所以倒着放。

2.应用

(输入为正整数)

#include<iostream>
#include<vector>

using namespace std;

class Hp_Add
{
public:
	void hp_add()
	{
		string a, b;
		cin >> a >> b;
		vector<int> A, B;

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

		auto C = add_(A, B);

		cout << "sum:>";
		for (int i = C.size() - 1; i >= 0; --i) cout << C[i];
	}
private:
	vector<int> add_(vector<int>& A, vector<int>& B)
	{
		vector<int> C;
		int t = 0;
		for (int i = 0; i < A.size() || i < B.size(); ++i)
		{
			if (i < A.size()) t += A[i];
			if (i < B.size()) t += B[i];
			C.push_back(t % 10);
			t /= 10;
		}
		if (t) C.push_back(1);
		return C;
	}
};

二、高精度减法

(输入为正整数)

 减法需要解决两数大小所导致的正负号的问题。

#include<iostream>
#include<vector>

using namespace std;

class Hp_Sub
{
public:
	void hp_sub()
	{
		string a, b;
		vector<int> A, B;
		cin >> a >> b;

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

	    // 去除前置的0	
		while (A.size() > 1 && A.back() == 0) A.pop_back();
		while (B.size() > 1 && B.back() == 0) B.pop_back();

		if (sign(A, B))
		{
			auto C = _sub(A, B);
			for (int i = C.size() - 1; i >= 0; i--)   cout << C[i];
		}
		else
		{
			auto C = _sub(B, A);
			cout << '-';
			for (int i = C.size() - 1; i >= 0; i--) cout << C[i];
		}
	}
private:
	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;
			if (i < B.size()) t -= B[i];
			C.push_back((t + 10) % 10);
			if (t < 0) t = 1;
			else t = 0;
		}
		while (C.size() > 1 && C.back() == 0) C.pop_back();
		return C;
	}
    
    // 判断大小
	bool sign(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;
	}
};

三、高精度乘法

相比于加法与减法,乘法需要注意进位问题(进位数超过原数的最大位数),要将遍历条件修改为 i < A.size() || t 。

#include<iostream>
#include<vector>

using namespace std;

class Hp_Mul
{
public:
	void hp_mul()
	{
		int b;
		string a;
		cin >> a >> b;
		vector<int> A;
		for (int i = a.size() - 1; i >= 0; --i) A.push_back(a[i] - '0');
		auto C = _mul(A, b);

        // 去除前置的0
		while (A.size() > 1 && A.back() == 0) A.pop_back();

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

private:
	vector<int> _mul(vector<int>& A, int b)
	{
		vector<int> C;
        // 注意当t不为0时,不结束循环
		for (int i = 0, t = 0; i < A.size() || t; ++i)
		{
			if (i < A.size()) t += A[i] * b;
			C.push_back(t % 10);
			t /= 10;
		}
		return C;
	}
};

四、高精度除法

引用了 reverse() 函数【采用头文件algorithm】来对储存商的vector进行逆置,从而解决前置 0 的问题。

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

class Hp_Div
{
public:
	void hp_div()
	{
		string a;
		int b, c = 0;
		vector<int> A;
		cin >> a >> b;

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

		while (a.size() > 1 && a.back() == 0) a.pop_back();

		auto C = _div(A, b, c);
		for (int i = C.size() - 1; i >= 0; --i) cout << C[i];

        // 返回余数
		if (c) cout << "……" << c << endl;
	}
private:
	vector<int> _div(vector<int>& A, int b, int& c)
	{
		vector<int> C;
		int r = 0;
		for (int i = A.size() - 1; i >= 0; --i)
		{
			r = r * 10 + A[i];
			C.push_back(r / b);
			r %= b;
		}

		// 去除商的前置0
		reverse(C.begin(), C.end());
		while (C.size() > 1 && C.back() == 0) C.pop_back();

		c = r;
		return C;
	}
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值