高精度加减乘除C/C++实现 + python实现

[高精度加法]例题 一、P601洛谷:A+B Problem(高精)

P601洛谷
A+B Problem(高精)
题目背景

题目描述
高精度加法,x相当于a+b problem,b不用考虑负数。

输入输出格式
输入格式:
分两行输入a,b<=10^500

输出格式:
输出只有一行,代表A+B的值

输入输出样例
输入样例#1:

1
1

输出样例#1

1

1.C/C++模板1[详细版]

#include<bits/stdc++.h>
using namespace std;
int a[501],b[501];//长度是位数 
void add(string s1,string s2)
{
    int i,j,len1,len2;
    char s[501];
	memset(a,0,sizeof(a));
	memset(b,0,sizeof(b));
	len1=s1.length();
	len2=s2.length();
	//把两个字符串转换成整数
	for(i=len1-1;i>=0;i--)
	a[i]=s1[len1-1-i]-'0';//s1=123,a=321 
	for(i=len2-1;i>=0;i--)
	b[i]=s2[len2-1-i]-'0';//s2=12 , b=21
	//       s1+s2=123+12=135     ,a+b=321+21=531 取个反就对了
	int c=0;//进位
	j=0;
	while(j<=max(len1,len2))//运算到0-max(len1,len2)位max(len1,len2)位可能是0 
	{
		a[j]=a[j]+b[j]+c;
		if(a[j]>=10)//进位 
		{
			a[j]-=10;
			c=1;
		}
		else//否则不进位 
		c=0;
		j++;
	}
	int k=max(len1,len2);
	while(a[k]==0&&k>=1)//k>=1一定要加啊 
	k--;//去掉后面的0 即max位如果是0 则去掉
	for(j=k;j>=0;j--)
	s[j]=a[k-j]+'0';
	s[k+1]='\0';printf("%s\n",s);
	//for(i=0;i<=k;i++)
	//printf("%c",s[i]); 
//	printf("\n");
	return;
}
int main(void)
{
	string s1,s2;
	while(cin>>s1>>s2)
	add(s1,s2);
	return 0;
}

2.python(三行代码)

python:
由于python的int是无长度限制的数据类型,理论上是无限长。所以python的高精度对于c++/c语言来说就像玩的一样。
AC代码:

a = input()
b = input()
print(int(a) + int(b))

不过时间复杂度上,C++/C更快
在这里插入图片描述

[高精度加法]例题二、蓝桥杯基础练习 高精度加法

资源限制
时间限制:1.0s 内存限制:512.0MB
问题描述
  输入两个整数a和b,输出这两个整数的和。a和b都不超过100位。
算法描述
  由于a和b都比较大,所以不能直接使用语言中的标准数据类型来存储。对于这种问题,一般使用数组来处理。
  定义一个数组A,A[0]用于存储a的个位,A[1]用于存储a的十位,依此类推。同样可以用一个数组B来存储b。
  计算c = a + b的时候,首先将A[0]与B[0]相加,如果有进位产生,则把进位(即和的十位数)存入r,把和的个位数存入C[0],即C[0]等于(A[0]+B[0])%10。然后计算A[1]与B[1]相加,这时还应将低位进上来的值r也加起来,即C[1]应该是A[1]、B[1]和r三个数的和.如果又有进位产生,则仍可将新的进位存入到r中,和的个位存到C[1]中。依此类推,即可求出C的所有位。
  最后将C输出即可。
输入格式
  输入包括两行,第一行为一个非负整数a,第二行为一个非负整数b。两个整数都不超过100位,两数的最高位都不是0。
输出格式
  输出一行,表示a + b的值。
样例输入:

20100122201001221234567890
2010012220100122

样例输出:

20100122203011233454668012

C/C++模板2[精简版]

