什么是位运算符?
按位运算符是一种逐位操作的运算符。
AND仅当其输入都为1时为1。
OR只要其中一个输入为1,则为1。
XOR仅当其输入中只有一个为1时为1。
NOT仅当其输入为0时为1。
这些可以最好地描述为真值表。输入可能性位于顶部和左侧,结果位是两个输入交叉点处显示的四个(NOT的情况下只有一个输入,所以只有两个)值之一。
AND的真值表:
AND|0 1 ---+---- 0|0 0 1|0 1
OR的真值表:
OR|0 1 ---+---- 0|0 1 1|1 1
XOR的真值表:
XOR|0 1 ---+---- 0|0 1 1|1 0
NOT的真值表:
NOT|0 1 ---+---- |1 0
一个例子是如果你只想要一个整数的低4位,你可以将其与15(二进制1111)进行AND运算:
203: 1100 1011 AND 15: 0000 1111 ------------------ IS 11: 0000 1011
位运算符是用来进行位操作的。位运算符在处理标志位时非常有用。例如,如果你想要将一系列标志位传递给一个操作(比如,使用File.Open()
函数打开文件,并同时启用读和写模式),你可以将它们作为一个单一的值进行传递。这可以通过为每个可能的标志位在位集(byte、short、int或long)中分配一个独立的位来实现。例如:
Read: 00000001 Write: 00000010
所以,如果你想要传递读和写两个标志位,你可以传递 (READ | WRITE),这将把两个标志位合并为
00000011
然后在另一端可以解密它,如下所示:
if ((flag & Read) != 0) { //...
这个判断会检查
00000011 & 00000001
返回的结果是
00000001
不等于 0,所以这个标志位确实指定了读取。
你可以使用异或运算符(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
颜色通常以这种方式存储(最高有效字节通常被忽略或用作透明度):
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
。所以对于红色,你实际上是这样做的:
Color >> 16 = (填充 00000000 00000000)11111111 00010101 (移除 11111111 00000000) 00000000 00000000 11111111 00010101 & 00000000 00000000 00000000 11111111 = 00000000 00000000 00000000 00010101(原始值)
x<<n,所以 n 必须是 2 的幂次方吗?
位运算符是一种用于操作二进制位的运算符。当我们使用整数进行位运算时,每一对位在每一列上都会通过相应的运算符计算,然后得到底部行上的输出位。因此,上述表达式的答案是4。在这个例子中,CPU并行地执行了8个独立的“AND”操作。
从这个例子中,我们可以看出位运算符的工作原理。通过对每一对输入位进行逻辑运算,我们可以得到二进制数的相应输出位。这种并行计算的方式使得位运算符在处理大量数据时非常高效。
这个例子让我想起了多年前学习位运算符时的“噢!”时刻。现在,这个概念变得更加清晰了。感谢提问者的问题和解释。
在这个讨论中,还有其他许多有用的回答。尽管我无法为它们投票,但仍然要感谢这些回答的作者们。
至今为止,我一直在使用位运算符,但却不知道这个原理。非常感谢提供这个解释。
通过这个问题和解释,我们了解到了位运算符的工作原理以及如何使用它们来对二进制数进行操作。这对于需要处理大量二进制数据的编程任务非常有用。