高精度

其实高精度就按你平时手算的的方法写出来就好了
这份代码用 \(long \ long\)\(8\)
高精乘可以用FFT优化(这里没有)
高精除需要使用 \(2\) 的幂次来试商,这样会快很多

其实这东西要的就是一个,一般用到高精的东西最后不是别的地方错了,而是高精错了。


#include<vector>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

namespace Super_Calc{
	typedef long long LL;
	const int WIDTH = 10000+9;
	const int MOD = 100000000;
	char BUF[WIDTH];
	struct Num{
		vector<LL> vec;
	};
	struct PAIR{
		Num first;
		bool second;
	};

	Num Input(){
		Num re;
		scanf("%s",BUF);
		int len=strlen(BUF);
		for(int i=len-1;i>=7;i-=8){
			LL tmp=0;
			for(int j=7;j>=0;j--)
				tmp=tmp*10+BUF[i-j]-'0';
			re.vec.push_back(tmp);
		}
		len=len%8;
		if(len==0)return re;
		LL tmp=0;
		for(int i=0;i<=len-1;i++)
			tmp=tmp*10+BUF[i]-'0';
		re.vec.push_back(tmp);
		return re;
	}

	void Print(const Num &A,char s=0,bool sign=1){
		if(!sign)putchar('-');
		sprintf(BUF,"%lld",A.vec.back());
		printf("%s",BUF);
		for(int i=A.vec.size()-2;i>=0;i--){
			sprintf(BUF,"%08lld",A.vec[i]);
			printf("%s",BUF);
		}
		if(s)putchar(s);
	}

	Num Change(LL val){
		Num re;
		re.vec.push_back(val);
		return re;
	}

	Num operator << (const Num &A,int k){
		Num re;
		re.vec.resize(A.vec.size()+k);
		for(int i=k,j=0;j<A.vec.size();i++,j++){
			re.vec[i]=A.vec[j];
		}
		return re;
	}

	bool operator < (const Num &A,const Num &B){
		if(A.vec.size()!=B.vec.size())
			return A.vec.size()<B.vec.size();
		int len=A.vec.size();
		for(int i=len-1;i>=0;i--){
			if(A.vec[i]<B.vec[i])return true;
			if(A.vec[i]>B.vec[i])return false;
		}
		return false;
	}

	bool operator <= (const Num &A,const Num &B){
		if(A.vec.size()!=B.vec.size())
			return A.vec.size()<B.vec.size();
		int len=A.vec.size();
		for(int i=len-1;i>=0;i--){
			if(A.vec[i]<B.vec[i])return true;
			if(A.vec[i]>B.vec[i])return false;
		}
		return true;
	}

	bool operator > (const Num &A,const Num &B){
		if(A.vec.size()!=B.vec.size())
			return A.vec.size()>B.vec.size();
		int len=A.vec.size();
		for(int i=len-1;i>=0;i--){
			if(A.vec[i]>B.vec[i])return true;
			if(A.vec[i]<B.vec[i])return false;
		}
		return false;
	}

	bool operator >= (const Num &A,const Num &B){
		if(A.vec.size()!=B.vec.size())
			return A.vec.size()>B.vec.size();
		int len=A.vec.size();
		for(int i=len-1;i>=0;i--){
			if(A.vec[i]>B.vec[i])return true;
			if(A.vec[i]<B.vec[i])return false;
		}
		return true;
	}

	bool operator == (const Num &A,const Num &B){
		if(A.vec.size()!=B.vec.size())
			return false;
		int len=A.vec.size();
		for(int i=0;i<len;i++)
			if(A.vec[i]!=B.vec[i])return false;
		return true;
	}

	Num operator + (const Num &A,const Num &B){
		Num re;
		re.vec.resize(max(A.vec.size(),B.vec.size())+1);
		for(int i=0;i<A.vec.size();i++){
			re.vec[i]+=A.vec[i];
		}
		for(int i=0;i<B.vec.size();i++){
			re.vec[i]+=B.vec[i];
		}
		for(int i=0;i<re.vec.size()-1;i++){
			re.vec[i+1]+=re.vec[i]/MOD;
			re.vec[i]%=MOD;
		}
		while(!re.vec.back() && re.vec.size()>1) re.vec.pop_back();
		return re;
	}

	PAIR operator - (const Num &A,const Num &B){
		Num X,Y;
		bool pd;
		if(A==B){X.vec.push_back(0);return (PAIR){X,1};}
		if(A>B){X=A;Y=B;pd=1;}
		else{X=B;Y=A;pd=0;}
		for(int i=0;i<Y.vec.size();i++){
			X.vec[i]-=Y.vec[i];
		}
		for(int i=0;i<X.vec.size()-1;i++){
			if(X.vec[i]<0){
				X.vec[i]+=MOD;
				X.vec[i+1]--;
			}
		}
		while(!X.vec.back() && X.vec.size()>1)X.vec.pop_back();
		return (PAIR){X,pd};
	}

	Num operator * (const Num &A,const Num &B){
		Num re;
		re.vec.resize(A.vec.size()+B.vec.size()+1);
		for(int i=0,lim=A.vec.size();i<lim;i++){
			for(int j=0,lim=B.vec.size();j<lim;j++){
				re.vec[i+j]+=A.vec[i]*B.vec[j];
			}
		}
		for(int i=0,lim=re.vec.size();i<lim;i++){
			re.vec[i+1]+=re.vec[i]/MOD;
			re.vec[i]%=MOD;
		}
		while(!re.vec.back() && re.vec.size()>1) re.vec.pop_back();
		return re;
	}

	Num DivMod(const Num &A,const Num &B,Num &R){
		R=A;
		Num re;
		re.vec.resize(A.vec.size()-B.vec.size()+1);
		for(int i=re.vec.size()-1;i>=0;i--){
			Num val10=B<<i;
			for(int j=26;j>=0;j--){
				LL tmp=1<<j;
				Num val2=val10*Change(tmp);
				if(R>=val2){
					R=(R-val2).first;
					re.vec[i]+=tmp;
				}
			}
		}
		while(!re.vec.back() && re.vec.size()>1) re.vec.pop_back();
		return re;
	}

	Num operator / (const Num &A,const Num &B){
		Num re;
		if(A==B){re.vec.push_back(1);return re;}
		if(A<B){re.vec.push_back(0);return re;}
		Num X;
		re=DivMod(A,B,X);
		return re;
	}

	Num operator % (const Num &A,const Num &B){
		Num re;
		if(A==B){re.vec.push_back(0);return re;}
		if(A<B){return A;}
		Num X;
		DivMod(A,B,X);
		return X;
	}
}

using namespace Super_Calc;
int main(){
	Num A=Input();
	Num B=Input();
	Print(A+B,'\n');
	PAIR C=A-B;
	Print(C.first,'\n',C.second);
	Print(A*B,'\n');
	Print(A/B,'\n');
	Print(A%B,'\n');
	return 0;
}

posted @ 2018-01-21 13:19  zzzc18  阅读(112)  评论(0编辑  收藏  举报