1024位大数运算(二)

//求模运算(调用除法)
int BigInt::Mod(_int64 X)
{
         unsigned int M = 0;
         this->Div(X,&M);
         return M;
}
//比较两个大数的大小(只用于比较两个同号的大数)
bool BigInt::Comp(BigInt BI)
{
           if(this->m_bSign == P)  //先比较长度,再由高向低位依次比较
           {
                    if(this->m_nLength > BI.m_nLength)
                             return true;
                    else if(this->m_nLength < BI.m_nLength)
                             return false;
                    else
                    {
                             int i= this->m_nLength;
                             while(this->m_nValue[i] == BI.m_nValue[i])
                                       i--;
                            if(this->m_nValue[i] > BI.m_nValue[i])
                                       return true;
                            else
                                       return false;
                    }
           }
          else
          {
                    if(this->m_nLength > BI.m_nLength)
                             return false;
                    else if(this->m_nLength < BI.m_nLength)
                             return true;
                    else
                    {
                             int i= this->m_nLength;
                             while(this->m_nValue[i] == BI.m_nValue[i])
                                         i--;
                             if(this->m_nValue[i] > BI.m_nValue[i])
                                         return false;
                             else
                                         return true;
                    }
         }
}

//加法
BigInt BigInt::Add(BigInt addend)
{
         BigInt Sum;
         //如果两数符号不同,调用减法
         if(this->m_bSign != addend.m_bSign )
         {
                 if(this->m_bSign == N)
                 {
                         this->m_bSign = P;
                         Sum = addend.Sub(*this);
                         this->m_bSign = N;
                  }
                 else
                {
                          addend.m_bSign = P;
                          Sum = this->Sub(addend);
                          addend.m_bSign = N;
                 }
                 return Sum;
       }
       //符号相同
       Sum.m_bSign = this->m_bSign ;
       Sum.m_nLength = (this->m_nLength > addend.m_nLength) ? this->m_nLength : addend.m_nLength;

       _int64 km = 0;
       bool carry = 0;  //进位标识
       for(int i=0; i<Sum.m_nLength; i++)
       {
                km = this->m_nValue[i] + addend.m_nValue[i] + carry;
                if(km > UPPERBOUND - 1)  //有进位
                {
                           carry = 1;
                           Sum.m_nValue[i] = km - UPPERBOUND;
                 }
                 else
                {
                            carry = 0;
                            Sum.m_nValue[i] = km;
                 }
  
       }
       if(carry)  //如果仍有进位,和的长度加一,并置一
       {
                Sum.m_nValue[i] = carry;
                Sum.m_nLength ++;
                if(Sum.m_nLength > MAXLENGTH)
                            cerr<<"overflow in add function!"<<endl;
       }
       return Sum;

}

//大数与32位无符号整型相加
void BigInt::Add(unsigned int addend)
{
         int  carry = 0;//进位标识
         _int64 km    = 0;
         km = this->m_nValue[0] + addend;
         if(km > UPPERBOUND - 1)//有进位
         {
                  carry = 1;
                  this->m_nValue[0] = km - UPPERBOUND;
         }
         else
         {
                   carry = 0;
                    this->m_nValue[0] = km;
                    return ;
         }
         //仍有进位,继续进行进位加
         for(int i=1; i < this->m_nLength && carry; i++)
         {
                    km = this->m_nValue[i] + carry;
                    if(km > UPPERBOUND - 1)
                    {
                             carry = 1;
                             this->m_nValue[0] = km - UPPERBOUND;
                     }
                     else
                     {
                             carry = 0;
                             this->m_nValue[0] = km;
                     }
         }
         if(carry)
         {
                  this->m_nValue[i] = carry;
                  this->m_nLength ++;
                  if(this->m_nLength > MAXLENGTH)
                              cout<<"overflow!"<<endl;
         }
}

