Java中一个字节的按位比较

8

我有一个三字节的值DB(DB_1,DB_2,DB_3)。 我需要检查DB_3中特定的位。例如,我必须查看是否 DB_3 == 11X0XXXX 只有第4、6和7位应该被检查。标记为X的位可以取任何值,不应该被检查。我不熟悉Java中的位运算,感谢任何帮助! 谢谢!


1
我建议阅读http://en.wikipedia.org/wiki/Bitwise_operation。 - Oliver Charlesworth
4个回答

23

你可以使用按位与操作符 (& 在Java中) 来实现掩码操作来获取特定位的值(掩码在第二行,只有当掩码对应的二进制位为1时才能将第一行对应的二进制位保留下来 [如下计算中箭头所示]:)

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

你将保留两个操作数中都是 1 的二进制位,因此实际上你将设置那些不感兴趣的二进制位为0

所以你只需要执行以下操作:

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

0xD0 是16进制的形式,对应于十进制的 208 ,二进制为 11010000。你想要知道它是否匹配 0xC0,即二进制的 11000000,也就是 192。由于按位与操作已经把你不关心(问题中的X)的所有位都变成了0,因此你可以知道它们是否匹配。


ETA (2011-12-14 14:24): 显然 Java 7 有二进制整数字面量,所以你可以这样做:

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

这让面罩更加明显。感谢Glenn


3
我猜Java 7有二进制字面量:http://docs.oracle.com/javase/7/docs/technotes/guides/language/binary-literals.html - Glenn

7

5
虽然Joey的方法很好用,但这里有另一种方式可以完成同样的任务,我个人认为这种方式更直观。
你需要两个掩码:MASK1 = 11000000 定义了DB_3应该如何显示,MASK2 = 11010000定义了应该考虑哪些位。在MASK2中,1位表示我们关心的位,0位表示我们不关心的位。
MASK1进行异或并取反,然后与MASK2进行与运算,并检查结果是否等于MASK2。前两个操作将在DB_3MASK1匹配的位置上放置1。第三个操作将在结果中除了MASK2中指定的1位之外都将数字变为0。只有当DB_3MASK2中指定的1位上与MASK1匹配时,比较才会得出true
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;

按位操作的示例:

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

I hope that was understandable.


我可能会将确切的位掩码作为注释添加,而不是使用 parseInt,但这可能是个人偏好(是的,注释可能会过时)。但 Grenn 指出,现在 Java 中有二进制字面量,这使得它看起来更自然。 - Joey
如果我要真正地做这件事,我可能会计算十进制表示,并添加一个“//208d = 11010000b”注释或类似的内容。在这里使用parseInt主要是为了清晰明了,而且当时我没有想到使用这样的注释... - Emil Lundberg


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接