我的高精日记 #1

我的高精日记 #1 2018-8

成功切掉高精度加法,逻辑运算。Code:

struct BN//Big_number
{
   #define LEN_SIZE 100001//定义长度
   int len;//记录长度
   int a[LEN_SIZE];//记录每一位数字
//   结构体中,可以直接调用自己的变量,不用写XX.XX,很方便 OVO!
   bool is_nn;//is negative num 记录是否是负数   
   inline void clear() { is_nn=false , memset(a,0,sizeof a) , len=0 ; return; }//将整个结构体清零 初值:不是负数,0
   inline void BN_read()
   {
      char t=getchar();//感觉getchar()会更快一点
      clear();//清空等待读入
      for(;!isdigit(t);t=getchar()) if(t=='-') is_nn=true;//不是数字,抛弃字符。如果是负号,把记录变量(is_nn)赋值成真(true)
      //isdigit(char _C) 返回布尔值,是否是数字
      for(;isdigit(t);t=getchar()) a[++len]=(t-'0');//是数字,把长度加一
      return;结束
    }
    inline void BN_write()
    {
        if(is_nn) putchar('-');//是负数,输出符号。
        for(int i=1;i<=len;++i) putchar(a[i]+'0');//输出字符,感觉putchar()会快一点,从1~长度len枚举输出,下标从1开始
        return;
    }
    template <typename _int>//定义一个类变量-- _int
    inline void change(_int A)//将任意类转成高精类(BN)。用_int定义,支持所有类
    {
        clear();//将载体清空
        if(!A)//如果A是0
        {
            len=1;//零的长度为1
            a[1]=0;//第一位是0
            is_nn=false;//无符号
            return;//返回
        }
        _int _A=A;//用另一个_int类来记录
        if(_A<0) _A=-_A,is_nn=true;//是负数,记录成有符号,取绝对值
        for(;_A;++len,_A/=10);//找长度有几位,特判0,不然卡掉循环
        _A=A;//因为找完长度_A为0,重新赋值成A。
        if(is_nn) _A=-_A;//如果有符号,取绝对值
        for(int i=len;i;--i) a[i]=_A%10,_A/=10;//把A的每一位存进存数字的数组中
        return;//结束
    }
    BN operator = (const BN &next)//重载运算符“=”,返回高精类值
    {
        clear();//同强转类型,清空载体
        is_nn=next.is_nn;//转移符号
        len=next.len;//转移长度
        for(int i=1;i<=next.len;++i) a[i]=next.a[i];//把next的每一位数赋给载体
        return *this;//返回自己(*this)。
        //*this——C++关键字,返回结构体中的变量,代指自己(结构体)
    }
    bool operator < (const BN &next) const //返回布尔值,重载“<”号,是否小于next(下一个数)
    {
        if(!next.is_nn&&!is_nn)//两数同为正数
        {
            if(len<next.len) return true;//长度比下一个数小,一定比下一个数小
            if(len>next.len) return false;//反之,比下一个数大
            for(int i=len;i;--i)//确认长度一样,从最高位开始比较
            {
                if(a[i]<next.a[i]) return true;//找到第i位数比下一个数的第i位数小,就比下一个数小,返回
                if(a[i]>next.a[i]) return false;//反之,比下一个数大,返回
                if(a[i]==next.a[i]) continue;//两个数相等,跳过以后的循环内容,貌似没了。。。
            }//不信找不到。假的
        }
        else if(next.is_nn&&is_nn)//两数同为负数,以下与判正数完全相反,复制的QAQ
        {
            if(len<next.len) return false;
            if(len>next.len) return true;
            for(int i=len;i;--i)
            {
                if(a[i]<next.a[i]) return false;
                if(a[i]>next.a[i]) return true;
                if(a[i]==next.a[i]) continue;
            }//看上面
        }
        //两数异号
        else if(next.is_nn&&!is_nn) return false;//下一个数是负数,这个是正数,返回比下一个数大
        else if(!next.is_nn&&is_nn) return true;//反之,返回比下一个数小
        return false;//没找到,说明相等,也不小于,返回
    }
    template <typename _int>//用于判低精数
    bool operator < (const _int &_next) const
    {
        BN next;
        next.change(_next);//转化成高精数再比较
        return (*this<next);//都是布尔值,直接返回就可以了
    }
    bool operator == (const BN &next) const //判相等
    {
        if(is_nn!=next.is_nn) return false;//位数不同,一定不相等
        for(int i=1;i<=len;++i) if(a[i]!=next.a[i]) return false;//发现数位不同,不想等,直接返回
        return true;//能跑到这里,欣慰啊,一定相等了,返回
    }
    template <typename _int>//判低精
    bool operator == (const _int &_next) const
    {
        BN next;
        next.change(_next);
        return (*this==next);
    }
    bool operator != (const BN &next) const //判不相等
    {
        return !(*this==next);//直接返回等于的假值,相等为假,不相等为真
    }
    template <typename _int>//判低精
    bool operator != (const _int &_next) const
    {
        BN next;
        next.change(_next);
        return (*this!=next);
    }
    bool operator > (const BN &next) const //判大于
    {
        return !((*this)<next&&((*this)!=next));//返回不小于并且不等于
    }
    template <typename _int>//判低精
    bool operator > (const _int &_next) const
    {
        BN next;
        next.change(_next);
        return (*this>next);
    }

