//returns true if left is > right, false if left <= right
bool do_bigless
   (const bigint::bigvalue_t left, const bigint::bigvalue_t right){


   if (left.size() > right.size()) 
      return true;
   else if(left.size() < right.size())
      return false;

   bigint::bigvalue_t::const_reverse_iterator
                       left_digit = left.rbegin();
   bigint::bigvalue_t::const_reverse_iterator
                       right_digit = right.rbegin();
 
   bool abs_val_greatest = false;
   while (left_digit != left.rend()){

      if (*left_digit > *right_digit){
         return true;
      } else if (*left_digit < *right_digit){
         break;  
      }        
      ++left_digit;
      ++right_digit;
   }
   return abs_val_greatest;
}
//works like doing multiplication by hand if
//left was the int on top and right was the int on bottom
bigint::bigvalue_t do_bigmult
   (bigint::bigvalue_t left, bigint::bigvalue_t right){

   bigint::bigvalue_t result;
   bigint::bigvalue_t number;

   //outer loop
   for (unsigned int right_i = 0; right_i < right.size(); ++right_i){

     
      number.clear();
      int carry = 0;
      
      //innter loop
      for(unsigned int left_j = 0; left_j < left.size(); ++left_j){
         
         //append zero's if necessary
         if(left_j == 0){
            for (unsigned int k = 0; k < right_i; ++k)
               number.push_back(0);
         }

         int product = (right[right_i]*left[left_j]) + carry;
         carry = product/10;  
         int digit = product - (carry * 10);
         number.push_back(digit);

         if(left_j == left.size() - 1 and carry != 0)
            number.push_back(carry);
      }
      
      result = do_bigadd(result, number);
   }
   return result;
}
bigint::bigvalue_t do_bigadd
      (bigint::bigvalue_t v1, bigint::bigvalue_t v2){

   //do_mult may pass in empty vectors as args
   if(v1.size() == 0) v1.push_back(0);
   if(v2.size() == 0) v2.push_back(0);

   char carry = 0;
   bigint::bigvalue_t v3;
   bool done1 = false;
   bool done2 = false;
   for (size_t i = 0; ; ++i) {
      char digit1, digit2;
      if (i < v1.size()) { digit1 = v1[i]; }
                    else { digit1 = 0; done1 = true; }
      if (i < v2.size()) { digit2 = v2[i]; }
                    else { digit2 = 0; done2 = true; }
      if (done1 && done2) break;
      char sum = digit1 + digit2 + carry;
      v3.push_back (sum % 10);
      carry = sum / 10;
   }
   if (carry != 0) v3.push_back (carry);
   return v3;


}
void divide_by_2 (bigint::bigvalue_t& div_by) {
    //int data = 0;      begin/rend 000001 end/rbegin == 100000
    for(unsigned it = 0; it < div_by.size(); ++it) {

        // Divide the value at index it by 2
        div_by.at(it) /= 2;
        // If the next higher digit is odd, add 5 to current digit
        if(it < div_by.size() - 1) {
            if(div_by.at(it + 1) % 2) {
                div_by.at(it) += 5;
            }
        }
    }
    div_by = trim(div_by);
}
bigint::bigvalue_t divide_by_2(bigint::bigvalue_t that){

   //bigint::bigvalue_t::iterator
    
   bigint::bigvalue_t fresh;

   for(size_t i = 0; i < that.size(); ++i){
   
      unsigned char digit = that[i];      
      
      if (i != that.size() -1){
         if(that[i+1]%2 == 1) digit += 5; 
      } else digit += 5;
       
      fresh.push_back(digit);
   }

   return fresh;
}
//left - right
bigint::bigvalue_t do_bigsub
   (bigint::bigvalue_t left, bigint::bigvalue_t right){
   
   //char carry = 0;
   bigint::bigvalue_t v3;
   bool done1 = false;
   bool done2 = false;
   bool borrow = false;

   
   for (size_t i = 0; ; ++i) {
      char left_digit, right_digit;


      if (i < left.size()) { left_digit = left[i]; }
                    else { left_digit = 0; done1 = true; }
      if (i < right.size()) { right_digit = right[i]; }
                    else { right_digit = 0; done2 = true; }


      if (done1 && done2) break;
      
      if (borrow){
        left_digit = left_digit - 1;
        borrow = false;
      }

      if(left_digit < right_digit){
         borrow = true;
         char sum = ( (left_digit + 10) - right_digit);
         v3.push_back(sum);
      } else {
         char sum = left_digit - right_digit;
         v3.push_back(sum);
      } 
      
   }

   return v3;

}
bigint::bigvalue_t do_bigadd(const bigint::bigvalue_t& left,
                             const bigint::bigvalue_t& right) {
    bigint::bigvalue_t sum;
    int carry = 0;
    bool left_empty = false;
    bool right_empty = false;
    auto left_it = left.begin();
    //bigint::bigvalue_t::const_reverse_iterator left_it = left.rbegin();
    auto right_it = right.begin();
    auto left_end = left.end();
    auto right_end = right.end();
    if(left.size() == 0) {
        left_empty = true;
    }
    if(right.size() == 0) {
        right_empty = true;
    }
    while(true) {
        int curr_value = (left_empty?0:*left_it) +
                         (right_empty?0:*right_it) + carry;
        carry = 0;
        if(curr_value >= 10) {
            carry = 1;
            curr_value -= 10;
        }
        sum.push_back(curr_value);
        if(++left_it == left_end) {
            left_empty = true;
        }
        if(++right_it == right_end) {
            right_empty = true;
        }
        if(left_empty and right_empty) {
            if(carry == 1) {
                sum.push_back(carry);
            }
            break;
        }
    }
    return sum;
}
bigint::bigvalue_t do_bigsub(const bigint::bigvalue_t& left,
                             const bigint::bigvalue_t& right) {
    bigint::bigvalue_t sum;
    int carry = 0;
    bool left_empty = false;
    bool right_empty = false;
    auto left_it = left.begin();
    //bigint::bigvalue_t::const_reverse_iterator left_it = left.rbegin();
    auto right_it = right.begin();
    auto left_end = left.end();
    auto right_end = right.end();
    if(left.size() == 0) {
        left_empty = true;
    }
    if(right.size() == 0) {
        right_empty = true;
    }
    while(true) {
        int curr_value = (left_empty?0:*left_it) -
                         (right_empty?0:*right_it) + carry;
        carry = 0;
        if(curr_value < 0 and !left_empty) {
            carry = -1;
            curr_value += 10;
        }
        sum.push_back(curr_value);
        if(++left_it == left_end) {
            left_empty = true;
        }
        if(++right_it == right_end) {
            right_empty = true;
        }
        if(left_empty and right_empty) {
            break;
        }
    }
    //remove leading 0s
    sum = trim(sum);
    return sum;
}
bigint::bigvalue_t do_bigmult(const bigint::bigvalue_t& left,
                              const bigint::bigvalue_t& right) {
    bigint::bigvalue_t prod;
    prod.resize(left.size() + right.size());
    int carry = 0;
    int d = 0;
    int uv = 0;

    for(unsigned i = 0; i != left.size(); ++i) {
        carry = 0;
        for(unsigned j = 0; j != right.size(); ++j) {
            uv = left.at(i) * right.at(j);
            d = prod.at(i + j) + uv + carry;
            prod.at(i + j) = d % 10;
            carry = d/10;
        }
        if(carry != 0) {
            prod.at(right.size() + i) = carry;
        }
    }
    prod = trim(prod);
    return prod;
}
Beispiel #10
0
//
// do_bigless()
// returns true if left < right
// returns false if left > right or left == right
//
bool do_bigless (const bigint::bigvalue_t& left,
      const bigint::bigvalue_t& right) {
   if (left.size() < right.size()) {
      return true;
   } else if (left.size() > right.size()) {
      return false;
   }

   auto itor_left = left.begin();
   auto itor_right = right.begin();

   while(itor_left != left.end() && itor_right != right.end()) {
      if (itor_left > itor_left) {
         return false;
      } else if (itor_left < itor_right) {
         return true;
      } else {
         itor_left++;
         itor_right++;
      }
   }
   return true;
}