Skip to content

Instantly share code, notes, and snippets.

@cfilipov
Created November 6, 2017 04:14
Show Gist options
  • Save cfilipov/9b7eb759bc3827fb9c5bc6b0ced08699 to your computer and use it in GitHub Desktop.
Save cfilipov/9b7eb759bc3827fb9c5bc6b0ced08699 to your computer and use it in GitHub Desktop.
Bit fiddling in C
#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