diff options
author | Olivier Gayot <og@satcom1.com> | 2017-11-19 13:13:21 +0100 |
---|---|---|
committer | Olivier Gayot <og@satcom1.com> | 2017-11-25 18:10:56 +0100 |
commit | 049402e53bd0e0fb1f589366102b4e938dffa3b8 (patch) | |
tree | 46d9e2bb17c97dc82dadd74ddf4391c676a5496d /number.cpp | |
parent | ef6b1c0dd80a7b37161557aef49d01724f7f7531 (diff) |
Added the right-shift computation
Signed-off-by: Olivier Gayot <og@satcom1.com>
Diffstat (limited to 'number.cpp')
-rw-r--r-- | number.cpp | 52 |
1 files changed, 52 insertions, 0 deletions
@@ -184,6 +184,42 @@ number::operator<<(std::uint32_t shift) const return result; } +number +number::operator>>(std::uint32_t shift) const +{ + number result(*this); + + /* + * Since, internally, we store 32-bits-wide integers, we can just get rid + * of "shift / 32" first integers. + */ + for (unsigned int i = 0; i < shift / 32; ++i) { + if (result == 0) { + return 0; + } + + result._operands.pop_front(); + } + + shift %= 32; + + std::uint32_t carry = 0; + + for (auto it = result._operands.rbegin(); it != result._operands.rend(); ++it) { + auto &operand = *it; + + std::uint32_t tmp = ((1ull * operand) >> shift) | carry; + + carry = ((1ull * operand) << (32 - shift)); + + operand = tmp; + } + + result.shrink_to_fit(); + + return result; +} + /* }}} */ /* Comparison operators {{{ */ @@ -266,6 +302,14 @@ number::operator<<=(std::uint32_t n) } number & +number::operator>>=(std::uint32_t n) +{ + *this = *this >> n; + + return *this; +} + +number & number::operator++() { *this = *this + 1; @@ -275,6 +319,14 @@ number::operator++() /* }}} */ +void +number::shrink_to_fit() +{ + while (_operands.back() == 0) { + _operands.pop_back(); + } +} + std::ostream & operator<<(std::ostream &os, const number &n) { |