高精度加减乘

当我们要计算的数字比系统可以存储的最大数字还要大的时候,我们就需要使用高精度算法,也就是通过一个数组,来代替运算的过程,其中,高精度加法和高精度乘法密切相关,高精度减法和高精度除法密切相关。但是高精度除法我们不做要求。

高精度加法

主要看注释:

#include <iostream>
#include <algorithm>

using namespace std;

char a[200];
char b[200];//用来存放我要计算的数字的数组
int a1[200];
int b1[200];//用来倒叙的数组,当我们要进位的时候,如果我们按照正常的顺序的话,进位每一个数字就都要往后面移动,时间复杂度太高,所以我们选择使用倒叙,这样进位就很方便了。
int sum[201];//用来计算的数组
char out_sum[201];//把倒叙的再正过来
int main()
{
	scanf("%s", a);
	scanf("%s", b);
	int len_a = strlen(a);
	int len_b = strlen(b);
    //len就是我的加法要进行的位数
	int len = len_a > len_b ? len_a : len_b;
    //倒叙过程
	for (int i = 0; i < len_a; i++)
	{
		a1[len - i - 1] = a[i] - '0';
	}
	for (int j = 0; j < len_b; j++)
	{
		b1[len - j - 1] = b[j] - '0';
	}
    //d是用来保存进位信息的
	int d = 0;
	for (int i = 0; i < len; i++)
	{
        //当有进位信息了之后,sum就是这么计算的
		sum[i] = a1[i] + b1[i] + d;
		if (sum[i] > 10)
		{
			d = sum[i] / 10;
			sum[i] %= 10;
		}
		else
		{
			d = 0;
		}
	}
    //如果都算完了,结果还存在进位信息,那么说明我的长度要进1了
	if (d > 0)
	{
		sum[len] += d;
		len++;
	}
    //放到输出数组里面取
	for (int i = 0; i < len; i++)
	{
		out_sum[i] = sum[len - 1 - i] + '0';//这里要注意要补'0'
	}
	for (int i = 0; i < len; i++)
	{
		printf("%c", out_sum[i]);
	}
	return 0;
}

高精度乘法

高精度乘法和高精度加法几乎一样,看图:

在这里插入图片描述

可以发现第i位和第j位的运算结果存放在i + j位中。存放完了之后再使用大数加法原则即可。

#include <iostream>
#include <algorithm>

using namespace std;
char a[200];
char b[200];
int a1[200];
int b1[200];
int pows[400];
char out_pow[400];
int main()
{
	scanf("%s", a);
	scanf("%s", b);
	int len_a = strlen(a);
	int len_b = strlen(b);
	int len = len_a + len_b - 1;
	for (int i = 0; i < len_a; i++)
	{
		a1[len_a - i - 1] = a[i] - '0';
	}
	for (int i = 0; i < len_b; i++)
	{
		b1[len_b - i - 1] = b[i] - '0';
	}
	for (int i = 0; i < len_a; i++)
	{
		for (int j = 0; j < len_b; j++)
		{
			pows[i + j] += a1[i] * b1[j];
		}
	}
	int d = 0;
		for (int i = 0; i < len; i++)
		{
			pows[i] += d;
				if (pows[i] > 0)
				{
					d = pows[i] / 10;
					pows[i] %= 10;
				}
				else
				{
					d = 0;
				}
		}
	if (d > 0)
	{
		pows[len] += d;
		len++;
	}
	for (int i = 0; i < len; i++)
	{
		out_pow[i] = pows[len - i - 1] + '0';
	}
	for (int i = 0; i < len; i++)
	{
		printf("%c", out_pow[i]);
	}
	return 0;
}

看看代码就行了,很好懂。

高精度减法

#include <iostream>
#include <algorithm>
#include <string.h>

using namespace std;
char a[200];
char b[200];
int a1[200];
int b1[200];
int sub[200];
char sub_out[200];
int main()
{
	scanf("%s", a);
	scanf("%s", b);
	int len_a = strlen(a);
	int len_b = strlen(b);
	bool flag = 0;
	//先判断哪个数字要大一些,我们默认让a里面的数字是大于b里面的数字的
	if (len_a < len_b)//这样a必定比bu要小
	{
		char temp[200];
		strcpy(temp, a);
		strcpy(a, b);
		strcpy(b, temp);
		flag = 1;
	}
	else if (len_a == len_b)
	{
		for (int i = 0; i < len_a; i++)
		{
			if (a[i] < b[i])
			{
				char temp[200];
				strcpy(temp, a);
				strcpy(a, b);
				strcpy(b, temp);
				flag = 1;
				break;
			}
			else if (a[i] > b[i])
			{
				break;//这个时候a一定要比b大
			}
		}
	}
	//走到这里为止,我们得到了a里面是大的数字
	//开始倒叙,不然可能会发生,第一位为0的情况
	for (int i = 0; i < len_a; i++)
	{
		a1[len_a - i - 1] = a[i] - '0';
	}
	for (int i = 0; i < len_b; i++)
	{
		b1[len_b - i - 1] = b[i] - '0';
	}
	int d = 0;//进位信息
	int len = len_a;
	for (int i = 0; i < len; i++)
	{
		sub[i] = a1[i] - b1[i] + d;
		if (sub[i] < 0)
		{
			sub[i] += 10;
			d = -1;
		}
		else
		{
			d = 0;
		}
	}
	if (sub[len - 1] == 0)//如果最高位是0的话,那么我们就直接len--
	{
		len--;
	}
	for (int i = 0; i < len; i++)
	{
		sub_out[i] = sub[len - i - 1] + '0';
	}
	if (flag)
	{
		printf("-");
	}
	for (int i = 0; i < len; i++)
	{
		printf("%c", sub_out[i]);
	}
	return 0;
}

高精度除法(高精除低精度)

模拟小学除法

代码如下:

#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

int main()
{
	string a;
	long long b;
	cin >> a >> b;
	long long c = 0;
	long long s = 0;
	long long f = 0;
	for(int i = 0; i < a.size(); i++)
	{
		s = a[i] - '0';//把字符转换成数字
		c = c * 10 + s;
		f = c / b;
		c = c % b;
		cout << f;
	}
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

胡桃姓胡,蝴蝶也姓胡

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

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

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

打赏作者

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

抵扣说明:

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

余额充值