示例#1
0
BigInt operator /(const BigInt& l, const BigInt& r)
{
	int carry_sign = l.sign * r.sign;
	BigInt result = l.abs();
	BigInt rr = r.abs();

	result /= rr;

	if ( result.size() > 1 )
	{
		result.sign = carry_sign;
	}
	
	return result;
}
BigInt BigInt::operator -(const BigInt& right) const
{
    BigInt left = *this;
    if (left.sign != right.sign)
    {
        return left - (-right);
    }

    if (this->abs() >= right.abs())
    {
        BigInt res = left;
        int carry = 0;

        for (int i = 0; i < right.number.size() || carry; ++i)
        {
            res.number[i] -= carry + (i < right.number.size() ? right.number[i] : 0);
            carry = res.number[i] < 0;

            if (carry)
            {
                res.number[i] += BigInt::base;
            }
        }
        res.RemoveZero();
        return res;
    }
    else
    {
        return -(right - left);
    }
}
示例#3
0
void BigInt::operator +=(BigInt num)
{
    if (_sign == SIGN_POSITIVE && num._sign == SIGN_NEGATIVE){
        return (*this) -= num.abs();
    }
    if (_sign == SIGN_NEGATIVE && num._sign  == SIGN_POSITIVE){
        (*this) = num - (*this).abs();
        return;
    }
    BigInt num1 = getLength() >= num.getLength() ? (*this) : num;
    BigInt num2 = getLength() >= num.getLength() ? num : (*this);
    int carry = 0;
    for (auto digit = num1._number.rbegin(); digit != num1._number.rend(); ++digit){
        if (num2.getLength() > 0){
            (*digit) += num2._number.back();
            num2._number.pop_back();
        }
        (*digit) += carry;
        carry = 0;
        if (*digit >= 10){
            (*digit) -= 10;
            if (digit == (num1._number.rend() - 1)){
                num1._number.push_front(1);
            } else {
                carry = 1;
            }
        }
    }
    (*this) = num1;
}
示例#4
0
 static BigInt gcd(const BigInt &a, const BigInt &b)
 {
     const BigInt zero("0");
     BigInt big, small, tmp;
     BigInt absnum1_=a.abs();
     BigInt absnum2_=b.abs();
     big=max(absnum1_, absnum2_);
     small=min(absnum1_,absnum2_);
     tmp=big%small;
     while(tmp!=zero)
     {
         big=small;
         small=tmp;
         tmp=big%small;
     }
     return small;
 }
示例#5
0
void BigInt::operator /=(BigInt num)
{
    if (num == (*this)){
        (*this) = 1;
        return;
    }
    if (2 * num.abs() > abs()){
        (*this) = 0;
        return;
    }

    BigInt result = 0;
    BigInt currentDivident;
    BigInt partialResult;

    for (auto digit = _number.cbegin(); digit != _number.cend(); ++digit){
        currentDivident._number.push_back(*digit);
        currentDivident._lTrim();
        if (currentDivident < num){
            continue;
        }
        for (int i = 1; i < 10; i++){
            if (num * i >= currentDivident){
                result._lTrim();
                result._number.push_back(--i);
                currentDivident -= (i * num);
                break;
            }
        }
        std::cout << (std::string)currentDivident<<std::endl;
    }



    result._lTrim();
    (*this) = result;

}
示例#6
0
void BigInt::operator -=(BigInt num)
{
    if (num._sign == SIGN_NEGATIVE){
        return (*this) += num.abs();
    }
    if (_sign == SIGN_NEGATIVE){
        *this = (*this).abs() + num;
        (*this)._sign = SIGN_NEGATIVE;
        return;
    }
    BigInt minuent = (*this) >= num ? (*this) : num;
    BigInt subtrahend = (*this) >= num ? num : (*this);
    int carry = 0;
    for (auto digit = minuent._number.rbegin(); digit != minuent._number.rend(); ++digit){
        if (subtrahend.getLength() > 0){
            (*digit) -= subtrahend._number.back();
            subtrahend._number.pop_back();
        }
        (*digit) -= carry;
        carry = 0;
        if (*digit < 0){
            if (digit != minuent._number.rbegin() - 1){
                (*digit) += 10;
                carry = 1;
            } else {
                (*digit) *= -1;
                minuent._sign = SIGN_NEGATIVE;
            }
        }
    }
    bool negative = (*this) < num;
    (*this) = minuent.copy();
    if (negative && (*this) != 0){
        _sign = SIGN_NEGATIVE;
    }
    _lTrim();
}
示例#7
0
PointGFp operator*(const BigInt& scalar, const PointGFp& point)
   {
   const CurveGFp& curve = point.get_curve();

   if(scalar.is_zero())
      return PointGFp(curve); // zero point

   std::vector<BigInt> ws(9);

   if(scalar.abs() <= 2) // special cases for small values
      {
      byte value = scalar.abs().byte_at(0);

      PointGFp result = point;

      if(value == 2)
         result.mult2(ws);

      if(scalar.is_negative())
         result.negate();

      return result;
      }

   const size_t scalar_bits = scalar.bits();

#if 0

   PointGFp x1 = PointGFp(curve);
   PointGFp x2 = point;

   size_t bits_left = scalar_bits;

   // Montgomery Ladder
   while(bits_left)
      {
      const bool bit_set = scalar.get_bit(bits_left - 1);

      if(bit_set)
         {
         x1.add(x2, ws);
         x2.mult2(ws);
         }
      else
         {
         x2.add(x1, ws);
         x1.mult2(ws);
         }

      --bits_left;
      }

   if(scalar.is_negative())
      x1.negate();

   return x1;

#else
   const size_t window_size = 4;

   std::vector<PointGFp> Ps(1 << window_size);
   Ps[0] = PointGFp(curve);
   Ps[1] = point;

   for(size_t i = 2; i != Ps.size(); ++i)
      {
      Ps[i] = Ps[i-1];
      Ps[i].add(point, ws);
      }

   PointGFp H(curve); // create as zero
   size_t bits_left = scalar_bits;

   while(bits_left >= window_size)
      {
      for(size_t i = 0; i != window_size; ++i)
         H.mult2(ws);

      const u32bit nibble = scalar.get_substring(bits_left - window_size,
                                                 window_size);

      H.add(Ps[nibble], ws);

      bits_left -= window_size;
      }

   while(bits_left)
      {
      H.mult2(ws);
      if(scalar.get_bit(bits_left-1))
         H.add(point, ws);

      --bits_left;
      }

   if(scalar.is_negative())
      H.negate();

   return H;
#endif
   }