高精度算法 --- 加法、减法、乘法和除法(C ++ 代码模板)

一、高精度算法(下文分别给出模板)

原理:

当一个数很大时,大到普通的 int 存不下时,可以考虑用数组来存储,即数组中一个位置存放一位。
但是对于数组而言,一个数顺序存入数组后,对其相加减是很简单的。但是当要进位时,是相当麻烦的。因为要将整个数组全都往后移动一位,将最高位的进位位置空出来,这个操作是 O(n) 的。
有一种方法可以很好的解决进位的问题。就是将这个数的个位数存至数组中的第一位(即 a[0]),最高位存入数组的最后一位(a[n - 1])。这样在处理进位时可以直接在数组的最后一位添加即可。在输出时倒序输出即可。

二、高精度加法

根据以上原理,我们可以很简单就模拟出具体实现方式。
举个例子:求 9724 + 377 后的值。
将两个数分别存入 a 数组和 b 数组中,如下图:
在这里插入图片描述
运算的话就很简单了。将第一个位置相加,如果大于 9 就要进一位(这一步可以利用取模来实现)。再将第二个位置的数相加,同时加上前一位的进位,再观察是否大于 9 。以此类推便可求出最终答案。
在这里插入图片描述

高精度加法代码模板

// 利用c ++ 中的 vector 来存放数。
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 = t + a[i];
		if(i < b.size()) t = t + b[i];
		
		c.push_back(t / 10);
		t = t % 10;
	}

	if(t) c.push_back(t);
	
	return c;
}

三 、高精度减法

减法与加法类似,区别的话具体有两点

  1. 在于是大的数减小的数还是小的数减大的数,这两种情况的共同点在于他们相减后的绝对值是相等的,所以在运算前判断数的大小即可。
  2. 又可能两个数相等或者高位数值相等,那么在相减的过程中会产生 0 ,并且这个 0 是在高位的,在输出时会输出 0 ,那么得要去除这个 0 。若是要求出产生 0 的位置,这个步骤是相对繁琐的。这个时候用数组倒序存数的又一大优势来了,可以直接利用 pop_back() 去除最后的元素(即最高位的元素)。

高精度减法代码模板

// 判断两个数的大小
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(); i ++ )
	{
		t = a[i] - t;
		if(i < b.size()) t = t - b[i];
		c.push_back(t / 10);
		if(t < 0) t = 1;
		else t = 0;
	}

	// 去除高位 0 
	while(c.size() > 1 && c.back() == 0) c.pop_back();
	return c;
}

四、高精度乘法

由于高精度乘于高精度应用不多,这里只给出高精度乘与低精度。
高精度乘法与高精度加法基本类似,下文直接给出模板。

高精度乘法代码模板

vector<int> mul(vector<int> a, int b)
{
	vector<int> c;
	int t = 0;

	for(int i = 0; i < a.size(); i ++ )
	{
		t = t + a[i] * b;
		c.push_back(t % 10);
		t = t / 10;
	}
	
	if(t) c.push_back(t);

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

	return c;
}

五、高精度除法

这里的情况同样是高精度与低精度,用高精度除以低精度。

高精度除法代码模板

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 = r * 10 + a[i];
        c.push_back(r / b);
        r %= b;
    }
    
    reverse(c.begin(), c.end());
    while (c.size() > 1 && c.back() == 0) c.pop_back();
    
    return c;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

辣辣溜溜梅

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

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

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

打赏作者

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

抵扣说明:

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

余额充值