c++高精度(精讲)

文章详细介绍了如何使用C++中的string类型解决大整数的加法、减法、乘法和除法问题,包括模拟行列式、进位处理、前导零去除等步骤,通过实例展示了这些操作的实现过程。
摘要由CSDN通过智能技术生成

目录

整数加法

整数减法

整数除法

整数乘法

整数加法

我们都知道long long是C里面的最大整数类型

那如果遇到222222222222222222222222222+3333333333333333333333333333333333333333呢???

我们可以用string类型来解决。spearboy:尊都假都

尊都

教学开始

照旧定义好 a, b, c(int类型)

这里spearboy建议用子程序

因为前面讲过我们用string类型来解决,所以这里的子程序使用string类型.(名字叫Add)

在这里定义string类型as和bs

由于可能会遇到多组数据所以我们在子程序的开头需要memset(a,0,sizeof(a)); memset(b,0,sizeof(b));memset(c,0,sizeof(c));//很长😑

接下来我们用int al和bl获取as和bs的长度(int al=as.size();int bl=bs.size();)注意还要定义cl获取al和bl中最大的那个值加一(max函数)

for循环每次将as[al-i]-"0"放入a[i];

bl也是同样的

接下来就到最难的一步了模拟行列式

注意

最难的还是在这一步模拟行列式,我们要思考怎么让这个进位能给他进到后面一位     spearboy:好难啊!😣      没事以后就简单了如果觉得太难的话可以看下面这一段代码。

    for(int i=1;i<=cl;i++){//遍历cl
        c[i]+=a[i]+b[i];//可可爱爱简简单单的加法
        c[i+1]+=c[i]/10;//这一步呢我们要让后面的CI加一加上我们这一步的余数也就是进位了
        c[i]%=10;//抹去一位
    }

注意

题目可能会说去除多余的前导零那么也就是说我们这里需要多一个去除前导零的步骤。

spearboy:前导零是什么😵‍💫

简单说一下前导零就是在一个正常的数字前面有一些零例如04328就是有前导零的数字这一步就是要把前面的这个零给他删除掉     是不是很简单😃

好了扯远了我们现在讲回来这一步去除前导零吧😃

由于我们的c是int类型所以说我们这里可以直接判断c[cl]==0

注意

这里不只是一个判断  还要判断cl>1

cl--;

最后我们每一次将这个得到的数存入string类型的cs里面最后return cs

子程序就好了                                                spearboy:欧耶😃😃😃😃😃😃😃😃

我们来做一道题检测一下究竟会不会😃

 大整数加法

题目描述

求两个不超过200位的非负整数的和

输入格式

有两行,每行是一个不超过200位的非负整数,可能有多余的前导0。

输出格式

一行,即相加后的结果。结果里不能有多余的前导0,即如果结果是342,那么就不能输出为0342。

输入输出样例

输入样例1:    

22222222222222222222             

33333333333333333333

输出样例1:

55555555555555555555

#include<bits/stdc++.h>
using namespace std;
int a[210],b[210],c[210];
string Add(string as,string bs){
	memset(a,0,sizeof(a));
	memset(b,0,sizeof(b));
	memset(c,0,sizeof(c));
	int al=as.size();int bl=bs.size();
	int cl=max(al,bl)+1;
	for(int i=1;i<=al;i++){
		a[i]=as[al-i]-'0';
	}
	for(int i=1;i<=bl;i++){
		b[i]=bs[bl-i]-'0';
	}
	for(int i=1;i<=cl;i++){
		c[i]+=a[i]+b[i];
		c[i+1]+=c[i]/10;
		c[i]%=10;
	}
	while(c[cl]==0&&cl>1){
		cl--;
	}
	string cs;
	for(int i=cl;i>=1;i--){
		cs+=c[i]+'0';
	}
	return cs;
}
int main(){
	string as,bs;
	cin>>as>>bs;
	cout<<Add(as,bs);
	return 0;
}

好了我们的整数加法看完了

OK

直接开始下面的整数减法

整数减法

我们还是用我们可爱的string类型来解决这个问题

我们跟上面的加法差不多也是用子程序来解决这个问题

