Jump to content
Sign in to follow this  
Darwin Amulet

Bitwise and binaries issue

You are about to reply to a thread that has been inactive for 3272 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

I recently got a piece of code which does the following:

it combines a few integers via bitshift to one integer. Thats nothing really troublesome.

but then it takes this integer and sends it out into the linkset like this: bitwise_integer & 0x7F8

now whats the 0x7F8 for? i know it has some purpose. and i know the person who initially wrote the code also reverts it back. but how?

many thanks in advance

 

Share this post


Link to post
Share on other sites

The & operator is a bitwise AND.  In this case, it is masking the bitwise_integer with 0x7F8, which is 2040 decimal or 111 1111 1000 binary.   Wherever there is a "1" in both the bitwise_integer AND the mask, the result is a 1.  otherwise, the result is a zero.   So, if your bitwise_integer is 11 0101 1100 (decimal 860 or 0x35C), for example:

0x35C & 0x7F8 = 11 0101 1100 & 111 1111 1000 = 11 0101 1000 (856 decimal or 0x358)

 

 

Share this post


Link to post
Share on other sites

nice to see you getting more comfortable with those bitwise operations =)

 

alternate explanation, since OP seems to have a handle on the shifts, is that Bitwise & acts just like Boolean && only on each bit.... so 32 boolean truth tests.

TRUE & TRUE = TRUE
TRUE & FALSE = FALSE
FALSE & TRUE = FALSE
FALSE & FALSE = FALSE

Share this post


Link to post
Share on other sites

To put it in simple functional terms:

 

Using a bitwise-AND (&) will only let those bits that are set in BOTH values appear in the result.  This lets it be used to 'mask off' bits we aren't interested in (by putting zeros in those bits in our 'mask' value.

 

Using a bitwise-OR (|) will set those bits that are in the 'mask' in the result, all others will be what was present in the other value.

 

So if I had an integer, and I was only interested in the 2nd bit, I could do this:

 

integer result = 0x02 & value;

 The 0x02 is the 'mask' (00000010b), and the only possible values for result are either 0 or 2.

 

Say I wanted to SET some bits to a specific value.....as an example, I wanted to make sure the top bit (sign bit) of a 32-bit integer was set (no normal reason to do this, but as an example.)  Then I could do this:

integer result = value | 0x80000000;

 The 0x80000000 is our 'mask' (10000000000000000000000000000000b), and the top bit of the result will ALWAYS be set.

 

In the example you gave, with a mask of 0x7F8, (0000011111111000b), you can see that by using a bitwise-AND, all the bits above the 11th, and the lowest 3 bits, will be zero.  Whatever the other bits of the value was, will be present in the same positions in the result.

 

So, as another example, say I wanted to put a value that was always between 0 and 12 together with a value that was always between 0 and 9, and store them as a single integer.  Both will fit in 4 bits (can represent 0-15 in 4 bits), but are too big for 3 bits (can represent 0-7 in 3 bits.)  We'll call the first one value1, and the second value2.

integer compressed = (value2 << 4) & (value1);

 The << and >> operators are the left and right bitshift operators.  They shift the bits in a value by the number of places specified.  So in the above, value2 gets shifted left (up) by four places (by the way, this is the same as multiplying the value by 2 for each 'place' shifted....so in the above, it is effectively multiplied by 16.)  Then we bitwise-AND the lower value with it (which, since it will always be below 13, means the low 4 bits will be the only ones which could be non-zero.

Now, what if we want to extract those values back out?

integer value1 = compressed & 0x0F;integer value2 = (compressed & 0xF0) >> 4;

 We 'mask' off the bits we want to pull out, and in the case of value2, we shift them back to their original position.

 

Viola!  Bitwise operators can be very handy, though you can go overboard with them.  But they are very fast, compared to most math operations.  When you need to multiply by a power of two, always shift instead.

 

  • Like 2

Share this post


Link to post
Share on other sites

They're using it simply so that an over-sized value won't corrupt the other compressed values.

So they mask out all the other bits that would do the aforementioned corruption.

Share this post


Link to post
Share on other sites

Okay. i think now i got it WHY he seperated the bits from 11 up and 3 down.

and i learned how to use this useful function. Thats worth a kudos

 

Thanks a bunch!

Share this post


Link to post
Share on other sites
You are about to reply to a thread that has been inactive for 3272 days.

Please take a moment to consider if this thread is worth bumping.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...