根据以下信息,我不明白为什么你想要评估,例如,使用&
运算符的2个十六进制整数。我理解下面解释的反演模式,我可以自己计算,但很难推断为什么(从我在互联网上看到的帖子)。什么是真实世界场景可能会让我在这里有所见解?
0xff00 & 0xf0f0 is 0xf000
0xff00 ^ 0xf0f0 is 0x0ff0
0xff00 | 0xf0f0 is 0xfff0
For &, the result value is the bitwise AND of the operand values.
For ^, the result value is the bitwise exclusive OR of the operand values.
For |, the result value is the bitwise inclusive OR of the operand values.
在我自己的脑海里,我现在想到这样:
if ( 65280 & 61680 ) // evaluates to 61440, not boolean?
答案 0 :(得分:9)
这些类型的运算符用于很多事情,但是现在在更高级别的语言中,它们最常用于标记。它是来自C等低级语言的延续,其中内存分配和释放并不总是微不足道的,而且是在硬件资源稀缺的时候开发的。
假设某些操作有3个可能的标志,并且可以在任何给定的组合中提供它们。提供标志的快速,简单且有效的方法是将每个标志分配给整数位。
public static final int FLAG_1 = 1; // 00000001
public static final int FLAG_2 = 1 << 1; // 00000010
public static final int FLAG_3 = 1 << 2; // 00000100
然后发送多个标志,我可以使用按位或&#34; |&#34;运营商。
someFunc(FLAG_1 | FLAG_3).
要读取传递的标志,我可以使用按位&amp;操作
public void someFunc(int flags) {
if ((flags & FLAG_1) == FLAG_1 /*Or (flags & FLAG_1) != 0 */) {
// Passed in flag 1.
}
}
还有其他方法可以做到这一点,但这非常有效,易于阅读,并导致堆上的零对象分配。如果你想到用Java完成这个的其他方法,让我们说一个枚举/整数的数组或集合,或者每个标志是一个单独的方法参数,它清楚为什么这个而是使用模式。
答案 1 :(得分:2)
我认为如果您需要实现一小部分boolean
,最好将其表示为int
或long
,每个位代表一个数组元素:
在这种情况下,您可以使用移位运算符和&
,|
,&=
,|=
或^=
进行测试,清除,设置或翻转数组的元素。 (另请注意,这可以并行使用多个数组元素。)
这种情况很少发生。为了便于阅读,使用常规array
或ArrayList
要好得多。但是,我有两个用例至少出现一次。一个是使用强力回溯算法编写数独求解器;我不记得细节,但我想我使用9位int
来表示行,列或方形中的单元格是否被占用。如果我没记错的话,我的一些代码会同时测试多个单元格,我可以使用一个&
运算符。由于通过回溯解决可能涉及大量的组合,我相信使用这种机制在运行时间方面产生了明显的差异。另一个案例涉及一个项目表,用于保存项目是否具有某些属性的信息。物业数量相对较少(10至20之间),但物品数量可能达到数千万。 Set
可能是表示属性集的自然选择,但由于我需要保留大量的HashSet
,因此需要记忆。
除非内存或时间有很大差异,否则我不建议这样做。它有点“棘手”,我更喜欢直截了当的代码来表达你想要完成的事情。
答案 2 :(得分:1)
对于if语句中的一个非常基本的例子:
if ( (65280 & 1) == 0 ){
// 65280 is even!
}
x & 1
是,则0
为x
如果x & 1
为奇数,1
为x