高精度コンピューティング研究ノート

高精度計算とは

高精度アルゴリズム高精度アルゴリズム)は、多数を処理するための数学的な方法です。一般科学的計算では、小数点以下数百桁以上で計算されることが多く、もちろん数千億から数百億にもなることもあります。一般に、これらのタイプの数値は、まとめて高精度数値と呼ばれます。高精度算術は、加算、減算、乗算、除算、累乗因数分解、および平方根演算の一種のコンピュータシミュレーションですコンピュータに正常に保存できない非常に大きな数の場合、その数は分割され、1つずつ、または4桁の4桁のストレージに分割され、配列は番号を表すために使用されます。数値は高精度数値と呼ばれます。高精度アルゴリズムは、高精度の数値に対するさまざまな操作を処理できるアルゴリズムですが、その特殊性のために、通常の数値のアルゴリズムから分離され、独自のアルゴリズムを形成します。

高精度の計算を使用する場合

操作に関係する数の範囲(加算、減算、因数分解など)が、標準のデータタイプ(整数、実数、長整数)が表すことができる範囲を大幅に超えている場合。たとえば、2つの20000桁の数字の合計を求めます。現時点では、高精度のアルゴリズムを使用する必要があります

高精度計算

整数

#include<bits/stdc++.h> 
using namespace std;
struct Wint:vector<int>
{
	Wint(int n=0)
	{
		push_back(n);
		check();
	}
	Wint& check()
	{
		while(!empty()&&!back())pop_back();
		if(empty())return *this;
		for(int i=1; i<size(); ++i)
		{
			(*this)[i]+=(*this)[i-1]/10;
			(*this)[i-1]%=10;
		}
		while(back()>=10)
		{
			push_back(back()/10);
			(*this)[size()-2]%=10;
		}
		return *this;
	}
};
istream& operator>>(istream &is,Wint &n)
{
	string s;
	is>>s;
	n.clear();
	for(int i=s.size()-1; i>=0; --i)n.push_back(s[i]-'0');
	return is;
}
ostream& operator<<(ostream &os,const Wint &n)
{
	if(n.empty())os<<0;
	for(int i=n.size()-1; i>=0; --i)os<<n[i];
	return os;
}
bool operator!=(const Wint &a,const Wint &b)
{
	if(a.size()!=b.size())return 1;
	for(int i=a.size()-1; i>=0; --i)
		if(a[i]!=b[i])return 1;
	return 0;
}
bool operator==(const Wint &a,const Wint &b)
{
	return !(a!=b);
}
bool operator<(const Wint &a,const Wint &b)
{
	if(a.size()!=b.size())
		return a.size()<b.size();
	for(int i=a.size()-1; i>=0; --i)
		if(a[i]!=b[i])return a[i]<b[i];
	return 0;
}
bool operator>(const Wint &a,const Wint &b)
{
	return b<a;
}
bool operator<=(const Wint &a,const Wint &b)
{
	return !(a>b);
}
bool operator>=(const Wint &a,const Wint &b)
{
	return !(a<b);
}
Wint& operator+=(Wint &a,const Wint &b)
{
	if(a.size()<b.size())
	{
		a.resize(b.size());
	}
	for(int i=0; i!=b.size();++i)
	{
		a[i]+=b[i];
	}
	return a.check();
}
Wint operator+(Wint a,const Wint &b)
{
	return a+=b;
}
Wint& operator-=(Wint &a,Wint b)
{
	if(a<b)swap(a,b);
	for(int i=0;i!=b.size();a[i]-=b[i],++i)
		if(a[i]<b[i])
		{
			int j=i+1;
			while(!a[j])++j;
			while(j>i)
			{
				--a[j];
				a[--j]+=10;
			}
		}
	return a.check();
}
Wint operator-(Wint a,const Wint &b)
{
	return a-=b;
}
Wint operator*(const Wint &a,const Wint &b)
{
	Wint n;
	n.assign(a.size()+b.size()-1,0);
	for(int i=0;i!=a.size();++i)
	{
		for(int j=0;j!=b.size();++j)
		{
			n[i+j]+=a[i]*b[j];
		}
	}
	return n.check();
}
Wint& operator*=(Wint &a,const Wint &b)
{
	return a=a*b;
}
Wint divmod(Wint &a,const Wint &b)
{
	Wint ans;
	for(int t=a.size()-b.size(); a>=b; --t)
	{
		Wint d;
		d.assign(t+1,0);
		d.back()=1;
		Wint c=b*d;
		while(a>=c)
		{
			a-=c;
			ans+=d;
		}
	}
	return ans;
}
Wint operator/(Wint a,const Wint &b)
{
	return divmod(a,b);
}
Wint& operator/=(Wint &a,const Wint &b)
{
	return a=a/b;
}
Wint& operator%=(Wint &a,const Wint &b)
{
	divmod(a,b);
	return a;
}
Wint operator%(Wint a,const Wint &b)
{
	return a%=b;
}
Wint pow(const Wint &n,const Wint &k)
{
	if(k.empty())return 1;
	if(k==2)return n*n;
	if(k.front()%2)return n*pow(n,k-1);
	return pow(pow(n,k/2),2);
}
int main()
{
	Wint a,b;
	cin>>a>>b;
	cout<<(a<b)<<endl<<(a==b)<<endl<<a+b<<endl<<a-b<<endl<<a*b<<endl<<a/b<<endl<<a%b<<endl<<pow(a,b);
	return 0;
}

