//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 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); }
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; }
//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; }
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; }
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; }
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; }
//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 (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; }
// // 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; }