上面的模板1其实就是初学的时候模范别人打的有点乱,但是原理清楚,建议用这个作为参考。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
char a[105];char b[105];int sum[150];
void solve()
{
	int c=0;
	int lena=strlen(a);int lenb=strlen(b);
	int k=max(lena,lenb);
	//翻转:位数对齐(列竖式)
	/*for(int i=0;i<lena/2;i++) swap(a[i],a[lena-i-1]);
	for(int i=0;i<lenb/2;i++) swap(b[i],b[lenb-i-1]);*///和下面一行等价 
	reverse(a,a+lena);reverse(b,b+lenb);
	int j=0;
	while(j<k||c!=0)
	{
		int na=0,nb=0;
		if(j<lena) na=a[j]-'0';
		if(j<lenb) nb=b[j]-'0';
		sum[j]=(na+nb)+c;
		c=sum[j]/10;
		sum[j]%=10;
		j++;
	}
	while(sum[k]==0&&k>0) k--;
	for(int i=k;i>=0;i--)
	printf("%d",sum[i]);
	printf("\n");
	return;
}
int main(void)
{
	scanf("%s",a);
	scanf("%s",b);
	solve();
	return 0;
} 

[高精度减法]模板(C++)

洛谷P2142

#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
using namespace std;
bool compare(string a,string b)
{
	if(a.size()>b.size()) return true;
	if(a.size()<b.size()) return false;
	if(a>=b)//长度相等才比 
	return true;
	return false;
}
void subtraction(string a,string b)
{
	int len=a.size();
	int sa[20005],sb[20005];
	for(int i=0;i<len;i++)	sa[i]=a[len-i-1]-'0';
	for(int i=0;i<len;i++) sb[i]=0;
	len=b.size();
	for(int i=0;i<len;i++)	sb[i]=b[len-i-1]-'0';
	len=a.size();
	int c[20005];
	int z=0;
	for(int i=0;i<len;i++){
		z=sa[i]-sb[i];
		if(z<0)
		{
			int j=i+1;
			while(sa[j]-1<0&&j<len)
			{
				sa[j]=9;
				j++;
			}
			sa[j]-=1;
			if(sa[j]==0&&j==len-1) len--;
			z+=10;
		}
		
		c[i]=z;
	}
	int k=len-1;
	while(k>0&&c[k]==0) k--;
	for(int i=k;i>=0;i--)
	printf("%d",c[i]);
	printf("\n");
	return;
}
int main(void)
{
	string a,b;
	cin>>a;
	cin>>b;
	if(!compare(a,b)){
		swap(a,b);
		printf("-");
	}
	subtraction(a,b);
	return 0;
}

或许题解中的另一个方法更简单,但是上面代码更符合我们日常习惯吧。
在这里插入图片描述

[高精度乘法]模板C++

poj2389

#include<iostream>
#include<cstdio>
#include<string>
using namespace std;
bool compare(string a,string b)
{
	if(a.size()>b.size())
	return true;
	return false;
}
int a[85],b[85],w[85];
void solve(string sa,string sb)
{
	int lena=sa.size(),lenb=sb.size();
	for(int i=0;i<lena;i++) a[i]=sa[lena-i-1]-'0';
	for(int i=0;i<lenb;i++) b[i]=sb[lenb-i-1]-'0';
	int c=0,z=0;
	for(int i=0;i<lenb;i++){
		for(int j=0;j<lena;j++){
			z=b[i]*a[j]+c;
			c=z/10;
			w[j+i]+=z%10;
			//注意加法进位
			if(w[j+i]>=10)
			{
				c+=w[j+i]/10;
				w[j+i]%=10;
			}
		}
		if(c)
		{
			w[lena+i]+=c;
			c=0;
		}
	}
	int k=84;
	while(k>0&&w[k]==0) k--;
	for(int i=k;i>=0;i--) printf("%d",w[i]);
	puts("");
	return;
}
int main(void)
{
	string a,b;
	cin>>a;
	cin>>b;
	if(!compare(a,b))
	swap(a,b);
	solve(a,b);
	return 0;
}

高精度除法

在这里插入图片描述
高精度除法要用到高精度减法,其中减法用于试商,而不是用高精度乘法。

高精度除法还没打,就用了一下其他博主的代码块,理清楚思路,相信能自己敲出来

步骤如下:

1、将除数和被除数对齐,被除数位数不够时,补0。

2、利用被除数减去除数,一直减到被除数小于除数,减的次数,就是“试商”的结果,每减一次当前位结果就加一个。

3、重复上述步骤,一直到被除数和除数的位数相等为止(求得余数)或者达到某一精度要求。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值