フローティングポイント

#include<bits/stdc++.h>
using namespace std;
struct Wint:vector<int>
{
	Wint(int n=0)
	{
		push_back(n);
		check();
	}
	Wint& check()
	{
		while(!empty()&&!back())pop_back();
		if(empty())return *this;
		for(int i=1; i<size(); ++i)
		{
			(*this)[i]+=(*this)[i-1]/10;
			(*this)[i-1]%=10;
		}
		while(back()>=10)
		{
			push_back(back()/10);
			(*this)[size()-2]%=10;
		}
		return *this;
	}
};
istream& operator>>(istream &is,Wint &n)
{
	string s;
	is>>s;
	n.clear();
	for(int i=s.size()-1; i>=0; --i)n.push_back(s[i]-'0');
	return is;
}
ostream& operator<<(ostream &os,const Wint &n)
{
	if(n.empty())os<<0;
	for(int i=n.size()-1; i>=0; --i)os<<n[i];
	return os;
}
bool operator!=(const Wint &a,const Wint &b)
{
	if(a.size()!=b.size())return 1;
	for(int i=a.size()-1; i>=0; --i)
		if(a[i]!=b[i])return 1;
	return 0;
}
bool operator==(const Wint &a,const Wint &b)
{
	return !(a!=b);
}
bool operator<(const Wint &a,const Wint &b)
{
	if(a.size()!=b.size())return a.size()<b.size();
	for(int i=a.size()-1; i>=0; --i)
		if(a[i]!=b[i])return a[i]<b[i];
	return 0;
}
bool operator>(const Wint &a,const Wint &b)
{
	return b<a;
}
bool operator<=(const Wint &a,const Wint &b)
{
	return !(a>b);
}
bool operator>=(const Wint &a,const Wint &b)
{
	return !(a<b);
}
Wint& operator+=(Wint &a,const Wint &b)
{
	if(a.size()<b.size())a.resize(b.size());
	for(int i=0; i!=b.size(); ++i)a[i]+=b[i];
	return a.check();
}
Wint operator+(Wint a,const Wint &b)
{
	return a+=b;
}
Wint& operator-=(Wint &a,Wint b)
{
	if(a<b)swap(a,b);
	for(int i=0; i!=b.size(); a[i]-=b[i],++i)
		if(a[i]<b[i])
		{
			int j=i+1;
			while(!a[j])++j;
			while(j>i)
			{
				--a[j];
				a[--j]+=10;
			}
		}
	return a.check();
}
Wint operator-(Wint a,const Wint &b)
{
	return a-=b;
}
Wint operator*(const Wint &a,const Wint &b)
{
	Wint n;
	n.assign(a.size()+b.size()-1,0);
	for(int i=0; i!=a.size(); ++i)
		for(int j=0; j!=b.size(); ++j)
			n[i+j]+=a[i]*b[j];
	return n.check();
}
Wint& operator*=(Wint &a,const Wint &b)
{
	return a=a*b;
}
Wint divmod(Wint &a,const Wint &b)
{
	Wint ans;
	for(int t=a.size()-b.size(); a>=b; --t)
	{
		Wint d;
		d.assign(t+1,0);
		d.back()=1;
		Wint c=b*d;
		while(a>=c)
		{
			a-=c;
			ans+=d;
		}
	}
	return ans;
}
Wint operator/(Wint a,const Wint &b)
{
	return divmod(a,b);
}
Wint& operator/=(Wint &a,const Wint &b)
{
	return a=a/b;
}
Wint& operator%=(Wint &a,const Wint &b)
{
	divmod(a,b);
	return a;
}
Wint operator%(Wint a,const Wint &b)
{
	return a%=b;
}
Wint pow(const Wint &n,const Wint &k)
{
	if(k.empty())return 1;
	if(k==2)return n*n;
	if(k.front()%2)return n*pow(n,k-1);
	return pow(pow(n,k/2),2);
}
int main()
{
	Wint a,b;
	cin>>a>>b;
	cout<<(a<b)<<endl<<(a==b)<<endl<<a+b<<endl<<a-b<<endl<<a*b<<endl<<a/b<<endl<<a%b<<endl<<pow(a,b);
	return 0;
}

 

おすすめ

転載: blog.csdn.net/Richard_1101/article/details/107654163