Notas de estudio de computación de alta precisión

¿Qué es el cálculo de alta precisión?

El algoritmo de alta precisión ( algoritmo de alta precisión ) es un método matemático para procesar números grandes. En los cálculos científicos generales , a menudo se calcula con unos pocos cientos de dígitos o más después del punto decimal y, por supuesto, puede ser una gran cantidad de cientos de miles de millones o decenas de miles de millones. Generalmente, estos tipos de números se conocen colectivamente como números de alta precisión La aritmética de alta precisión es un tipo de simulación por computadora de operaciones de suma, resta, multiplicación, división, potencia , factorial y raíz cuadrada . Para un número muy grande que no se puede almacenar normalmente en la computadora, el número se divide, se divide en un almacenamiento de uno por uno o cuatro dígitos de cuatro dígitos en una matriz , y una matriz se usa para representar un número, por lo que este Los números se denominan números de alta precisión. Los algoritmos de alta precisión son algoritmos que pueden manejar varias operaciones con números de alta precisión, pero debido a sus particularidades, están separados de los algoritmos de números ordinarios y forman los suyos propios.

Cuándo usar cálculos de alta precisión

Cuando el rango del número involucrado en la operación (suma, resta, factor ...) excede en gran medida el rango que puede ser representado por los tipos de datos estándar (entero, real, entero largo). Por ejemplo, encuentre la suma de dos números de 20.000 dígitos. En este momento, es necesario utilizar algoritmos de alta precisión .

Cálculo de alta precisión

Entero

#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;
}

Punto flotante

#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;
}

 

Supongo que te gusta

Origin blog.csdn.net/Richard_1101/article/details/107654163
Recomendado
Clasificación