由于没有人提出这些为什么有用的主题:
在处理标志时,我经常使用按位运算。例如,如果您想将一系列标志传递给操作(例如,File.Open(),同时启用读取模式和写入模式),您可以将它们作为单个值传递。这是通过在位集(字节、短、整数或长)中为每个可能的标志分配它自己的位来实现的。例如:
Read: 00000001
Write: 00000010
所以如果你想通过 read AND write,你会通过 (READ | WRITE) 然后将两者组合成
00000011
然后可以在另一端解密,例如:
if ((flag & Read) != 0) { //...
哪些检查
00000011 &
00000001
返回
00000001
不是 0,所以标志确实指定了 READ。
您可以使用 XOR 来切换各种位。我在使用标志指定方向输入(上、下、左、右)时使用了它。例如,如果一个精灵水平移动,我希望它转身:
Up: 00000001
Down: 00000010
Left: 00000100
Right: 00001000
Current: 00000100
在这种情况下,我只是将当前值与 (LEFT | RIGHT) 进行异或,这将关闭 LEFT 并打开 RIGHT。
位移位在多种情况下很有用。
x << y
和
一样
x * 2y
如果您需要快速乘以 2 的幂,但要注意将 1 位移到最高位 - 这会使数字变为负数,除非它是无符号的。在处理不同大小的数据时它也很有用。例如,从四个字节中读取一个整数:
int val = (A << 24) | (B << 16) | (C << 8) | D;
假设 A 是最重要的字节,而 D 是最不重要的。它最终会是:
A = 01000000
B = 00000101
C = 00101011
D = 11100011
val = 01000000 00000101 00101011 11100011
颜色通常以这种方式存储(最高有效字节被忽略或用作 Alpha):
A = 255 = 11111111
R = 21 = 00010101
G = 255 = 11111111
B = 0 = 00000000
Color = 11111111 00010101 11111111 00000000
要再次找到值,只需将位向右移动直到它位于底部,然后屏蔽剩余的高阶位:
Int Alpha = Color >> 24
Int Red = Color >> 16 & 0xFF
Int Green = Color >> 8 & 0xFF
Int Blue = Color & 0xFF
0xFF 与 11111111 相同。所以本质上,对于 Red,你会这样做:
Color >> 16 = (filled in 00000000 00000000)11111111 00010101 (removed 11111111 00000000)
00000000 00000000 11111111 00010101 &
00000000 00000000 00000000 11111111 =
00000000 00000000 00000000 00010101 (The original value)