高精度运算模板

支持 加、减、乘、除、开方运算,保留整数位

#include<iostream>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<cstdio>
using namespace std;
struct hac
{
    vector<int> a;
    bool flag;
    hac con()const //符号取反 
    {
        hac temp=*this;
        temp.flag=!temp.flag;
        return temp;
    }
    void store(string str="")
    {
        string t;
        int temp;
        flag=(str[0]!='-');
        if(!flag||str[0]=='+')
         str.erase(0,1);
        while(str.length()%4!=0)str='0'+str; //高位补零 
        a.push_back(str.length()/4);//位数
        for(int i=0;i<a[0];i++)
        {
            t=str.substr(str.length()-4,4);
            temp=1000*(t[0]-'0')+100*(t[1]-'0')+10*(t[2]-'0')+(t[3]-'0');
            a.push_back(temp);
            str.erase(str.length()-4,str.length()-1);
        }
    }
    bool operator==(const hac x)const
    {
        if(flag!=x.flag||a[0]!=x.a[0])return false;
        for(int i=1;i<=a[0];i++)
         if(a[i]!=x.a[i])
          return false;
        return true;
    }
    bool operator<(const hac x)const
    {
        if(!flag&&x.flag)return true;
        if(flag&&!x.flag)return false;
        if(!flag&&!x.flag)
         return x.con()<(*this).con();
        if(a[0]<x.a[0])return true;
        if(a[0]>x.a[0])return false;
        int i=a[0];
        while(i>=1&&a[i]==x.a[i])i--;
        if(i>=1)
         return a[i]<x.a[i];
        return false;
    }
    bool operator>(const hac x)const
    {
        return x<*this;
    }
    bool operator<=(const hac x)const
    {
        return !(*this>x);
    }
    bool operator>=(const hac x)const
    {
        return !(*this<x);
    }
    hac operator+(hac b)const
    {
        hac ans=*this;
        int i;
        if(ans.flag&&b.flag)
        {
            if(ans.a[0]<b.a[0])return b+ans;
            ans.a.push_back(0);
            ans.a.push_back(0);
            for(i=1;i<=b.a[0];i++)
               ans.a[i]+=b.a[i];
            for(i=1;i<=ans.a[0];i++)
               while(ans.a[i]>=10000){ans.a[i+1]+=ans.a[i]/10000;ans.a[i]%=10000;}
            while(ans.a[ans.a[0]+1]!=0)ans.a[0]++;
            return ans;
        }
        else if(!ans.flag&&b.flag)
        {
            ans.flag=true;
            return b-ans;
        }
        else if(ans.flag&&!b.flag)
        {
            b.flag=true;
            return ans-b;
        }
        else 
        {
            ans.flag=true;
            b.flag=true;
            return (ans+b).con();
        }
    }
    hac operator-(hac b)const
    {
        hac ans=*this;
        if(!ans.flag&&!b.flag)
        {
            return (b.con()-ans.con());
        }
        if(ans<b){return (b-ans).con();}
        if(!ans.flag)
        {
            return (ans.con()+b).con();
        }
        if(!b.flag)
        {
            return ans+b.con();
        }
        for(int i=1;i<=b.a[0];i++)
            ans.a[i]-=b.a[i];
        for(int i=1;i<=ans.a[0];i++)
            while(ans.a[i]<0)
            {
                ans.a[i+1]--;
                ans.a[i]+=10000; 
            }         
        while(ans.a[ans.a[0]]==0&&ans.a[0]>1)ans.a[0]--;
        return ans; 
    }
    hac operator*(hac b)const
    { 
        hac temp=*this;
        vector<int> c(temp.a[0]+b.a[0]+2);
        int i,j;
        if(!b.flag)temp.flag=!temp.flag;
        c[0]=temp.a[0]+b.a[0]-1;
        for(i=1;i<=temp.a[0];i++)
         for(j=1;j<=b.a[0];j++)
         {
             c[i+j-1]+=(temp.a[i]*b.a[j]);
             c[i+j]+=(c[i+j-1]/10000);
             c[i+j-1]%=10000;
         }
        temp.a=c;
        while(temp.a[temp.a[0]+1]!=0)temp.a[0]++;
        return temp;
    }
    hac div2()
    {
        a[1]/=2;
        for(int i=2;i<=a[0];i++)
        {
            if(a[i]%2)a[i-1]+=5000;
            a[i]/=2;
        }
        if(!a[a[0]])a[0]--;
        return *this;    
    }
    hac operator/(hac b) //二分法,求整数商 
    {
        if(!flag&&!b.flag)return con()/b.con();
        if(!flag&&b.flag)return (con()/b).con();
        if(flag&&!b.flag)return (*this/b.con()).con();
        hac l,r,m,one;
        string s="";
        l.store("0");
        one.store("1");
        for(int i=1;i<=a[0]-b.a[0]+1;i++)s+="0000";
        s='1'+s;
        m.store(s);
        r=m*b;
        while(l+one<r)
        {
            m=(l+r).div2();
            if(m*b==*this) return m;
            (m*b>=*this)? r=m:l=m;
        }
        return l;
    }
    void print() //打印 
    {
        if(!flag)cout<<'-';
        while(a[a[0]]==0&&a[0]>1)a[0]--;
        cout<<a[a[0]];
        for(int i=a[0]-1;i>0;i--)
         printf("%04d",a[i]);
    }
    hac sqrt()
    {
        hac l,r=*this,m,one;
        r.a[0]/=2;
        r.a[0]++;
        one.store("1");
        l.store("0");
        if(!flag)return l;//负数无法开方
        if(*this==one)return one; 
        while(l+one<r)
        {
            m=(l+r).div2();
            if(m*m==*this) return m;
            (m*m>=*this)? r=m:l=m;
        }
        return l;
    }
};
hac a,b;
string x,y;
int main()
{
    cin>>x;
    a.store(x);
    a.sqrt().print();
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值