How do I get bit-by-bit data from an integer value in C?
If you want the k-th bit of n, then do
(n & ( 1 << k )) >> k
Here we create a mask, apply the mask to n, and then right shift the masked value to get just the bit we want. We could write it out more fully as:
int mask = 1 << k; int masked_n = n & mask; int thebit = masked_n >> k;
You can read more about bit-masking here.
Here is a program:
#include <stdio.h>#include <stdlib.h>int *get_bits(int n, int bitswanted){ int *bits = malloc(sizeof(int) * bitswanted); int k; for(k=0; k<bitswanted; k++){ int mask = 1 << k; int masked_n = n & mask; int thebit = masked_n >> k; bits[k] = thebit; } return bits;}int main(){ int n=7; int bitswanted = 5; int *bits = get_bits(n, bitswanted); printf("%d = ", n); int i; for(i=bitswanted-1; i>=0;i--){ printf("%d ", bits[i]); } printf("\n");}
As requested, I decided to extend my comment on forefinger's answer to a full-fledged answer. Although his answer is correct, it is needlessly complex. Furthermore all current answers use signed int
s to represent the values. This is dangerous, as right-shifting of negative values is implementation-defined (i.e. not portable) and left-shifting can lead to undefined behavior (see this question).
By right-shifting the desired bit into the least significant bit position, masking can be done with 1
. No need to compute a new mask value for each bit.
(n >> k) & 1
As a complete program, computing (and subsequently printing) an array of single bit values:
#include <stdio.h>#include <stdlib.h>int main(int argc, char** argv){ unsigned input = 0b0111u, n_bits = 4u, *bits = (unsigned*)malloc(sizeof(unsigned) * n_bits), bit = 0; for(bit = 0; bit < n_bits; ++bit) bits[bit] = (input >> bit) & 1; for(bit = n_bits; bit--;) printf("%u", bits[bit]); printf("\n"); free(bits);}
Assuming that you want to calculate all bits as in this case, and not a specific one, the loop can be further changed to
for(bit = 0; bit < n_bits; ++bit, input >>= 1) bits[bit] = input & 1;
This modifies input
in place and thereby allows the use of a constant width, single-bit shift, which may be more efficient on some architectures.
Here's one way to do it—there are many others:
bool b[4];int v = 7; // number to dissectfor (int j = 0; j < 4; ++j) b [j] = 0 != (v & (1 << j));
It is hard to understand why use of a loop is not desired, but it is easy enough to unroll the loop:
bool b[4];int v = 7; // number to dissectb [0] = 0 != (v & (1 << 0));b [1] = 0 != (v & (1 << 1));b [2] = 0 != (v & (1 << 2));b [3] = 0 != (v & (1 << 3));
Or evaluating constant expressions in the last four statements:
b [0] = 0 != (v & 1);b [1] = 0 != (v & 2);b [2] = 0 != (v & 4);b [3] = 0 != (v & 8);