Skip to content

Instantly share code, notes, and snippets.

@catfact
Last active November 16, 2019 00:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save catfact/8b85599e389e0082fa6f7fee3847adae to your computer and use it in GitHub Desktop.
Save catfact/8b85599e389e0082fa6f7fee3847adae to your computer and use it in GitHub Desktop.
bitrot16 : demonstration of logical shift-and-rotate on signed integer
#include <stdint.h>
#include <stdio.h>
// perform a logical bit shift with rotation on a signed 16-bit integer
// second argument is number of bits:
// positive to shift right, negative shift left
int16_t bitrot16(int16_t x, int n) {
// use a union with unsigned type,
// so all our bitwise ops ignore sign
union { int16_t si; uint16_t ui; } u;
u.si = x;
if (n > 0) { // shift right
// low bits wrap to high
u.ui = u.ui >> n | (u.ui << (16-n));
} else { // shift left
int m = n * -1;
// high bits go left and wrap
u.ui = u.ui << m | (u.ui >> (16-m));
}
return u.si;
}
// testing
void print_bits(int16_t x) {
union { int16_t si; uint16_t ui; } u;
u.si = x;
for (int i=0; i<16; ++i) {
if (u.ui & (1 << (15-i))) {
printf("1");
} else {
printf("0");
}
}
printf("\n");
}
// test
int main(void) {
int x;
x = 0xdead;
for (int i=0; i<16; ++i) {
print_bits(bitrot16(x, i));
}
for (int i=0; i<16; ++i) {
print_bits(bitrot16(x, i * -1));
}
x = 0xbeef;
for (int i=0; i<16; ++i) {
print_bits(bitrot16(x, i));
}
for (int i=0; i<16; ++i) {
print_bits(bitrot16(x, i));
}
for (int i=0; i<16; ++i) {
print_bits(bitrot16(x, i * -1));
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment