0

我对下面 if 语句中的“&”感到困惑。如果说“如果位0x10 = 0x10”是拳头

def lcd_byte(bits, mode):
  if bits&0x10==0x10:
    GPIO.output(LCD_D4, True)
  if bits&0x20==0x20:
    GPIO.output(LCD_D5, True)
  if bits&0x40==0x40:
    GPIO.output(LCD_D6, True)
   if bits&0x80==0x80:
    GPIO.output(LCD_D7, True)
4

5 回答 5

7

不,&按位 AND,而不是布尔AND。对于操作数值的每个单独位,按位在二进制级别上工作。

因此,使用值 1 和 0 你会得到:

1 & 1 == 1
1 & 0 == 0
0 & 1 == 0
0 & 0 == 0

但是对于二进制中包含多个位的整数值,运算符将改为处理每个位对:

2 & 1 == 0
2 & 2 == 2

该表达式& 0x10测试是否设置了第 5 位:

0b00010000 & 0x10 == 0x10

因为0x10(十六进制)或十进制 16 是00010000二进制的。0x20是第 6 位,0x40是第 7位,是0x80最左边或第 8 位。

代码比需要的要冗长一些;仅针对一位进行测试时,操作员将返回0或测试针对的位,并且==可以省去该部分:

def lcd_byte(bits, mode):
    if bits & 0x10:
        GPIO.output(LCD_D4, True)
    if bits & 0x20:
        GPIO.output(LCD_D5, True)
    if bits & 0x40:
        GPIO.output(LCD_D6, True)
    if bits & 0x80:
        GPIO.output(LCD_D7, True)

有关按位运算如何工作的详细信息,请参阅Wikipedia 上的按位运算文章。Python 定义了几个位运算符

  • &: 和
  • |: 或者
  • ^: 异或
  • <<: 左移
  • >>: 右移
于 2013-05-06T19:01:32.410 回答
2

正在发生的事情是正在测试字节的特定位。例如,假设值为 0xAF 或十进制 175。二进制为:

bit    7654 3210
----------------
value  1010 1111

现在我们要测试一下是否设置了上面的第 5 位。所以我们制作了一个只包含那个位集的掩码。它被称为掩码,因为它就像一个模板,只允许某些位“显示”在掩码中有 1 的地方。掩码中的 0 位被“屏蔽”,我们不关心它们的值。

bit    7654 3210
----------------   =   0x20 or 32 in decimal
value  0010 0000

现在我们可以使用按位和运算来测试该值。“按位”是指一个值中的每个位都针对另一个值中的相应位进行测试,而“和”是指只有在两个原始值中都设置了该位时才设置结果位。在 Python 中,这个操作是写成的&

ORIGINAL VALUE          MASK                    RESULT

bit    7654 3210        bit    7654 3210        bit    7654 3210
----------------   &    ----------------   =    ----------------
value  1010 1111        value  0010 0000        value  0010 0000

现在我们看看结果。如果结果非零,则我们知道该位已设置为原始值。

现在,您发布的 Python 代码实际上不是检查它是否非零,而是查看它是否是实际的掩码值。只有在一次测试多个位时才真正需要这样做,只需在掩码中包含多个 1 位即可。在这种情况下,如果在原始值中设置了任何相应位,则结果为非零。有时这就是您想要的,但如果您想确保所有这些都已设置,那么您需要明确地将结果与掩码值进行比较。

在此特定示例中,每个位对应于一个特定的 GPIO 输出,该输出在该位打开时被激活(假设这些输出在代码的前面都立即关闭)。

于 2013-05-06T19:15:05.930 回答
1

这里需要注意两点:

  • &是按位,不是逻辑
  • &的优先级高于==,因此您的表达式被解析为(bits & 0x20) == 0x20

该成语x & mask具有过滤比特的作用,x以便只保留其中1的比特mask

bits        : b8 b7 b6 b5 b4 b3 b2 b1
0x20        :  0  0  1  0  0  0  0  0
===================================== 
bits & 0x20 :  0  0 b6  0  0  0  0  0

因此,当第 6 位 ( ) 为 1 inbits & 0x20 == 0x20时,恰好是正确的。b6bits

于 2013-05-06T19:09:46.677 回答
1

正如所写,这有点多余:

if bits & 0x10 == 0x10: ...

测试是否设置了位 0x10,可以更简单地表示为

if bits & 0x10: ...

但是,如果您需要测试多个位,它可能不是多余的。

if bits & 0x11: ...

测试是否设置位 0x01 或位 0x10;

if bits & 0x11 == 0x11: ...

测试是否设置位 0x01 和 0x10。

于 2013-05-06T19:10:38.790 回答
0

不,它说的是“位和 0x10”,它会评估它,然后它会接受任何东西并检查是否等于 0x10。

我讨厌按位十六进制(看看它的怪异)所以我玛使用二进制

例如:

if 0b10000 & 0b10000 == 0b10000:

我使用 0x11 例如位

如果简化,则评估为“(0b10001 & 0b10000) == 0b10000”或“0b10000 == 0b10000”,如果进一步简化,则评估为“True”。

于 2013-05-06T19:09:54.863 回答