高精度算法

当运算数据超过int,long long的范围时,我们就需要运用高精度算法来计算。其基本思想我总结为,将输入的数据以字符的形式存入,对两组数据同位数字进行运算,找到各位之间的关系,以此来进行大数的加减乘除。

高精度加法

#include <bits/stdc++.h>
using namespace std;

long long s1[505];
long long s2[505];
long long s3[505];                //用于输出最终答案

int main() {
	string str1, str2;
	cin >> str1 >> str2;
	int l1 = str1.size();
	int l2 = str2.size();

	for (int i = 0; i < l1; i++)            //将数据反向存入,依次从小位到大位的进制
		s1[l1 - i] = str1[i] - '0';
	for (int i = 0; i < l2; i++)
		s2[l2 - i] = str2[i] - '0';

	int l3 = max(l1, l2) + 1;                //两数相加可能会往后进一位,因此需要长度加一
	for (int i = 1; i <= l3; i++) {          //这一部分是算法的主体,这里的思想就是小学时将两                            
                                               个数叠在一起的计算思路
		s3[i] = s3[i] + s1[i] + s2[i];
		s3[i + 1] = s3[i] / 10;
		s3[i] = s3[i] % 10;

	}
	if (s3[l3] == 0 && l3 > 1)                //这里判断两个数字相加之后最高位是否改变
		l3--;
	for (int i = l3; i > 0; i--) {
		cout << s3[i];
	}
	return 0;
}

高精度减法

高精度加法的主要思路与加法相同,但在一开始减数与被减数的选择上有所侧重,这与不同高精度减法方法不同有很大的关系,我这里是将输入的两个数进行比较,将大的数放在前面。

#include <bits/stdc++.h>
using namespace std;

long long s1[10100] = {0};

long long s2[10100] = {0};

long long s3[10100] = {0};

int main() {
	string str1, str2;
	cin >> str1 >> str2;
	int l1 = str1.size();
	int l2 = str2.size();

	for (int i = 0; i < l1; i++)
		s1[l1 - i] = str1[i] - '0';
	for (int i = 0; i < l2; i++)
		s2[l2 - i] = str2[i] - '0';

	int p;                                        //p=1和p=0来表示两个数谁大谁小
	if (l1 < l2)
		p = 0;
	else {
		if (l1 > l2)
			p = 1;
		else {
			for (int i = l1; i >= 0; i--) {    //从高位往低位依次比较数字大小来判断
				if (s1[i] > s2[i]) {
					p = 1;
					break;
				} else if (s1[i] < s2[i]) {
					p = 0;
					break;
				} else if (i == 0 && s1[i] == s2[i]) {
					p = 1;
				}
			}
		}
	}

	int l3 = max(l1, l2) ;                        //由于两个数相减不会出现进位的情况,因此    
                                                    不用加一
	int k;
	for (int i = 1; i <= l3; i++) {
		if (p == 1) {        
			if (s1[i] < s2[i]) {
				s1[i + 1]--;
				s1[i] += 10;
			}
			s3[i] = s1[i] - s2[i];
		} else {
			if (s1[i] > s2[i]) {
				s2[i + 1]--;
				s2[i] += 10;
			}
			s3[i] = s2[i] - s1[i];
		}
	}
	while (s3[l3] == 0 && l3 > 1)                //两个数高位相减可能会刚好减完,需要判断
		l3--;
	for (int i = l3; i > 0; i--) {
		if (p == 0) {
			if (i == l3) {
				cout << '-' << s3[i];
			} else
				cout << s3[i];
		} else {
			cout << s3[i];
		}

	}
	return 0;
}

高精度乘法

首先我们先来用小学生的方法计算两个数的相乘,通过观察我们不难发现,C的下标=a的下标+b的下标+1,因此整体算法与加法相似。

#include <bits/stdc++.h>
using namespace std;

long long s1[1000000];
long long s2[1000000];
long long s3[1000000];

int main() {
	string str1, str2;
	cin >> str1 >> str2;
	int l1 = str1.size();
	int l2 = str2.size();

	for (int i = 0; i < l1; i++)
		s1[l1 - i] = str1[i] - '0';
	for (int i = 0; i < l2; i++)
		s2[l2 - i] = str2[i] - '0';

	int l3 = l1 + l2;                       //前面我们已经知道c=a+b+1
	
	for (int i = 1; i <= l1; i++) {
		for (int j = 1; j <= l2; j++) {
			s3[i + j - 1] = s3[i + j - 1] + s1[i] * s2[j];
			s3[i + j] += s3[i + j - 1] / 10;        //注意这里是+=,具体为什么自己推一推吧,                
			s3[i + j - 1] = s3[i + j - 1] % 10;     //毕竟是小学二年级的内容哈
		}
	}
	if (s3[l3] == 0 && l3 > 0)                      //注意这里的条件是l3>0,而不是l3>1;
		l3--;
	for (int i = l3; i > 0; i--) {
		cout << s3[i];
	}
	return 0;
}

 

高进度除法

高进度除法分为高精度除以低精度高精度除以高精度两种情况

高精度除以低精度

运用小学所学的逐位试商法,是个求商和求余的过程

#include <bits/stdc++.h>
using namespace std;

long long s1[1000000];

long long s3[1000000];

int main() {
	string str1;
	long long b;
	long long x = 0;
	cin >> str1 >> b;
	int l1 = str1.size();
	for (int i = 1; i <= l1; i++) {        //由于是除法,所以不需要倒着输入
		s1[i] = str1[i - 1] - '0';
	}

	for (int i = 1; i <= l1; i++) {
		s3[i] = (x * 10 + s1[i]) / b;
		x = (x * 10 + s1[i]) % b;
	}
	long long l3 = 1;
	while (s3[l3] == 0 && l3 < l1) {       //删除前面的所有0;
		l3++;
	}
	for (int i = l3; i <= l1; i++) {        //注意这里i的范围
		cout << s3[i];
	}
	return 0;
}

高精度除以高精度

由于除数和被除数都是很大的数,显然无法通过long long来存储了,那么这里又需要用到一种新的方法——减法模拟除法

家人们看懂了吗,ok,接下来就是算法了

额,这个我现在好像也不太会,过几天再来写吧

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值