Last active
November 16, 2019 00:16
-
-
Save catfact/8b85599e389e0082fa6f7fee3847adae to your computer and use it in GitHub Desktop.
bitrot16 : demonstration of logical shift-and-rotate on signed integer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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