diff options
author | David Robillard <d@drobilla.net> | 2018-08-26 21:15:09 +0200 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2018-09-29 14:50:33 +0200 |
commit | d5522f58d508827c0db084b2102d73bbafe00255 (patch) | |
tree | 5c03c6be1989012098fbf77ccde9db5df980c2cc | |
parent | 7a7f6f69369a858f9022e44e7f1a8a30bff56c3e (diff) | |
download | chilbert-d5522f58d508827c0db084b2102d73bbafe00255.tar.gz chilbert-d5522f58d508827c0db084b2102d73bbafe00255.tar.bz2 chilbert-d5522f58d508827c0db084b2102d73bbafe00255.zip |
Rewrite left and right shift as single-pass algorithms
-rw-r--r-- | chilbert/detail/MultiBitVec.hpp | 56 |
1 files changed, 28 insertions, 28 deletions
diff --git a/chilbert/detail/MultiBitVec.hpp b/chilbert/detail/MultiBitVec.hpp index a184287..573deef 100644 --- a/chilbert/detail/MultiBitVec.hpp +++ b/chilbert/detail/MultiBitVec.hpp @@ -266,25 +266,25 @@ public: const Index index{bits}; - if (index.rack > 0) { - // Shift entire racks + if (index.bit == 0) { + // Simple rack-aligned shift for (size_t i = num_racks() - 1; i >= index.rack; --i) { rack(i) = rack(i - index.rack); } - for (size_t i = 0; i < index.rack; ++i) { - rack(i) = 0; + } else { + // Rack + bit offset shift + const size_t right_shift = bits_per_rack - index.bit; + for (size_t i = num_racks() - index.rack - 1; i > 0; --i) { + rack(i + index.rack) = + (rack(i) << index.bit) | (rack(i - 1) >> right_shift); } + + rack(index.rack) = rack(0) << index.bit; } - if (index.bit > 0) { - // Shift bits within racks - size_t bi = bits_per_rack - index.bit; - size_t i; - for (i = num_racks() - 1; i >= index.rack + 1; --i) { - rack(i) <<= index.bit; - rack(i) |= rack(i - 1) >> bi; - } - rack(i) <<= index.bit; + // Zero least significant racks + for (size_t i = 0; i < index.rack; ++i) { + rack(i) = 0; } return *self(); @@ -301,26 +301,26 @@ public: const Index index{bits}; - if (index.rack > 0) { - // Shift entire racks - size_t i; - for (i = 0; i < num_racks() - index.rack; ++i) { + if (index.bit == 0) { + // Simple rack-aligned shift + for (size_t i = 0; i < num_racks() - index.rack; ++i) { rack(i) = rack(i + index.rack); } - for (; i < num_racks(); ++i) { - rack(i) = 0; + } else { + // Rack + bit offset shift + const size_t last = num_racks() - 1; + const size_t left_shift = bits_per_rack - index.bit; + for (size_t i = index.rack; i < last; ++i) { + rack(i - index.rack) = + (rack(i) >> index.bit) | (rack(i + 1) << left_shift); } + + rack(last - index.rack) = rack(last) >> index.bit; } - if (index.bit > 0) { - // Shift bits within racks - size_t bi = bits_per_rack - index.bit; - size_t i; - for (i = 0; i < num_racks() - index.rack - 1; ++i) { - rack(i) >>= index.bit; - rack(i) |= rack(i + 1) << bi; - } - rack(i) >>= index.bit; + // Zero most significant racks + for (size_t i = num_racks() - index.rack; i < num_racks(); ++i) { + rack(i) = 0; } return *self(); |