高精度算法——加减

目录

1.高精度算法介绍

2.高精度加法

3.高精度减法


1.高精度算法介绍

   我们知道,每道让我们输入的题目都会现在输入数据的类型和范围

这里我们可以看到最大的范围是10^308次方,这些范围也足够大部分题目的输入,但是往往有需要上千位数字,甚至是上百万位的范围输入,这时我们就需要用到我们的高精度算法。

在高精度算法中,数据的输入要使用字符串,然后在后面将字符串的数字用一个数组存下,后面再将数组输出。

2.高精度加法

因为加法需要进位,为了方便,我们需要将字符串从后面往前用一个数组接受。

for(int i=0;i<len1;i++)
	a[len1-i]=s1[i]-'0';
	for(int i=0;i<len2;i++)
	b[len2-i]=s2[i]-'0';

上面将字符串通过这样的方式转换为数组后,就完美得将它们两的个位十位等对其了,然后它们相加的答案的位数肯定取这两位数大的再加上1。

再下面是进位操作

当数组某一位和相加后的值大于9,那么将它的十位加给数组下一位,自己取个位就行。

	c[i]+=a[i]+b[i];
		c[i+1]+=c[i]/10;
		c[i]%=10;

最后还会遇到前导0的情况,这是因为这两个数相加不能给最大位进位,所以我们要去除前导0,但是个位0不能去除。

if(c[len3]==0&&len3>0) len3--;

下面拿一道洛谷高精度题示例

P1601 A+B Problem(高精) - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

#include<stdio.h>
#include<string.h>
const int N=100010;
char s1[N],s2[N];
int a[N],b[N],c[N];
int main()
{
	scanf("%s%s",s1,s2);
	int len1=strlen(s1),len2=strlen(s2);
	for(int i=0;i<len1;i++)
	a[len1-i]=s1[i]-'0';//字符串转换为数组 
	for(int i=0;i<len2;i++)
	b[len2-i]=s2[i]-'0';
	int len3=(len1>len2?len1:len2)+1;//取长度长的一个再+1 
	for(int i=1;i<=len3;i++){
		c[i]+=a[i]+b[i];//进位 
		c[i+1]+=c[i]/10;
		c[i]%=10;
	}
	if(c[len3]==0&&len3>0) len3--;//去除前导0 
	for(int i=len3;i>=1;i--){
		printf("%d",c[i]);//从后面输出,得到答案 
	}
	return 0;
}

3.高精度减法

看懂了高精度加法,那么高精度减法就容易看懂了,与加法不同的是,减法是借位,当这一位不够减时,向上一位借10,上一位减1。

借位操作

if(a[i]<b[i])
		{
			c[i]=a[i]+10-b[i];
			a[i+1]--;
		}
		else c[i]=a[i]-b[i];

当a<b时,输出的答案有“-”所以在一开始就可以对字符串长度判断,如果长度一样就对大小判断,保证是大数减小数,区别不同就是是否在前面加一个“-”。

if(len1<len2||(len1==len2 && s1<s2))
	{
		swap(a,b);
		cout<<"-";
	}

下面一道示例题目。

P2142 高精度减法 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

直接出代码。

#include<iostream>
using namespace std;
const int N=100010;
int a[N],b[N],c[N];
int main()
{
	string s1,s2;
	cin>>s1>>s2;
	int len1=s1.length(),len2=s2.length();
	for(int i=0;i<len1;i++){
		a[len1-i]=s1[i]-'0';
	}
	for(int i=0;i<len2;i++){//字符串用数组接受 
		b[len2-i]=s2[i]-'0';
	}
	if(len1<len2||(len1==len2 && s1<s2))//保证大数减小数 
	{
		swap(a,b);
		cout<<"-";
	}
	int len3=max(len1,len2);
	for(int i=1;i<=len3;i++)
	{
		if(a[i]<b[i])//借位操作 
		{
			c[i]=a[i]+10-b[i];
			a[i+1]--;
		}
		else c[i]=a[i]-b[i];
	}
	while(c[len3]==0 && len3>1)//去除前导0 
		len3--;
	for(int i=len3;i>=1;i--)
		cout<<c[i];
	return 0;
}

先到这里,高精度乘法和除法后续发。

  • 14
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值