Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java bitwise comparison of a byte

I have a value DB of 3 bytes (DB_1, DB_2, DB_3). I need to check DB_3 for specific bits. For example I have to see if DB_3 == 11X0XXXX Where only bit 4, 6 and 7 should be checked. Bits marked as X can take any value and should not be checked. I am not familiar with Bit operations in Java and glad for any help! Thanks!

like image 802
tzippy Avatar asked Dec 14 '11 12:12

tzippy


3 Answers

You can use a bitwise AND (& in Java) to accomplish the masking to specific bits (the mask is the second line and will only let those bits of the first line through where the mask has a 1 [marked with arrows below the calculation]):

  11101001
& 11010000
----------
  11000000
  ↑↑ ↑

You'll retain exactly those bits that were 1 in both operands, so essentially you set all those bits to 0 that you are not interested in.

So you just need to do

if (DB_3 & 0xD0 == 0xC0) { ... }

0xD0 is the hexadecimal form of 208 which is 11010000 in binary and you want to know whether it matches 0xC0 which is 192, or 11000000. You'll know that all the bits you don't care about (the Xes in your question) are already zero at this point due to the bitwise AND.


ETA (2011-12-14 14:24): Apparently Java 7 has binary integer literals, so you can do

if (DB_3 & 0b11010000 == 0b11000000) { ... }

which makes the mask more readily apparent. Thanks, Glenn.

like image 141
Joey Avatar answered Nov 13 '22 20:11

Joey


You have to use Masks. You do a bit operation with the value and the mask.
The result will contain only the bit if it was set in the value.

http://www.divnull.com/lward/writing/bitwise.html

like image 24
hellectronic Avatar answered Nov 13 '22 21:11

hellectronic


While Joey's method works just fine, here's another way to do it which I personally think feels more intuitive.

You will need two masks: MASK1 = 11000000 which defines how DB_3 is supposed to look, and MASK2 = 11010000 which defines which bits should be taken into account. 1 bits in MASK2 indicate bits we care about and 0 bits indicate bits we do not care about.

Do an XOR with MASK1 and invert that, then an AND with MASK2, and check if the result equals MASK2. The first two operations will place 1s where DB_3 and MASK1 match. The third operation will drop all digits in the result to 0 except for the bits indicated by 1s in MASK2. The comparison evaluates to true if and only if DB_3 matches MASK1 at the positions indicated by 1s in MASK2.

int MASK1 = Integer.parseInt("11000000", 2); // tell parseInt to use base 2
int MASK2 = Integer.parseInt("11010000", 2);
boolean matches = (~(DB_3 ^ MASK1) & MASK2) == MASK2;

Example of the bitwise operations:

  11101001
^ 11000000
----------
  00101001
~
----------
  11010110
& 11010000
----------
  11010000

I hope that was understandable.

like image 5
Emil Lundberg Avatar answered Nov 13 '22 21:11

Emil Lundberg