【问题标题】:Bit comparison code, would like help understanding it位比较代码,希望帮助理解它
【发布时间】:2019-08-18 03:55:41
【问题描述】:

我一直在查看二进制计数器的示例代码,我很难完全理解使用按位操作切换每个 ledOnOffState 的 for 循环中发生了什么。

对于从 0 到 7 计数的每个 i 数字,我现在遇到了一些麻烦的是 (i & 1)、(i & 2) 和 (i & 4)。

我认为,对于循环中的每个 i 小数,它们的二进制值都被用于针对 ledOnOffState 的 () 中的 1、2 和 4 的二进制值进行操作。但我不太确定这些部分到底在做什么。例如,当 i = 3, 011 时,(3 & 1)、(3 & 2) 和 (3 & 4) 中的每一个发生了什么,分别为二进制值 011 产生 1、1 和 0?

bool led1OnOffState; // true = 1 = ON (HIGH), false = 0 = OFF (LOW)
bool led2OnOffState;
bool led3OnOffState;

int iterations = 2;

for (int iteration = 0; iteration < iterations; iteration++)
{
     // a for loop that counts from 0 to 7
    for (int i = 0; i < 8; i++)
    {
        // check to see if the 1, 2, and 4 bits are set for the current counter number
        led1OnOffState = (i & 1); // check for binary bit value 1 = true (1) or false (0)
        led2OnOffState = (i & 2); // check for binary bit value 2
        led3OnOffState = (i & 4); // check for binary bit value 4

        printf("The decimal %d is %d%d%d in binary\n", i, led3OnOffState, led2OnOffState, led1OnOffState);

如果它只比较一位,例如 (3 & 1) 的 2^0 位和 (3 & 2) 的 2^1 位以及 (3 & 4) 的 2^2 位在这些情况下,这对我来说是有意义的,因为它分别导致 1、1、0。

但我怀疑情况并非如此,我的另一个想法是它可能正在对每个位执行 3 次按位与运算,如果其中任何一个为真,它会将 ledOnOffState 值更改为 TRUE,如果没有一个为真的话更改为 FALSE。

我使用 ledOnOffState = (i & 3) 尝试了代码,结果让我认为后一种情况可能是正确的,因为只有十进制值 0 和 4 为 0,而其他所有值都为 1。

【问题讨论】:

  • (i &amp; x) 表达式获得 非零 值,而 i 中的相应 非零。由于这些被分配给bool 变量,它们只能具有非零值1true

标签: c boolean boolean-logic boolean-operations


【解决方案1】:

分配给bool 的任何非零整数都会被隐式转换为1/true,否则0/false。掩码 1、2 和 4 分别简单地引用值的 3 个最低有效位,二进制 001010100。如果设置了掩码位,则每个表达式的计算结果都为true

这意味着这段代码根据这个生成了一个真值表:

i     LED1 LED2 LED3
0      0    0    0
1      1    0    0
2      0    1    0
3      1    1    0
4      0    0    1
...

也就是说,代码只是简单地进行二进制计数并将其分散到 3 个布尔变量中。

一种更传统的方法,如在实际嵌入式系统中所做的那样,是使用引脚 0、1、2 将所有 3 个 LED 路由到同一个端口,然后只需执行以下操作:

for (int i = 0; i < 8; i++)
{
  PORT = i;
}

【讨论】:

  • 谢谢您,但是您能否详细说明一下与选择 LED 设置为 1 还是 0 的 i 值相关的掩码发生了什么?在执行 AND 操作时,它是否只是查看 3 LSB 内的 1、2 或 4 的单个位值?还是将所有 3 个 LSB 都考虑在内?如果我们用 3 代替数字而不是 1、2 或 4,那么二进制是 011,并且掩码现在包含 2 个 ON 值,那么代码中发生了什么来确定状态是 ON 还是 OFF?
  • @Dave (i &amp; 1) 表示第 0 位,(i &amp; 2) 表示第 1 位,(i &amp; 4) 表示第 2 位。这就是位掩码的重点。操作数 i 当然是“整个 i”,但在每种情况下掩码只是一个位。将位掩码写为十六进制更为常见,但在这种情况下它不会改变任何内容(0x01、0x2、0x04)。用 3 屏蔽没有任何意义,因为这里的目的是创建一个二进制计数器。
  • 谢谢,我知道在这种二进制计数器的情况下,用 3 屏蔽是没有意义的,但我的问题不是二进制计数器本身。我的问题的重点和我想了解的是代码的 (i & x) 部分发生了什么,使其成为 0 或 1,这就是为什么我询问 (i & 3) 的情况我希望这能为我澄清一下。如果两位为 1,则操作中会发生什么情况,掩码是否需要两个 1 来匹配 & 才能使其为真或只有一个?如果我使用 (i & 7),它会为每个 1-7 值输出 1,为 0 输出 0?
  • @Dave 这段代码的重点是仅用 1 位进行掩码。任何非零结果都将变为true。按位与学习。
  • 我问这个问题是因为我在理解这个 bool 运算中的按位与时遇到了困难,希望得到一些澄清。同样,虽然代码的重点是掩码,但我的问题不是关于整个代码,只是其中的一个操作,我希望这一点对我的问题的读者来说是清楚的,试图用 (i & 3),也许我包含了太多的代码。但是,从您的“任何非零结果都将变为真实”的评论中,这对我来说已经帮助一切到位,所以谢谢。如果有任何非零,则结果为 TRUE。
猜你喜欢
  • 2014-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-24
  • 2021-07-29
  • 2010-11-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多