C语言中的位选择
我正在尝试选择位字符串1010000000001的位[0:2]和位[6:8]。位[0:2]为001,位[6:8]为000。我尝试使用以下选项选择这些位:C语言中的位选择,c,binary,C,Binary,我正在尝试选择位字符串1010000000001的位[0:2]和位[6:8]。位[0:2]为001,位[6:8]为000。我尝试使用以下选项选择这些位: int instr = 0x1401; int src2 = (instr & 0x0006); //get bits [2:0] int src1 = (instr & 0x01C0) >> 6; //get bits [6:8] printf("%04x, %04x",src2, src1); 然而,我得到s
int instr = 0x1401;
int src2 = (instr & 0x0006); //get bits [2:0]
int src1 = (instr & 0x01C0) >> 6; //get bits [6:8]
printf("%04x, %04x",src2, src1);
然而,我得到src1和src2都是0000。有人能帮我理解我做得不对吗?这样我就可以从我能看到的内容中选择位[0:2]和[6:8]。如果从0x1401和0x0006得到结果,那么从0x1401和0x01c0得到相同的结果。在src1上执行的位移位只是0向右移位6位,这仍然是0 从我所看到的,如果从0x1401和0x0006得到结果,则得到0,从0x1401和0x01c0得到相同的结果。在src1上执行的位移位只是0向右移位6位,这仍然是0 看看这段代码:
#include <stdio.h>
int main (void) {
unsigned instr = 0x1401;
unsigned src2 = instr & 0x0007; // 7 in hex == 0000 0000 0111 in binary
unsigned src1 = (instr & 0x01C) >> 6; // 1C in hex == 0001 1100 0000 in binary
printf("%04x, %04x", src2, src1);
}
它屏蔽了instr中所需的位,并按正确的偏移量对它们进行移位。此外,在执行位操作时,首选无符号类型。请查看以下代码:
#include <stdio.h>
int main (void) {
unsigned instr = 0x1401;
unsigned src2 = instr & 0x0007; // 7 in hex == 0000 0000 0111 in binary
unsigned src1 = (instr & 0x01C) >> 6; // 1C in hex == 0001 1100 0000 in binary
printf("%04x, %04x", src2, src1);
}
它屏蔽了instr中所需的位,并按正确的偏移量对它们进行移位。此外,在执行位操作时,首选无符号类型。只需编写一个函数,在此处使用1而不是0作为最低有效位,即可计算任意位片:
#include <stdio.h>
#include <assert.h>
int bit_select(int num, size_t start, size_t end)
{
assert(end >= start);
const int mask = (1 << (end-start+1)) - 1;
const int shift = start - 1;
return (num & (mask << shift)) >> shift;
}
int main(void)
{
printf("Bits 1...3 of 01100101: %d\n", bit_select(0x65, 1, 3));
printf("Bits 3...3 of 01100101: %d\n", bit_select(0x65, 3, 3));
printf("Bits 4...4 of 01100101: %d\n", bit_select(0x65, 4, 4));
printf("Bits 3...7 of 01100101: %d\n", bit_select(0x65, 3, 7));
return 0;
}
在这里,只需编写一个函数,使用1而不是0作为最低有效位来计算任意位片,就更容易了:
#include <stdio.h>
#include <assert.h>
int bit_select(int num, size_t start, size_t end)
{
assert(end >= start);
const int mask = (1 << (end-start+1)) - 1;
const int shift = start - 1;
return (num & (mask << shift)) >> shift;
}
int main(void)
{
printf("Bits 1...3 of 01100101: %d\n", bit_select(0x65, 1, 3));
printf("Bits 3...3 of 01100101: %d\n", bit_select(0x65, 3, 3));
printf("Bits 4...4 of 01100101: %d\n", bit_select(0x65, 4, 4));
printf("Bits 3...7 of 01100101: %d\n", bit_select(0x65, 3, 7));
return 0;
}
因为你提供了一个错误的面具 如果您使用gcc,为了让生活更轻松,只需提供二进制文字而不是十六进制版本,这样您就可以毫不费力地看到要屏蔽的内容:
unsigned src2 = instr & 0b111;
因为你提供了一个错误的面具 如果您使用gcc,为了让生活更轻松,只需提供二进制文字而不是十六进制版本,这样您就可以毫不费力地看到要屏蔽的内容:
unsigned src2 = instr & 0b111;
啊,好的。那么如何得到前三位001呢?对于位[0:3],它是0x000f;[0:2]它是0x0007;[6:8]它是0x01c0Ah,好的。那么我如何得到前三位001呢?对于位[0:3]是0x000f,对于位[0:2]是0x0007,对于位[6:8]是0x01C0,我正在尝试选择位[0:2]和[6:8]1+2+4=7。因此,使用0x7获取三个最低有效位,而不是0x6。位0的值为1,而不是0,因此,您的掩码6是off-by-1.0x7是正确的,src1实际上是000-将您的输入更改为11011或类似的内容,以便于查看获取src1值的常量可能更容易确定,并且代码更容易读取,如果您>>先移位6,然后将最低的三位掩码为&7。我正在尝试选择位[0:2]和[6:8]1+2+4=7。因此,使用0x7获取三个最低有效位,而不是0x6。位0的值为1,而不是0,因此,您的掩码6是off-by-1.0x7是正确的,src1实际上是000-将您的输入更改为11011或类似的内容,以便于查看获取src1值的常量可能更容易确定,并且代码更容易读取,如果您>>6先移位,然后将最低的三位掩码为&7。使用断言和pow似乎使它有点低效。断言的效率是无关紧要的,因为它在发布版本中是无操作的。使用pow比手动计算、写出和调试一千个单独指定的掩码,然后编写有关它们的问题的堆栈溢出问题更有效。为什么不使用mask=1>shift&mask?但是,这是为了教育目的,不是为了生产,所以谁会在乎效率。@ndim:公平竞争第一点,这绝对值得修改,答案更新。第二个也是公平的,但我保留了答案,因为我认为它使事情变得更清楚了。assert和pow的使用似乎使它有点低效。assert的效率无关紧要,因为它是一个无操作版本。使用pow比手动计算、写出和调试一千个单独指定的掩码,然后编写有关它们的问题的堆栈溢出问题更有效。为什么不使用mask=1>shift&mask?但是,这是为了教育目的,不是为了生产,所以谁会在乎效率。@ndim:公平竞争第一点,这绝对值得修改,答案更新。第二个也是公平的,但我保留了答案,因为我认为这会让事情变得更清楚。