高精度運算(c/c++)/**加法、減法、乘法、除法、取餘模板*/



高精度 + 高精度

😄題目連接:http://acm.hdu.edu.cn/showproblem.php?pid=1002 😄
暈,初始化數組寫錯,wa幾回才發現.這裏須要注意的是輸出的時候注意最後一位的進位.php

//大數加法模板(求兩個非負的高精度整數相加的和)
#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 😄html

//求兩個高精度正整數(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 😄
此題怎麼也過不去,不知道爲何.有作出來的能夠交流交流(必定是我寫的板子太弱了).ios


高精度 * 高精度

😄題目連接: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 😄tcp

//只夠大內存(不廣泛適用)
#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 😄spa

#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 😄
在這裏插入圖片描述.net

//大數取餘
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;
}
相關文章
相關標籤/搜索