beefviper

better total(), 6th draft

Sep 5th, 2018
148
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /* total */
  2. BigNum BigNum::_total(const BigNum& _augend, const BigNum& _addend) {
  3.     BigNum sum;
  4.     sum.integer.clear();
  5.     sum.fraction.clear();
  6.  
  7.     const int numbase = _augend.base;
  8.     int carry = 0;
  9.  
  10.     // copy extra part of longer fraction
  11.     auto fracOffset = std::abs((int)_augend.fraction.size() - (int)_addend.fraction.size());
  12.     auto fracExtra = (_augend.fraction.size() > _addend.fraction.size()) ?
  13.         _augend.fraction.rbegin() : _addend.fraction.rbegin();
  14.  
  15.     sum.fraction.resize(fracOffset);
  16.  
  17.     std::copy(fracExtra, fracExtra + fracOffset, sum.fraction.begin());
  18.  
  19.     // add overlapping fraction part
  20.     carry = _sumDigit(_augend.fraction, _addend.fraction, sum.fraction, fracOffset, carry, numbase);
  21.  
  22.     // add integer part
  23.     carry = _sumDigit(_augend.integer, _addend.integer, sum.integer, 0, carry, numbase);
  24.  
  25.     // add final carry, if needed
  26.     if (carry == 1) {
  27.         sum.integer.push_back(1);
  28.     }
  29.  
  30.     // if changing _sumDigit() to only do over lapping parts
  31.     // don't forget to copy the extra part of the longer integer part
  32.  
  33.  
  34.     // and reverse vectors to proper order
  35.     std::reverse(sum.integer.begin(), sum.integer.end());
  36.     std::reverse(sum.fraction.begin(), sum.fraction.end());
  37.  
  38.     return sum;
  39. }
  40.  
  41. /* sumDigit */
  42. int BigNum::_sumDigit(const std::vector<int>& _numOne, const std::vector<int>& _numTwo,
  43.     std::vector<int>& _result, int _offset, int _carry, int _numbase) {
  44.  
  45.     auto augIt = _numOne.rbegin();
  46.     auto addIt = _numTwo.rbegin();
  47.  
  48.     if (_numOne.size() > _numTwo.size()) {
  49.         augIt += _offset;
  50.     }
  51.     else if (_numTwo.size() > _numOne.size()) {
  52.         addIt += _offset;
  53.     }
  54.  
  55.     int carry = _carry;
  56.     int tempSum = 0;
  57.  
  58.     while (augIt != _numOne.rend() || addIt != _numTwo.rend()) {
  59.         tempSum = 0;
  60.  
  61.         if (augIt != _numOne.rend()) {
  62.             tempSum += *augIt; augIt++;
  63.         }
  64.         if (addIt != _numTwo.rend()) {
  65.             tempSum += *addIt; addIt++;
  66.         }
  67.  
  68.         tempSum += carry;
  69.         carry = 0;
  70.  
  71.         if (tempSum > (_numbase - 1)) {
  72.             tempSum -= _numbase;
  73.             carry = 1;
  74.         }
  75.  
  76.         _result.push_back(tempSum);
  77.  
  78.         // could test for (augIt end() || addIt end()) && carry = 0
  79.         // and copy extra part of longer integer part in _total()
  80.     }
  81.  
  82.     return carry;
  83. }
RAW Paste Data