aboutsummaryrefslogtreecommitdiffstats
path: root/chilbert
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2018-08-26 21:15:09 +0200
committerDavid Robillard <d@drobilla.net>2018-09-29 14:50:33 +0200
commitd5522f58d508827c0db084b2102d73bbafe00255 (patch)
tree5c03c6be1989012098fbf77ccde9db5df980c2cc /chilbert
parent7a7f6f69369a858f9022e44e7f1a8a30bff56c3e (diff)
downloadchilbert-d5522f58d508827c0db084b2102d73bbafe00255.tar.gz
chilbert-d5522f58d508827c0db084b2102d73bbafe00255.tar.bz2
chilbert-d5522f58d508827c0db084b2102d73bbafe00255.zip
Rewrite left and right shift as single-pass algorithms
Diffstat (limited to 'chilbert')
-rw-r--r--chilbert/detail/MultiBitVec.hpp56
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();