spearboy:快来吧我都等不及了😜😜

教学开始

照旧定义好 a, b, c(int类型)

这里spearboy建议用子程序

因为前面讲过我们用string类型来解决,所以这里的子程序使用string类型.(名字叫sub)

在这里就不是定义string类型as和bs(待会讲)

由于可能会遇到多组数据所以我们在子程序的开头需要memset(a,0,sizeof(a)); memset(b,0,sizeof(b));memset(c,0,sizeof(c));//很长😑

多了一个模拟行列式稍微简单一点的部分那么这个部分呢我们需要判断嗯是否需要输出负号因为减法中可能会减到负数所以我们需要判断😑

    if(as.size()<bs.size()||(as.size()==bs.size()&&as<bs)){
        cout<<"-";
        swap(as,bs);//一定要写一定要写一定要写
    }

接下来我们用int al和bl获取as和bs的长度(int al=as.size();int bl=bs.size();)注意还要定义cl获取al和bl中最大的那个值加一(max函数)

for循环每次将as[al-i]-"0"放入a[i];

bl也是同样的

接下来就到最难的一步了模拟行列式

跟前面的加法一样这道题也有它的难点就是借位

spearboy:啊题目好难感觉小脑萎缩了😵‍💫

跟上面一样也是去除前导零最后return cs就可以了

子程序就好了                                                spearboy:欧耶😃😃😃😃😃😃😃😃

我们来做一道题检测一下究竟会不会😃

大整数减法

目描述

求两个大的正整数相减的差。

输入格式

共2行,第1行是被减数a,第2行是减数b。每个大整数不超过200位,不会有多余的前导零。

输出格式

一行,即所求的差。

输入输出样例

输入样例1:

9999999999999999999999999999999999999

9999999999999

输出样例1:

9999999999999999999999990000000000000

#include<bits/stdc++.h>
using namespace std;
int a[200+10],b[200+10],c[200+10]; 
string sub(string as,string bs){
	memset(a,0,sizeof(a));
	memset(b,0,sizeof(b));
	memset(c,0,sizeof(c));
	if(as.size()<bs.size()||(as.size()==bs.size()&&as<bs)){
		cout<<"-";
		swap(as,bs);
	}
	int al=as.size(),bl=bs.size();
	int cl=max(al,bl)+1;
	for(int i=1;i<=al;i++){
		a[i]=as[al-i]-'0';
	}
	for(int i=1;i<=bl;i++){
		b[i]=bs[bl-i]-'0';
	}
	for(int i=1;i<=cl;i++){
		if(a[i]<b[i]){
			a[i+1]--;
			a[i]+=10;
		}
		c[i]=a[i]-b[i];
	}
	while(c[cl]==0&&cl>1){
		cl--;
	}
	string cs;
	for(int i=cl;i>=1;i--){
		cs+=c[i]+'0';
	}
	return cs;
}
int main(){
	string as,bs;
	cin>>as>>bs;
	cout<<sub(as,bs);
	return 0;
}

                                完成!!!!!!!!!!!!!!!!、

整数乘法

教学开始

照旧定义好 a, b, c(int类型)

这里spearboy建议用子程序

因为前面讲过我们用string类型来解决,所以这里的子程序使用string类型.(名字叫Muit)

在这里定义string类型as和bs

由于可能会遇到多组数据所以我们在子程序的开头需要memset(a,0,sizeof(a)); memset(b,0,sizeof(b));memset(c,0,sizeof(c));//很长😑

接下来我们用int al和bl获取as和bs的长度(int al=as.size();int bl=bs.size();)注意还要定义cl获取al+bl

for循环每次将as[al-i]-"0"放入a[i];

bl也是同样的

接下来就到最难的一步了模拟行列式

    for(int i=1;i<=al;i++){
        for(int j=1;j<=bl;j++){
            c[i+j-1]+=a[i]*b[j];
            c[i+j]+=c[i+j-1]/10;
            c[i+j-1]%=10;
        }
    }

spearboy:好难啊!😣

接下来就又到了去除前导零

                                                上题目

计算a*b(1)

题目描述

计算a*b,并输出结果

输入格式

