高精度运算(c/c++)/**加法、减法、乘法、除法、取余模板*/



高精度 + 高精度

?题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1002 ?
晕,初始化数组写错,wa几次才发现.这里需要注意的是输出的时候注意最后一位的进位.

//大数加法模板(求两个非负的高精度整数相加的和)
#include<cstdio>
#include<cstring>
#include<cmath> 
#include<iostream>
using namespace std;
 
const int Max_n=1005;
typedef long long LL;
int a[Max_n],b[Max_n];
char c[Max_n],d[Max_n];

int main(){
    int t;
    scanf("%d",&t);
    for(int cnt=1;cnt<=t;cnt++){
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        scanf("%s%s",c,d);
        int lenc=strlen(c);
        for(int i=0;i<lenc;i++)
            a[i]=c[lenc-i-1]-'0';
        int lend=strlen(d);
        for(int i=0;i<lend;i++)
            b[i]=d[lend-i-1]-'0';
        int len=max(lenc,lend); 
        for(int i=0;i<len;i++){
            a[i]=a[i]+b[i];
            if(a[i]>9){
                a[i]-=10;
                a[i+1]++;
            }
        }
        printf("Case %d:\n",cnt);
        printf("%s + %s = ",c,d);
        len=a[len]?len:len-1;//这里要注意进位的问题
        for(int i=len;i>=0;i--)
            printf("%d",a[i]);
        printf("\n");
        if(cnt<t) printf("\n");
    }
    return 0;
}


高精度 - 高精度

?题目链接:http://tk.hustoj.com/problem.php?id=22598 ?

//求两个高精度正整数(x,y)相减的,如果x<y就交换位置,最后输出的时候加-
#include<cstdio>
#include<cstring>
#include<cmath> 
#include<iostream>
using namespace std;
 
const int Max_n=10005;
typedef long long LL;
int a[Max_n],b[Max_n];
string c,d;

bool cmp(){
	if(c.length()!=d.length()) 
		return c.length()>d.length();
	return c>=d;
}

int main(){
    cin>>c>>d;
    int lenc=c.length();
    int lend=d.length();
    if(cmp()){
    	for(int i=0;i<lenc;i++)
    		a[i]=c[lenc-i-1]-'0';
    	for(int i=0;i<lend;i++)
    		b[i]=d[lend-i-1]-'0';
    }else{
    	for(int i=0;i<lend;i++)
    		a[i]=d[lend-i-1]-'0';
    	for(int i=0;i<lenc;i++)
    		b[i]=c[lenc-i-1]-'0';
    	cout<<"-"; 
    }
    int len=max(lenc,lend);
    for(int i=0;i<len;i++){
    	if(a[i]>=b[i]) a[i]-=b[i];
    	else{
    		a[i]=a[i]+10-b[i];
    		a[i+1]--;
    	}
    }
    int index=-1;
    for(int i=len-1;i>0;i--){//可以借助高精度/单精度里面的方法去除前导0(要比这个简单很多).
    	if(a[i]){
    		index=i;
			break;
    	} 
    }
 	if(index!=-1){
 		for(int i=index;i>=0;i--)
 			cout<<a[i];
 		cout<<endl;
 	}else cout<<"0"<<endl;
    return 0;
}

?题目链接:http://acm.sdut.edu.cn/onlinejudge2/index.php/Home/Index/problemdetail/pid/2525.html ?
此题怎么也过不去,不知道为什么.有做出来的可以交流交流(一定是我写的板子太弱了).


高精度 * 高精度

?题目链接:http://www.51nod.com/Challenge/Problem.html#!#problemId=1027 ?
?题目链接:http://tk.hustoj.com/problem.php?id=22599 ?

//首先计算被乘数与乘数的每位数字的乘积,其中a[i]乘b[j]的积 累加到数组ans[i+j]上,然后对累加结果ans作一次性进位.
#include<cstdio>
#include<cstring>
#include<cmath> 
#include<iostream>
using namespace std;
 
const int Max_n=1005;
typedef long long LL;
int a[Max_n],b[Max_n],ans[2*Max_n];//保存的最大位数就是lena+lenb 
char c[Max_n],d[Max_n];

