高精度

struct node{
	int m[MAXN];
	node(){memset(m,0,sizeof(m));}
	inline friend void operator *= (node &a,re int b){
		int x=0;
		for(re int i=1;i<=a.m[0];i++){
			re int y=a.m[i]*b+x;
			a.m[i]=y%10;
			x=y/10;
		}
		while(x){
		    a.m[++a.m[0]]=x%10;
		    x/=10;
		}
	}
	inline friend void operator /= (node &a,re int b){
		re int x=0;
		for(re int i=a.m[0];i>=1;i--){
			x+=a.m[i];
			a.m[i]=x/b;
			x%=b;
			x*=10;
		}
		while(a.m[a.m[0]]==0&&a.m[0]>1) 
			a.m[0]--;
	}
	inline friend node operator - (node a,node b){
		node c;
		re int i=1;
		while((i<=a.m[0])||(i<=b.m[0])){
			if(a.m[i]<b.m[i]){
				a.m[i]+=10;
				a.m[i+1]--;
			}
			c.m[i]=a.m[i]-b.m[i];
			i++;
		}
		while(c.m[i]==0&&i>1)
			i--;
		c.m[0]=i;
		return c;
	}
	inline friend void print(node a){
		for(re int i=a.m[0];i>=1;i--)
			printf("%d",a.m[i]);
		puts("");
	}
}x;

重载的运算符,m[0]表示位数

 

#include<bits/stdc++.h>
using namespace std;
char ch[500000];
struct node{
	int s[1000000],len;
	void init(){
		scanf("%s",ch+1);
		len=strlen(ch+1);
		for(int i=1;i<=len;++i) s[len-i+1]=ch[i]-48;
	}
	void multi(){
		++len;
		for(int i=len;i;--i) s[i]=s[i-1];
	}
	void divid(){
		for(int i=1;i<=len;++i) s[i]=s[i+1];
		--len;
	}
	friend bool operator <= (const node &a,const node &b){
		if(a.len^b.len) return a.len<b.len;
		for(int i=a.len;i;--i) if(a.s[i]^b.s[i]) return a.s[i]<b.s[i];
		return 1;
	}
	friend void operator -= (node &a,const node &b){
		for(int i=1;i<=b.len;++i) a.s[i]-=b.s[i];
		for(int i=1;i<=a.len;++i) if(a.s[i]<0) a.s[i]+=10,a.s[i+1]--;
		while(a.len!=1&&a.s[a.len]==0) a.len--;
	}
	friend void operator += (node &a,const node &b){
		a.len=max(a.len,b.len)+1;
		for(int i=1;i<=a.len;++i) a.s[i]+=b.s[i];
		for(int i=1;i<=a.len;++i) if(a.s[i]>9) a.s[i]-=10,a.s[i+1]++;
		while(a.len!=1&&a.s[a.len]==0) a.len--;
	}
	friend void operator *= (node &a,const node &b){
		node c;c.len=a.len*b.len+10;
		for(int i=1;i<=a.len;++i)
			for(int j=1;j<=b.len;++j)
				c.s[i+j-1]+=a.s[i]*b.s[j];
		for(int i=1;i<=c.len;++i) if(c.s[i]>9) c.s[i+1]+=c.s[i]/10,c.s[i]%=10;
		while(c.len!=1&&c.s[c.len]==0) c.len--;
		a=c;
	}
	friend void operator %= (node &a,const node &d){
		node b=d;int x=b.len;
		while(b<=a) b.multi();b.divid();
		node c;c.s[c.len=0]=0;
		while(b.len>=x){
			++c.len;
			while(b<=a) a-=b,++c.s[c.len];
			c.divid();
		}
		c.len=max(c.len,1);
	}
	friend void operator /= (node &a,const node &d){
		node b=d;int x=b.len;
		while(b<=a) b.multi();b.divid();
		node c;c.s[c.len=0]=0;
		while(b.len>=x){
			++c.len;
			while(b<=a) a-=b,++c.s[c.len];
			b.divid();
		}
		c.len=max(c.len,1);//防止a<d的情况出不来数
		a=c;
	}
}n,m;
int main(){
	n.init(),m.init();
	n/=m;
	for(int i=1;i<=n.len;++i)printf("%d",n.s[i]);

}

 

#include<iostream>
#include<vector>
#include<string>
using namespace std;
struct Wint:vector<int>//用标准库vector做基类,完美解决位数问题,同时更易于实现
{
    //将低精度转高精度的初始化,可以自动被编译器调用
    //因此无需单独写高精度数和低精度数的运算函数,十分方便
    Wint(int n=0)//默认初始化为0,但0的保存形式为空
    {
        push_back(n);
        check();
    }
    Wint& check()//在各类运算中经常用到的进位小函数,不妨内置
    {
        while(!empty()&&!back())pop_back();//去除最高位可能存在的0
        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.back()%2)return n*pow(n,k-1);
    return pow(pow(n,k/2),2);
}
//通过重载运算符,还可以实现++、--、^、!、逻辑运算符等很多运算,十分简单,此处都不写了
int main()//现在你完全可以像int一般便捷地使用Wint,如下
{
    Wint a,b;
    //可以把b改成int型,仍能正常使用
    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);
}
View Code

 

posted @ 2019-07-21 17:18  xukl21  阅读(167)  评论(0编辑  收藏  举报