BigInt BigInt::Sub(BigInt subtra)
{
        BigInt Diff;  //差
        //若符号不同调用加法函数
        if(this->m_bSign != subtra.m_bSign )
        {
                if(this->m_bSign == P)
                {
                        subtra.m_bSign = P;
                        Diff = this->Add(subtra);
                        subtra.m_bSign = N;
                }
                else
                {
                         subtra.m_bSign = N;
                         Diff = this->Add(subtra);
                         subtra.m_bSign = P;
                }
                return Diff;
       }
 
 
        if(this->Comp(subtra))  //被减数大于减数
        {
                 if(this->m_bSign == P) //同为正号
                 {
                         Diff.m_nLength = this->m_nLength;
                         _int64 km;
                         int carry = 0;
                         for(int i=0;i<Diff.m_nLength; i++)
                         {
                               //预先借位减
                              km = UPPERBOUND + this->m_nValue[i] - subtra.m_nValue[i] - carry;
                               if(km >= UPPERBOUND)  //不需要借位
                               {
                                    carry  = 0;
                                    km = km - UPPERBOUND; //将借来的再减去
                                }
                                else
                                         carry = 1;
                                Diff.m_nValue[i] = km; 
                         }
                 }
                 else  //同为负号,将被减数很减数都设置为正数,调用减法
                 {
                         this->m_bSign  = P;
                         subtra.m_bSign = P;
                         Diff = subtra.Sub(*this);  //减数减被减数
                         this->m_bSign = N;
                         subtra.m_bSign = N;
                 }
                 Diff.m_bSign = P;
          }
          else
          {
                  if(this->m_bSign == P)
                   {
                           Diff = subtra.Sub(*this);
                   }
                  else
                  {
                           this->m_bSign  = P;
                           subtra.m_bSign = P;
                           Diff = this->Sub(subtra);
                           this->m_bSign = N;
                           subtra.m_bSign = N;
                 }
                 Diff.m_bSign = N;
         }
 
        return Diff;
 
}

//大数乘法

BigInt BigInt::Mul(BigInt multiplier)
{
        BigInt Product;
        if(this->m_bSign == multiplier.m_bSign )
                 Product.m_bSign = P;
        else
                 Product.m_bSign = N;
        int i = multiplier.m_nLength - 1;
 //由乘数的高位开始乘,先将部分积移位(乘10),然后和乘数第i位与被乘数的积相加
        while(i>=0)
        {
               Product = Product.Mul(UPPERBOUND);
               Product = Product.Add(Mul(multiplier.m_nValue[i]));
               i--;
        }
        //积可达到的最长的位数
        Product.m_nLength = this->m_nLength + multiplier.m_nLength;
        if(Product.m_nValue[Product.m_nLength-1] == 0)
                  Product.m_nLength --;
        return Product;

}
//大数与64位无符号整型相乘(实际达不到64位)
BigInt BigInt::Mul(_int64 multiplier)
{
         BigInt Product;
         _int64 km;
         unsigned int carry = 0;  //进位
         Product.m_bSign = this->m_bSign;
         for(int i=0; i<this->m_nLength; i++)
         {
                 km = this->m_nValue[i] * multiplier + carry;
                 Product.m_nValue[i] = km % UPPERBOUND;  
                 carry = km /UPPERBOUND;
         }
         if(carry)
         {
                  Product.m_nValue[i] = carry;
                  Product.m_nLength = this->m_nLength + 1;
         }
         else
          {
                  Product.m_nLength = this->m_nLength;
          }
         return Product;

}
//除法
BigInt BigInt::Div(unsigned int X,unsigned int *M )
{
         BigInt result;
         result.m_nLength = this->m_nLength;
         result.m_bSign = this->m_bSign ;
         _int64 km = 0;
         //按竖式除法即可,km为上一位除得的余数
         for(int i=this->m_nLength-1; i>=0; i--)
         {  
                result.m_nValue[i] = (this->m_nValue[i]+km*UPPERBOUND)/X;
                km = (this->m_nValue[i]+km*UPPERBOUND)%X;
         }

        if( (result.m_nLength != 1) && (result.m_nValue[result.m_nLength-1] == 0) )
                 result.m_nLength --;
        if(this->m_bSign == N)
                km = 10 - km;
        if(M != NULL)
               *M = km;
        return result;
}
//幂的计算
BigInt BigInt::Power(BigInt index)
{

         BigInt Product;
         bool Sign = P;
         int k = 0;
         unsigned int M = 0;
         char* str = new char[index.m_nLength*8*4];//用来存放指数的二进制序列


         if(index.m_bSign == N)
         {
                  cerr<<"指数不可为负!"<<endl;
                  return Product;
         }
         if(this->EqulZero()&&index.EqulZero())
         {
                  cerr<<"底数和指数不可同时为零!"<<endl;
                  return Product;
         }

        if(index.Mod(2) == 1)  //指数为奇数
                  Sign = this->m_bSign;

         while( !index.EqulZero() )
         {
                index = index.Div(2,&M);
                str[k] = '0' + M;
                k++;
          }
         str[k] = '/0';
         k--;
         //下面是根据一个通用的求幂的快速算法
         if(str[k--] == '1')
                  Product.Set(*this);
         else 
                  Product.Set(1);
         for(int i= k; i>=0; i--)
         {
                  Product = Product.Mul(Product);
                  if(str[i] == '1')
                           Product = Product.Mul(*this);
         }
         Product.m_bSign = Sign;
         delete []str;
         return Product;
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值