int main(){
    scanf("%s%s",c,d);
    int lenc=strlen(c);
    for(int i=0;i<lenc;i++)
    	a[i]=c[lenc-i-1]-'0';
    int lend=strlen(d);
    for(int i=0;i<lend;i++)
    	b[i]=d[lend-i-1]-'0';
    for(int i=0;i<lenc;i++)
    	for(int j=0;j<lend;j++)
    		ans[i+j]+=a[i]*b[j];//注意'+' 
    int len=lenc+lend;//最多len位(从0开始取到的就是a[len-1]),无进位就是len-1(a[len-2])位 
    for(int i=0;i<len-1;i++){
    	if(ans[i]>9){
    		ans[i+1]+=ans[i]/10;//抽出个位以外的数字 
    		ans[i]%=10;//保留个位 
    	}
    }
   	len=ans[len-1]?len-1:len-2;//下标最多到len-1 
	for(int i=len;i>=0;i--)
		printf("%d",ans[i]);
	printf("\n");	
    return 0;
}

高精度 * 单精度

?题目链接:http://www.dotcpp.com/oj/problem1474.html ?

//只够大内存(不普遍适用)
#include<cstdio>
#include<cstring>
#include<cmath> 
#include<iostream>
using namespace std;
 
const int Max_n=4*1005;
typedef long long LL;

struct BigNum{
	int s[Max_n],l;
}c[1005];

BigNum operator *(BigNum a,int b){
	for(int i=0;i<a.l;i++) a.s[i]*=b;
	for(int i=0;i<a.l;i++){//(除最高位)处理各个位上面的数 
		a.s[i+1]+=a.s[i]/10;
		a.s[i]%=10;
	}	
	while(a.s[a.l]!=0){//处理最高位 
		a.s[a.l+1]+=a.s[a.l]/10;
		a.s[a.l]%=10; 
		a.l++;
	} 
	return a;
} 

void print(BigNum a){
	for(int i=a.l-1;i>=0;i--)
		printf("%d",a.s[i]); 
	printf("\n");
}

int main(){
	c[0].s[0]=1,c[0].l=1;
	for(int i=1;i<=1000;i++)
		c[i]=c[i-1]*i;
	int n;
	scanf("%d",&n);
	print(c[n]);
    return 0;
}

高精度 / 单精度

//与下面的大数取余原理差不多
//示例1:
BigNum operator /(BigNum a,int b){
	for(int i=a.l-1;i>0;i--){//从最高位开始处理 
		a.s[i-1]+=(a.s[i]%b)*10;
		a.s[i]/=b;
	}
	a.s[0]/=b;
	while(a.s[a.l-1]==0) a.l--;//去除前导0
	return a; 
} 
//示例2:
int main(){//计算1234/8
	int n=4;
	int a[4]={4,3,2,1};
	for(int i=n-1;i>0;i--){
		a[i-1]+=(a[i]%8)*10;
		a[i]/=8;
	}
	a[0]/=8;
	while(a[n-1]==0) n--;
	for(int i=n-1;i>=0;i--)
		printf("%d",a[i]);
	printf("\n");
    return 0;
}

高精度幂取模

?题目链接:https://ac.nowcoder.com/acm/contest/392/B ?

#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;

const int Max_n=100005;
typedef long long LL;

LL q_mul(LL a,LL b,LL mod){//快速乘
	LL ans=0,res=a;
	while(b){
		if(b&1) ans=(ans+res)%mod;
		res=(res+res)%mod;
		b>>=1;
	}
	return ans;
}

LL q_pow(LL a,LL b,LL mod){//快速幂
	LL ans=1,res=a;
	while(b){
		if(b&1) ans=q_mul(ans,res,mod);
		res=q_mul(res,res,mod);
		b>>=1;
	}
	return ans;	
}

int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		LL a,b,mod;
		scanf("%lld%lld%lld",&a,&b,&mod);
		LL ans=q_pow(a,b,mod);
		printf("%lld\n",ans);
	}
	return 0;
}

高精度取余

?总结链接:https://blog.csdn.net/qq_42217376/article/details/86722805 ?
在这里插入图片描述

//大数取余
LL Qpow_mod(){
	LL ans=0;
	int n=strlen(a);
	for(int i=0;i<n;i++)
		ans=(ans*10+(a[i]-'0'))%mod;
	return ans;
}

int main(){ 
	scanf("%s",a);
	LL b=Qpow_mod();
	printf("%lld\n",b);
    return 0;
}

转载于:https://www.cnblogs.com/zut-syp/p/10543667.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值