Пример #1
0
//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;
}
Пример #2
0
bigint::bigvalue_t trim_zeros(bigint::bigvalue_t that){
   bigint::bigvalue_t result;
   
   bigint::bigvalue_t::reverse_iterator rit2 = that.rbegin();
   bigint::bigvalue_t::iterator it = result.begin();

   bool high_order = true;
   //int i = 0;

   while(rit2 != that.rend()){

      while(high_order){
         if(*rit2 != 0){
            high_order = false;
         } else{
            ++rit2;    
         }

         if (rit2 == that.rend()) break;
      }
      
      if (rit2 != that.rend()){
         it = result.insert(it, *rit2);
         it = result.begin();
         ++rit2;
      }
  
   }
   if (result.size() == 0){ 
      result.push_back(0);
      //result.negative = false;
   }
   return result;
}
bigint::bigvalue_t trim(bigint::bigvalue_t result) {
    for(auto it = result.rbegin(); it != result.rend()
            and *it == 0; ++it) {
        result.pop_back();
    }
    if(result.empty()) result.push_back(0);
    return result;
}
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);
}
Пример #5
0
bigint::bigvalue_t do_bigsub(const bigint::bigvalue_t& top,
      const bigint::bigvalue_t& bottom) {
   bigint::bigvalue_t diff{};
   auto itor_top = top.rbegin();
   auto itor_bottom = bottom.rbegin();

// use signed integers so we don't end up with -1 == 255
   int digit_top{0};
   int digit_bottom{0};
   int digit_diff{0};
   int borrow{0};

   while (itor_top != top.rend()) {
      digit_top = static_cast<int>(*itor_top++);
      if (itor_bottom  == bottom.rend()) {
         digit_bottom = 0;
      } else {
         digit_bottom = static_cast<int>(*itor_bottom++);
      }
      digit_top -= borrow;
      if (digit_top < digit_bottom) {
         borrow = 1;
         digit_top += 10;
      } else {
         borrow = 0;
      }
      digit_diff = digit_top - digit_bottom;
/*      cout << "do_bigsub():digit:"<< static_cast<unsigned>(digit_top);
      cout << " - " << static_cast<unsigned>(digit_bottom);
      cout << " = " << static_cast<unsigned>(digit_diff) << endl;*/
      diff.insert(diff.begin(), digit_diff);
   }
/*   cout << "do_bigsub(): ";
   for (auto i : top) cout << static_cast<unsigned>(i);
   cout << " - ";
   for (auto i : bottom) cout << static_cast<unsigned>(i);
   cout << " = ";
   for (auto i : diff) cout << static_cast<unsigned>(i);
   cout << endl;*/
   // Trim trailing zeros
   for (auto i : diff) {
      if (i == 0) diff.pop_back();
      else break;
   }
   return diff;
}
Пример #6
0
//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;
}
Пример #7
0
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;
}
Пример #8
0
bigint::bigvalue_t do_bigmult(const bigint::bigvalue_t& top,
      const bigint::bigvalue_t& bottom) {

   bigint::bigvalue_t product{};

   auto itor_bottom = bottom.rbegin();

   while (itor_bottom != bottom.rend()) {
      unsigned char carry {0};
      auto itor_top = top.rbegin();
      while (itor_top != top.rend()) {
         unsigned char digit = *itor_top++ * *itor_bottom++;
         digit += carry;
         product.insert(product.begin(), digit % 10);
         carry = digit / 10;
      }
   }
   return product;
}
Пример #9
0
bigint::bigvalue_t do_bigadd(const bigint::bigvalue_t& top,
      const bigint::bigvalue_t& bottom) {
   bigint::bigvalue_t sum{};        // return value
   bigint::digit_t digit_sum{0};    // digit marker
   bigint::digit_t digit_top{0};
   bigint::digit_t digit_bottom{0};
   bigint::digit_t carry{0};        // carryover marker

   // iterators
   auto itor_top = top.rbegin();
   auto itor_bottom = bottom.rbegin();

   while(itor_top != top.rend()) {
      digit_top = static_cast<unsigned>(*itor_top++);
      if (itor_bottom  == bottom.rend()) {
         digit_bottom = 0;
      } else {
         digit_bottom = static_cast<unsigned>(*itor_bottom++);
      }
      digit_sum = digit_bottom + digit_top + carry;
      if (digit_sum > 9) {
         carry = 1;
         digit_sum -= 10;
      } else {
         carry = 0;
      }
      sum.insert(sum.begin(), digit_sum);
   }
   cout << "do_bigadd(): ";
   for (auto i : top) cout << static_cast<unsigned>(i);
   cout << " + ";
   for (auto i : bottom) cout << static_cast<unsigned>(i);
   cout << " = ";
   for (auto i : sum) cout << static_cast<unsigned>(i);
   cout << endl;

   for (auto i : sum) {
      if (i == 0) sum.pop_back();
      else break;
   }
   return sum;
}
Пример #10
0
//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;

}
Пример #11
0
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;


}
Пример #12
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;
}
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;
}
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;
}