一行:两个空格分隔的正整数a和b

输出格式

一行:a*b的结果

输入输出样例

输入样例1:

3 5

输出样例1:

15

#include<bits/stdc++.h>
using namespace std;
int a[1010],b[1010],c[2020];
string Muit(string as,string bs){
	memset(a,0,sizeof(a));
	memset(b,0,sizeof(b));
	memset(c,0,sizeof(c));
	int al=as.size(),bl=bs.size();
	int cl=al+bl;
	for(int i=1;i<=al;i++){
		a[i]=as[al-i]-'0';
	} 
	for(int i=1;i<=bl;i++){
		b[i]=bs[bl-i]-'0';
	}
	for(int i=1;i<=al;i++){
		for(int j=1;j<=bl;j++){
			c[i+j-1]+=a[i]*b[j];
			c[i+j]+=c[i+j-1]/10;
			c[i+j-1]%=10;
		}
	}
	while(cl>1&&c[cl]==0){ 
		cl--;
	}
	string cs;
	for(int i=cl;i>=1;i--){
		cs+=c[i]+'0';
	} 
	return cs;
}
int main(){
	string as,bs;
	cin>>bs>>as;
	cout<<Muit(bs,as);
	return 0;
}

整数除法

                                               特殊

学开始

照旧定义好 a,  c(int类型)

这里spearboy建议用子程序

因为前面讲过我们用string类型来解决,所以这里的子程序使用string类型.(名字叫 Div)

在这里定义string类型as和 long long b

由于可能会遇到多组数据所以我们在子程序的开头需要memset(a,0,sizeof(a));;memset(c,0,sizeof(c));//很长😑

接下来我们用int al获取as的长度(int al=as.size();)注意还要定义cl获取al

for循环每次将as[al-i]-"0"放入a[i];

接下来就到最难的一步了模拟行列式

    for(int i=1;i<=cl;i++){
        r=r*10+a[i];
        c[i]=r/b;
        r=r%b;
    }

去除前导零也变了

    int t=1;
    while(c[t]==0&&t<cl){
        t++;
    }

还有余数代码

int ys(string as,long long b){
    memset(a,0,sizeof(a));
    memset(c,0,sizeof(c));
    int al=as.size(),cl=al;
    for(int i=1;i<=al;i++){
        a[i]=as[i-1]-'0';
    }
    int r=0;
    for(int i=1;i<=cl;i++){
        r=r*10+a[i];
        c[i]=r/b;
        r=r%b;
    } 
    return r;

spearboy:好难啊!😣

                                        上题目

 a÷b

题目描述

输入两个整数a和b,求a÷b的商和余数。

输入格式

一行:两个空格分隔的正整数a和b。

输出格式

一行,两个空格分隔的整数,分别表示a÷b的商和余数。

输入输出样例

输入样例1:

20 3

输出样例1:

6 2
#include<bits/stdc++.h>
using namespace std;
int a[10000+10],c[10000+10];
string Div(string as,long long b){
	memset(a,0,sizeof(a));
	memset(c,0,sizeof(c));
	int al=as.size(),cl=al;
	for(int i=1;i<=al;i++){
		a[i]=as[i-1]-'0';
	}
	int r=0;
	for(int i=1;i<=cl;i++){
		r=r*10+a[i];
		c[i]=r/b;
		r=r%b;
	}
	int t=1;
	while(c[t]==0&&t<cl){
		t++;
	}
	string cs;
	for(int i=t;i<=cl;i++){
		cs+=c[i]+'0';
	}
	return cs;
}
int ys(string as,long long b){
	memset(a,0,sizeof(a));
	memset(c,0,sizeof(c));
	int al=as.size(),cl=al;
	for(int i=1;i<=al;i++){
		a[i]=as[i-1]-'0';
	}
	int r=0;
	for(int i=1;i<=cl;i++){
		r=r*10+a[i];
		c[i]=r/b;
		r=r%b;
	} 
	return r;
} 
int main(){
	string as;
	int n;
	cin>>as>>n;
	cout<<Div(as,n)<<" ";
	cout<<ys(as,n); 
	return 0;
}

                                                  完成!!!!!!!!!!!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值