Reputation: 8570
The following code will take 4-bit "nibbles" and swap them:
inline void swap(uint64_t& v, int pos1, int pos2) {
pos1 <<= 2; pos2 <<= 2;
uint64_t t1 = v & (0xFLL << pos1);
uint64_t t2 = v & (0xFLL << pos2);
cout << hex << t1 <<',' << t2 << '\n';
v &= ~(t1 | t2);
int deltaBitPos = pos1 - pos2;
if (deltaBitPos > 0) {
t2 <<= deltaBitPos;
t1 >>= deltaBitPos;
} else {
deltaBitPos = -deltaBitPos;
t2 >>= deltaBitPos;
t1 <<= deltaBitPos;
}
v |= (t1 | t2);
}
For example:
uint64_t v = 0x123456789LL;
swap(v, 0, 1)
will result in v = 0x123456798
But is there a faster way with some bitwise primitive functions? I can't find any that will do it, either the gcc builtins, or on bithacks:
https://graphics.stanford.edu/~seander/bithacks.html
Upvotes: 2
Views: 108
Reputation: 59358
It's not bad, but I would get rid of the conditional and simplify a bit:
inline void swap(uint64_t& v, int pos1, int pos2) {
pos1 <<= 2; pos2 <<= 2;
uint64_t ret = v&~((0xFLL << pos1)|(0xFLL << pos2));
ret|=((v>>pos1)&15)<<pos2;
ret|=((v>>pos2)&15)<<pos1;
v = ret;
}
Upvotes: 4