Created
November 6, 2017 04:14
-
-
Save cfilipov/9b7eb759bc3827fb9c5bc6b0ced08699 to your computer and use it in GitHub Desktop.
Bit fiddling in C
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 "stdio.h" | |
#include "stdint.h" | |
/** | |
* Print the binary representation of an integer `n` with length `len`. | |
* Any unsigned integer can be safely cast to uintmax_t. | |
* | |
* Shift right then mask to the last bit. | |
*/ | |
void printb2(uintmax_t n, size_t len) | |
{ | |
size_t w = len - 1; | |
for (size_t i = 0; i < len; i++) | |
printf("%ju ", (n >> (w - i)) & 0x01); | |
} | |
/** | |
* Print the binary representation of an integer `n` with length `len`. | |
* Any unsigned integer can be safely cast to uintmax_t. | |
* | |
* Start with a bit mask where the MSB is set then shift right until the LSB. | |
*/ | |
void printb3(uintmax_t n, size_t len) | |
{ | |
/* Note the 1U is important because otherwise 1 will be treated as a | |
* signed value, resulting in all the bits to the left being set. */ | |
for (uintmax_t i = 1U << (len - 1); i > 0; i >>= 1) | |
printf("%i ", n & i ? 1 : 0); | |
} | |
/** | |
* Print the binary representation of an integer `n` with length `len`. | |
* Any unsigned integer can be safely cast to uintmax_t. | |
* | |
* Same as printb3, using `while` instead of `for`. | |
*/ | |
void printb4(uintmax_t n, size_t len) | |
{ | |
while (--len < SIZE_MAX) | |
printf("%i ", n & (1 << len) ? 1 : 0); | |
} | |
/** | |
* Print the binary representation of an 8-bit wide integer. | |
*/ | |
void printb(uint8_t i) | |
{ | |
printf("%x ", (i >> 7) & 0x01); | |
printf("%x ", (i >> 6) & 0x01); | |
printf("%x ", (i >> 5) & 0x01); | |
printf("%x ", (i >> 4) & 0x01); | |
printf("%x ", (i >> 3) & 0x01); | |
printf("%x ", (i >> 2) & 0x01); | |
printf("%x ", (i >> 1) & 0x01); | |
printf("%x", (i >> 0) & 0x01); | |
} | |
/* | |
Swap the second and fourth bytes in an integer sequence | |
http://stackoverflow.com/questions/17409874 | |
See also: http://commandcenter.blogspot.com/2012/04 | |
int someInt = 0x12345678; | |
int byte2 = someInt & 0x00FF0000; | |
int byte4 = someInt & 0x000000FF; | |
int swapd = (someInt & 0xFF00FF00) | (byte2 >> 16) | (byte4 << 16); | |
byte2 = 0x00340000 | |
byte4 = 0x00000078 | |
someInt & 0xFF00FF00 = 0x12005600 | |
byte2 >> 16 = 0x00000034 | |
byte4 << 16 = 0x00780000 | |
0x12005600 | |
| 0x00000034 | |
| 0x00780000 | |
= 0x12785634 | |
*/ | |
enum byte_order { | |
BIG_ENDIAN, | |
LITTLE_ENDIAN | |
}; | |
enum byte_order get_byte_order() { | |
} | |
int main() | |
{ | |
uint8_t i8 = 42; | |
uint16_t i16 = 42; | |
uint32_t i32 = 42; | |
printf("b: "), printb(i8), printf("\n"); | |
printf("b2: "), printb2(i8, 8), printf("\n"); | |
printf("b3: "), printb3(i8, 8), printf("\n"); | |
printf("b4: "), printb4(i8, 8), printf("\n\n"); | |
printf("b2: "), printb2(i16, 16), printf("\n"); | |
printf("b3: "), printb3(i16, 16), printf("\n"); | |
printf("b4: "), printb4(i16, 16), printf("\n\n"); | |
printf("b2: "), printb2(i32, 32), printf("\n"); | |
printf("b3: "), printb3(i32, 32), printf("\n"); | |
printf("b4: "), printb4(i32, 32), printf("\n"); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment