我对位掩码感到困惑
I'm confused with bitmasks
我正在使用 IAR 嵌入式 workbench 和 C。我想创建一个掩码并决定传输的下一位是 1 还是 0。
我试过了但是没用
int transmit(int signal, int number_of_bits)
{
int mask;
for (int i = 0; i < number_of_bits; i++)
{
mask = pow(2,number_of_bits-1-i)
if ((signal & mask) == 0) // bit '0'
{
transmit0();
}
else // bit '1'
{
transmit1();
}
}
}
我试过了,它传输 0001,但我正在尝试传输 1000(反之亦然)
int transmit(int signal, int number_of_bits)
{
int mask;
for (int i = 0; i < number_of_bits; i++)
{
mask = (1 << i);
if ((signal & mask) == 0) // bit '0'
{
transmit0();
}
else // bit '1'
{
transmit1();
}
}
}
正如@L.F 注意到的那样,^
不是幂运算符,唉 <<
,位移运算符,可以解决问题。
此处 mask
是将始终包含 "power of 2" 值的变量。
目标是始终只在 mask
中设置一位。
这个mask
用来测试"isolation"中的每一位。
结合逻辑 AND
函数,您可以将其视为一个过滤器,它只为您提供特定位对应的值或不提供任何值(零)。
请记住,根据定义,仅设置一位的二进制字的值始终对应于 2 的幂值。因此,在测试单个位之后,您将看到零或 2 的幂值。
让我们在程序运行(假设8位)的情况下看一些实际值。
所以在 for 循环中,这就是 mask
的值随时间变化的样子:
00000001
00000010
00000100
00001000
00010000
...
注意:您也可以进入相反的方向,例如,如果接收方希望先看到最高位,最后看到最低位。不知道这里需要什么,但只是让你知道。
如果你想倒退,你用 (1 << (num_bits-1))
初始化 mask
然后在循环中每次向右走一步 mask >>= 1
).
每个掩码值都是按位 AND
-ed(&
运算符),输入值 signal
到 "filter" 是我们感兴趣的特定位.
记住:这个 AND
操作的结果仍然是多位——而不是一位,所以我们不能寻找 1 的值(我们还必须测试案例2、4、8 ...等等)。
例如,假设所有位都打开,则逻辑与输出将如下所示:
00000001 AND 11111111 = 00000001
00000010 AND 11111111 = 00000010
00000100 AND 11111111 = 00000100
00001000 AND 11111111 = 00001000
00010000 AND 11111111 = 00010000
...
请注意在这种情况下结果如何遵循掩码。
尽管每次的值都不同,但您知道当您得到非零值时,您测试的位一定很高!
如果所有位都关闭,您将看到:
00000001 AND 00000000 = 00000000
00000010 AND 00000000 = 00000000
00000100 AND 00000000 = 00000000
00001000 AND 00000000 = 00000000
00010000 AND 00000000 = 00000000
您会注意到检查结果是否为零更容易。这意味着该位已关闭。这也是代码只检查零值的原因,它知道在所有其他情况下该位是 1
!
现在的诀窍是获取正确的掩码值。
你想要的是将 1
的位值向左移动到正确的位置。
因此,如果您开始测试位 4,例如,您将 1 向左移动四位,您将得到(00010000 二进制)。
为此,我们使用左移运算符 <<
。
正如其他人已经说过的,^
不幸地做了一些完全不同的事情 (XOR),这增加了整个混乱。
我正在使用 IAR 嵌入式 workbench 和 C。我想创建一个掩码并决定传输的下一位是 1 还是 0。
我试过了但是没用
int transmit(int signal, int number_of_bits)
{
int mask;
for (int i = 0; i < number_of_bits; i++)
{
mask = pow(2,number_of_bits-1-i)
if ((signal & mask) == 0) // bit '0'
{
transmit0();
}
else // bit '1'
{
transmit1();
}
}
}
我试过了,它传输 0001,但我正在尝试传输 1000(反之亦然)
int transmit(int signal, int number_of_bits)
{
int mask;
for (int i = 0; i < number_of_bits; i++)
{
mask = (1 << i);
if ((signal & mask) == 0) // bit '0'
{
transmit0();
}
else // bit '1'
{
transmit1();
}
}
}
正如@L.F 注意到的那样,^
不是幂运算符,唉 <<
,位移运算符,可以解决问题。
此处 mask
是将始终包含 "power of 2" 值的变量。
目标是始终只在 mask
中设置一位。
这个mask
用来测试"isolation"中的每一位。
结合逻辑 AND
函数,您可以将其视为一个过滤器,它只为您提供特定位对应的值或不提供任何值(零)。
请记住,根据定义,仅设置一位的二进制字的值始终对应于 2 的幂值。因此,在测试单个位之后,您将看到零或 2 的幂值。
让我们在程序运行(假设8位)的情况下看一些实际值。
所以在 for 循环中,这就是 mask
的值随时间变化的样子:
00000001
00000010
00000100
00001000
00010000
...
注意:您也可以进入相反的方向,例如,如果接收方希望先看到最高位,最后看到最低位。不知道这里需要什么,但只是让你知道。
如果你想倒退,你用 (1 << (num_bits-1))
初始化 mask
然后在循环中每次向右走一步 mask >>= 1
).
每个掩码值都是按位 AND
-ed(&
运算符),输入值 signal
到 "filter" 是我们感兴趣的特定位.
记住:这个 AND
操作的结果仍然是多位——而不是一位,所以我们不能寻找 1 的值(我们还必须测试案例2、4、8 ...等等)。
例如,假设所有位都打开,则逻辑与输出将如下所示:
00000001 AND 11111111 = 00000001
00000010 AND 11111111 = 00000010
00000100 AND 11111111 = 00000100
00001000 AND 11111111 = 00001000
00010000 AND 11111111 = 00010000
...
请注意在这种情况下结果如何遵循掩码。 尽管每次的值都不同,但您知道当您得到非零值时,您测试的位一定很高!
如果所有位都关闭,您将看到:
00000001 AND 00000000 = 00000000
00000010 AND 00000000 = 00000000
00000100 AND 00000000 = 00000000
00001000 AND 00000000 = 00000000
00010000 AND 00000000 = 00000000
您会注意到检查结果是否为零更容易。这意味着该位已关闭。这也是代码只检查零值的原因,它知道在所有其他情况下该位是 1
!
现在的诀窍是获取正确的掩码值。
你想要的是将 1
的位值向左移动到正确的位置。
因此,如果您开始测试位 4,例如,您将 1 向左移动四位,您将得到(00010000 二进制)。
为此,我们使用左移运算符 <<
。
正如其他人已经说过的,^
不幸地做了一些完全不同的事情 (XOR),这增加了整个混乱。