Take the 2-minute tour ×

Sorry if the title is a little bit confusing, here's a full explanation:

Suppose I have the following structure:

union data {
        uint32_t h : 16;
        uint32_t p : 16;
    uint32_t f;

and the following code:

struct data d;
d.f = 0xbaadf00d;
printf("%d %d\n", d.h, d.p);

My question is as follows, is there an equivalent way of doing this using bitwise operations? Something like:

uint32_t u32 = 0xbaadf00d;
uint32_t h = u32 ... some hacks ...
uint32_t p = u32 ... some more hacks ...

Would greatly appreciate an answer with explanation and/or reference read.

share|improve this question
h is the f00d part right? (I don't use bitfields often enough to remember). h = u32 & 0xffff; p = u32 >> 16; –  harold Oct 21 '13 at 11:14
Please explain your intention of what you want to do? It is unclear what you want to achieve. Is it that you want to get the low-word and high-word of a 32bit value, or something different? –  elgonzo Oct 21 '13 at 11:14
@elgonzo not just that I want to get the low-word and high-word, but suppose I have even more variables like union { uint32_t a : 4; uint32_t b : 4; ... } and so on. –  user9000 Oct 21 '13 at 11:15
Why is a union relevant for bit-wise operations? I am still not certain about what you try to achieve. –  elgonzo Oct 21 '13 at 11:16
In general: mask the bits away that you don't want, then align the bits that you do want (or the other way around, doesn't matter, and sometimes one of those operations turns into a no-op) –  harold Oct 21 '13 at 11:19
show 1 more comment

1 Answer

up vote 4 down vote accepted
uint32_t d=0xbaadf00d;
printf("%d %d\n", d>>16, d&0xffff);

d>>16 performs a right shift, which moves the upper bits 16 positions on the right (inserting zeroes in the upper positions), which extracts the upper 16 bits (notice that if d was of a wider type, you would have to also apply a mask to kill the undesired upper bits).

d&0xffff applies a mask, which lets only the lowest 16 bit pass through. This comes from the fact that 0xffff is an integer with all the lower 16 bits set, and the AND operation leave untouched only the bits corresponding to 1s in the mask.

In general, the pattern is like this:

(d>>n) & m

Where n is the position of the rightmost bit of your interest, and m is a mask made by as many binary 1s as the field you want to extract is wide .

Incidentally, notice that your original method, as far as the standard is concerned, exhibits undefined behavior.

share|improve this answer
+1, for mentioning UB in original code. –  Don't You Worry Child Oct 21 '13 at 11:21
mind explaining why'd my code exhibit an UB? Also have a look at: codepad.org/z9hitl5g –  user9000 Oct 21 '13 at 11:23
@user9000: because type-punning via unions is not allowed by the standard; only one field of a union can be "active" at a time (in C++ there are some exceptions about standard layout classes with common initial subsequence, I suppose in C there's something similar). –  Matteo Italia Oct 21 '13 at 11:28
I got a small question if you don't mind, I would like to learn how all these stuff work (I already know the truth tables and so on) but I want to learn how to correctly and usefully use bitwise operations and understand them, so I can write code using them by myself, do you know of any good books/read? Thanks! –  user9000 Oct 21 '13 at 19:15
@user9000: I never actively studied this matter, I guess it comes with practice. –  Matteo Italia Oct 21 '13 at 19:32
show 1 more comment

Your Answer


