在C语言中的位运算:从左侧设置位

4

给定一个整数,例如10,我该如何在16个比特位中写入10个1(从左侧开始):

11111111.11000000

如果给出一个整数例如4,它会输出:

11110000.00000000

谢谢,我还在学习C语言,对位运算不熟悉。

3个回答

3

-(1 << wordsize - numbits)可以解决问题。

看看你的例子会很有启发性。 1 << wordsize - numbits1 << 12,即00010000.00000000。回想一下-x = ~x+1,我们计算~(1 << 12) = 11101111.111111。加上1,您将得到11110000.00000000


1

实际上,int通常是32位。但我在注释中只提到了16位,以使它更清晰明了。

int i = 0; //00000000 00000000
int mask = 65536; //10000000 00000000
int retVal = 0; //00000000 00000000
int yourAmountOfBitsToOne = 2;

for(i = 0; i < yourAmountOfBitsToOne; i++){
    retVal = retVal | (mask >> i);
}

printf("%d", retVal);

如果你运行这个程序,输出应该是 2ˆ16 + 2ˆ15 = 98304。
为什么呢?
迭代0:
line 1: retVal = 00000000 00000000 | (10000000 00000000 >> 0)
line 1: retVal = 10000000 00000000

迭代1:
line 1: retVal = 10000000 00000000 | (10000000 00000000 >> 0)
line 1: retVal = 10000000 00000000 | (01000000 00000000)
line 1: retVal = 11000000 00000000 

在 for 循环结束后,您打印了整数值为 11000000 0000000098304
现在创建一个函数,按位打印 int retVal,这将使您更容易检查输出是否正确。 这也是学习位运算符的非常好的练习。
希望对您有所帮助。

0

整数通常是32位的。如果你指的是短整数,则:

unsigned short MakeMask16(unsigned short width,unsigned short offsetFromLeft)
{
    unsigned short mask = -1;
    mask <<= (sizeof(unsigned short)*8-width);
    mask >>= offsetFromLeft;
    return mask;
}

或者全部放在一行上:

unsigned short MakeMask16(unsigned short width,unsigned short offsetFromLeft)
{
    return (unsigned short(-1<<(sizeof(unsigned short)*8-width)) >> offsetFromLeft);
}

请注意,在进行右移操作之前,如果您不将其转换为 unsigned short 类型,则您认为被移除的 1 仍将存在。如果您不需要从左侧偏移,则可以忽略此问题并取消右移操作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接