位运算与usag

2024-05-23 19:18:34 发布

您现在位置:Python中文网/ 问答频道 /正文

请考虑以下代码:

x = 1        # 0001
x << 2       # Shift left 2 bits: 0100
# Result: 4

x | 2        # Bitwise OR: 0011
# Result: 3

x & 1        # Bitwise AND: 0001
# Result: 1

我能理解Python(和其他语言)中的算术运算符,但我对“按位”运算符的理解一直不太好。在上面的例子中(来自Python的一本书),我理解左移位,但不理解其他两个。

另外,按位运算符实际上用于什么?我想举几个例子。


Tags: orand代码语言shift运算符算术result
3条回答

位运算符是处理多位值的运算符,但在概念上是一次一位。

  • AND只有当其输入的都为1时才为1,否则为0。
  • OR是1,如果输入的一个或两个都是1,否则是0。
  • XOR只有当它的输入中只有一个是1时才是1,否则是0。
  • NOT只有当其输入为0时才为1,否则为0。

这些通常可以最好地显示为真值表。输入可能性在顶部和左侧,结果位是在输入交集处显示的四个值之一(如果不是,则为两个,因为它只有一个输入)。

AND | 0 1     OR | 0 1     XOR | 0 1    NOT | 0 1
----+-----    ---+----     ----+----    ----+----
 0  | 0 0      0 | 0 1       0 | 0 1        | 1 0
 1  | 0 1      1 | 1 1       1 | 1 0

一个例子是,如果您只需要整数的低位4位,那么您和它用15(二进制1111)表示:

    201: 1100 1001
AND  15: 0000 1111
------------------
 IS   9  0000 1001

在这种情况下,15中的零位有效地充当一个过滤器,迫使结果中的位也为零。

此外,>><<通常包含为按位运算符,它们将一个值分别左右“移位”一定数量的位,丢弃向其移动的一端滚动的位,并在另一端输入零位。

例如:

1001 0101 >> 2 gives 0010 0101
1111 1111 << 4 gives 1111 0000

请注意,Python中的左移不常见,因为它没有使用丢弃位的固定宽度,而许多语言根据数据类型使用固定宽度,Python只是扩展宽度以满足额外位的需要。为了获得Python中的丢弃行为,可以使用按位and执行左移位,例如在8位值中左移4位:

bits8 = (bits8 << 4) & 255

考虑到这一点,按位运算符的另一个示例是,如果有两个4位值要打包为8位值,则可以使用这三个运算符(left-shiftandor):

packed_val = ((val1 & 15) << 4) | (val2 & 15)
  • & 15操作将确保两个值都只有较低的4位。
  • << 4是左移4位,将val1移到8位值的前4位。
  • |只是将这两者结合在一起。

如果val1是7,val2是4:

                val1            val2
                ====            ====
 & 15 (and)   xxxx-0111       xxxx-0100  & 15
 << 4 (left)  0111-0000           |
                  |               |
                  +-------+-------+
                          |
| (or)                0111-0100

what are bitwise operators actually used for? I'd appreciate some examples.

位操作最常见的用途之一是解析十六进制颜色。

例如,这里有一个Python函数,它接受类似#FF09BE的字符串,并返回其红色、绿色和蓝色值的元组。

def hexToRgb(value):
    # Convert string to hexadecimal number (base 16)
    num = (int(value.lstrip("#"), 16))

    # Shift 16 bits to the right, and then binary AND to obtain 8 bits representing red
    r = ((num >> 16) & 0xFF)

    # Shift 8 bits to the right, and then binary AND to obtain 8 bits representing green
    g = ((num >> 8) & 0xFF)

    # Simply binary AND to obtain 8 bits representing blue
    b = (num & 0xFF)
    return (r, g, b)

我知道有更有效的方法来实现这一点,但我相信这是一个非常简洁的示例,演示了移位和按位布尔运算。

一个典型用法:

|用于将某个位设置为1

&用于测试或清除特定位

  • 设置一个位(其中n是位号,0是最低有效位):

    unsigned char a |= (1 << n);

  • 清除一点:

    unsigned char b &= ~(1 << n);

  • 切换一点:

    unsigned char c ^= (1 << n);

  • 测试一下:

    unsigned char e = d & (1 << n);

以您的列表为例:

x | 2用于将x的位1设置为1

x & 1用于测试x的位0是1还是0

相关问题 更多 >