bitwise: add rotater
This commit is contained in:
parent
fc935863ef
commit
028dee034a
17
bitwise.hpp
17
bitwise.hpp
@ -33,13 +33,24 @@ const uint8_t BITMASK_6BITS = 0x3F;
|
|||||||
const uint8_t BITMASK_7BITS = 0x7F;
|
const uint8_t BITMASK_7BITS = 0x7F;
|
||||||
const uint8_t BITMASK_8BITS = 0xFF;
|
const uint8_t BITMASK_8BITS = 0xFF;
|
||||||
|
|
||||||
|
#define MODT(x) ((x) % (sizeof (T) * 8))
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T
|
constexpr T
|
||||||
rotatel (const T &value, size_t magnitude) {
|
rotatel (const T &value, size_t magnitude) {
|
||||||
magnitude %= sizeof (T) * 8;
|
return (value << MODT (magnitude)) |
|
||||||
return (value << magnitude) | (value >> sizeof (value) * 8 - magnitude);
|
(value >> sizeof (value) * 8 - MODT (magnitude));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
constexpr T
|
||||||
|
rotater (const T &value, size_t magnitude) {
|
||||||
|
return (value >> MODT (magnitude)) |
|
||||||
|
(value << sizeof (value) * 8 - MODT (magnitude));
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef MODT
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -7,15 +7,28 @@ main (int, char**) {
|
|||||||
CHECK_EQ (rotatel (uint8_t (0xF0), 4), 0x0F);
|
CHECK_EQ (rotatel (uint8_t (0xF0), 4), 0x0F);
|
||||||
CHECK_EQ (rotatel (uint8_t (0x0F), 8), 0x0F);
|
CHECK_EQ (rotatel (uint8_t (0x0F), 8), 0x0F);
|
||||||
|
|
||||||
|
CHECK_EQ (rotater (uint8_t (0x0F), 0), 0x0F);
|
||||||
|
CHECK_EQ (rotater (uint8_t (0x0F), 4), 0xF0);
|
||||||
|
CHECK_EQ (rotater (uint8_t (0xF0), 4), 0x0F);
|
||||||
|
CHECK_EQ (rotater (uint8_t (0x0F), 8), 0x0F);
|
||||||
|
|
||||||
CHECK_EQ (rotatel (uint16_t (0xABCD), 0), 0xABCD);
|
CHECK_EQ (rotatel (uint16_t (0xABCD), 0), 0xABCD);
|
||||||
CHECK_EQ (rotatel (uint16_t (0xABCD), 4), 0xBCDA);
|
CHECK_EQ (rotatel (uint16_t (0xABCD), 4), 0xBCDA);
|
||||||
CHECK_EQ (rotatel (uint16_t (0xABCD), 8), 0xCDAB);
|
CHECK_EQ (rotatel (uint16_t (0xABCD), 8), 0xCDAB);
|
||||||
CHECK_EQ (rotatel (uint16_t (0xABCD), 12), 0xDABC);
|
CHECK_EQ (rotatel (uint16_t (0xABCD), 12), 0xDABC);
|
||||||
CHECK_EQ (rotatel (uint16_t (0xABCD), 16), 0xABCD);
|
CHECK_EQ (rotatel (uint16_t (0xABCD), 16), 0xABCD);
|
||||||
|
|
||||||
|
CHECK_EQ (rotater (uint16_t (0xABCD), 0), 0xABCD);
|
||||||
|
CHECK_EQ (rotater (uint16_t (0xABCD), 4), 0xDABC);
|
||||||
|
CHECK_EQ (rotater (uint16_t (0xABCD), 8), 0xCDAB);
|
||||||
|
CHECK_EQ (rotater (uint16_t (0xABCD), 12), 0xBCDA);
|
||||||
|
CHECK_EQ (rotater (uint16_t (0xABCD), 16), 0xABCD);
|
||||||
|
|
||||||
CHECK_EQ (rotatel (uint32_t (0x12345670), 12), 0x45670123);
|
CHECK_EQ (rotatel (uint32_t (0x12345670), 12), 0x45670123);
|
||||||
|
CHECK_EQ (rotater (uint32_t (0x12345670), 12), 0x67012345);
|
||||||
|
|
||||||
CHECK_EQ (rotatel (uint64_t (0x1234567890ABCDEF), 12), 0x4567890ABCDEF123);
|
CHECK_EQ (rotatel (uint64_t (0x1234567890ABCDEF), 12), 0x4567890ABCDEF123);
|
||||||
|
CHECK_EQ (rotater (uint64_t (0x1234567890ABCDEF), 12), 0xDEF1234567890ABC);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user