summaryrefslogtreecommitdiff
path: root/number.cpp
diff options
context:
space:
mode:
authorOlivier Gayot <og@satcom1.com>2017-11-19 13:13:21 +0100
committerOlivier Gayot <og@satcom1.com>2017-11-25 18:10:56 +0100
commit049402e53bd0e0fb1f589366102b4e938dffa3b8 (patch)
tree46d9e2bb17c97dc82dadd74ddf4391c676a5496d /number.cpp
parentef6b1c0dd80a7b37161557aef49d01724f7f7531 (diff)
Added the right-shift computation
Signed-off-by: Olivier Gayot <og@satcom1.com>
Diffstat (limited to 'number.cpp')
-rw-r--r--number.cpp52
1 files changed, 52 insertions, 0 deletions
diff --git a/number.cpp b/number.cpp
index c3dd33c..75fd0f8 100644
--- a/number.cpp
+++ b/number.cpp
@@ -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)
{