    bool operator <= (const BN &next) const//判小于等于
    {
        return !(*this>next);//不大于即为小于等于
    }
    template <typename _int>//判低精
    bool operator <= (const _int &_next) const
    {
        BN next;
        next.change(_next);
        return (*this<=next);
    }
    bool operator >= (const BN &next) const//判大于等于
    {
        return !(*this<next);//不小于即为大于等于
    }
    template <typename _int>//不打了,判低精
    bool operator >= (const _int &_next) const
    {
        BN next;
        next.change(_next);
        return (*this>=next);
    }
    bool opeator ! () const//判是否为零
    {
        for(int LEN=LEN_SIZE-1;LEN!=-1;--LEN) if(a[LEN]) return false;//找到一位不为零,返回
        return true;//为零,返回
    }
    //终于写完了
    BN operator + (const BN &next) //高精度加法——模板  自己写的
    {
        if(!next) return *this;//一个数为0,返回另一个数
        if(!(*this)) return next;//同上
        BN temp;//返回变量在此
        temp.clear();//清空,避免神奇的事情发生
        if((next.is_nn&&is_nn)||(!next.is_nn&&!is_nn))//两数同号
        {
            if(is_nn) temp.is_nn=true;//如果其中一个数为负数,因为两数同号,另一个数一定为负数,判一个就够了
            BN A,B;//暂存用的变量A,B
            A.clear(),B.clear();//先清空,不急
            A.len=len,B.len=next.len;//取长度
            int Len=Max(len,next.len),_len=Min(len,next.len),LEN;//取出最大长度,最小长度,和位数
            for(int i=1,I=A.len;i<=A.len&&I;++i,--I) A.a[I]=a[i];//把高精数反向存储,方便进位
            for(int i=1,I=B.len;i<=B.len&&I;++i,--I) B.a[I]=next.a[i];//同上
            for(int i=1;i<=_len;++i)//加到最小长度
            {
                A.a[i]+=B.a[i];//加上对应的数,可能有进上的数,是加等于
                if(A.a[i]>=10) A.a[i]-=10,A.a[i+1]++;//如果大于10,就减去10,取个位,把下一位加1
            }
            for(int i=_len+1;i<=Len;++i)//把从最小长度到最大长度的位数补上
            {
                if(A.len<B.len) A.a[i]+=B.a[i];//如果下一个数大,加上位数
                if(A.a[i]>=10) A.a[i]-=10,A.a[i+1]++;//处理进位
            }
            for(LEN=LEN_SIZE-1;!A.a[LEN];--LEN);//从最后一位开始找,直到有不为零的数
            //因为是反序存储,0都在后面,倒叙找不会去末尾0,相当于去前导0
            temp.len=LEN;//结果的长度是这个值
            for(int i=LEN,I=1;I<=LEN&&i;++I,--i) temp.a[i]=A.a[I];//再把它反过来存进结果里
            return temp;//返回结果
        }
        else;//因为减法还没写,不处理两数异号的情况
        //目前只能处理同号运算,异号再说吧,会加进去的
    }
};

萌新第一次发布博客,请大佬多多指教

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值