beefviper

better total(), 7th draft

Sep 7th, 2018
141
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.  
  5.     // building number from scratch,
  6.     // clear default 0s from integer and fraction vector
  7.     sum.integer.clear();
  8.     sum.fraction.clear();
  9.  
  10.     // find the length of the non-overlapping part
  11.     auto fracOffset = std::abs((int)_augend.fraction.size() - (int)_addend.fraction.size());
  12.  
  13.     if (fracOffset) {
  14.         // find the number with more digits in its fraction part
  15.         auto fracExtra = (_augend.fraction.size() > _addend.fraction.size()) ?
  16.             _augend.fraction.rbegin() : _addend.fraction.rbegin();
  17.  
  18.         // use difference to resize result vector
  19.         sum.fraction.resize(fracOffset);
  20.  
  21.         // then copy that chunk to the answer
  22.         std::copy(fracExtra, fracExtra + fracOffset, sum.fraction.begin());
  23.     }
  24.  
  25.     int carry = 0;
  26.     int numbase = _augend.base;
  27.  
  28.     // add overlapping fraction part
  29.     carry = _sumDigits(_augend.fraction, _addend.fraction, sum.fraction, fracOffset, carry, numbase);
  30.  
  31.     // add integer part
  32.     carry = _sumDigits(_augend.integer, _addend.integer, sum.integer, 0, carry, numbase);
  33.  
  34.     // add final carry, if needed
  35.     if (carry == 1) {
  36.         sum.integer.push_back(1);
  37.     }
  38.  
  39.     // and reverse vectors to proper order
  40.     std::reverse(sum.integer.begin(), sum.integer.end());
  41.     std::reverse(sum.fraction.begin(), sum.fraction.end());
  42.  
  43.     return sum;
  44. }
  45.  
  46. /* sum digits */
  47. int BigNum::_sumDigits(const std::vector<int>& _numOne, const std::vector<int>& _numTwo,
  48.     std::vector<int>& _result, int _offset, int _carry, int _numbase) {
  49.  
  50.     auto augIt = _numOne.rbegin(); // grab reverse iterators
  51.     auto addIt = _numTwo.rbegin();
  52.  
  53.     if (_offset != 0) {
  54.         if (_numOne.size() > _numTwo.size()) { // apply offset to longer fraction part
  55.             augIt += _offset;
  56.         }
  57.         else if (_numOne.size() < _numTwo.size()) {
  58.             addIt += _offset;
  59.         }
  60.     }
  61.  
  62.     int carry = _carry;
  63.     int tempSum = 0;
  64.  
  65.     while (augIt != _numOne.rend() || addIt != _numTwo.rend()) { // loop until both at end
  66.         tempSum = 0;
  67.  
  68.         if (augIt != _numOne.rend()) {
  69.             tempSum += *augIt; augIt++;
  70.         }
  71.         if (addIt != _numTwo.rend()) {
  72.             tempSum += *addIt; addIt++;
  73.         }
  74.  
  75.         tempSum += carry;
  76.  
  77.         carry = 0;
  78.  
  79.         if (tempSum > (_numbase - 1)) {
  80.             tempSum -= _numbase;
  81.             carry = 1;
  82.         }
  83.  
  84.         _result.push_back(tempSum);
  85.     }
  86.  
  87.     return carry;
  88. }
RAW Paste Data