位掩码左移

3

我尝试解决一个问题,但不确定这是否是正确的解决方案。

构建一个类型为unsigned long的掩码,其中最低有效位(从右边开始)的14位设置为1;

#include <stdio.h>
#include <stdlib.h>
unsigned long mask;
int main()
{
    int i;
    for(i=0;i<14;i++)
        mask|=(1<<i);
    printf("%li",mask);
    return 0;
}

2
你为什么不直接写0x3fff或者0b0011'1111'1111'1111呢? - 5gon12eder
2
避免循环的提示 - 如果从一个只有1位设置为1且所有其他位都为零的数字中减去1会发生什么。 - user180247
1
@5gon12eder:不使用0b0011'1111'1111'1111的一个很好的理由是它在C中是语法错误(我认为,在除最新版本的C++之外的所有版本中也是如此)。 - Keith Thompson
1
@5gon12eder:我并没有说它更易读。 - Keith Thompson
@Olaf,请给我举一个例子,这样我就可以学习了。 - Mark Ransom
显示剩余10条评论
1个回答

9

更好的做法是

#include <stdio.h>
#include <stdlib.h>
unsigned long mask;
int main()
{
    int num = 14;
    mask = (1 << num) - 1;
    printf("%lu", mask);
    return 0;
}

这里的num表示最低有效位的总数。 工作原理 2^14 = 16348 的二进制表示为 0000000000000000 0100000000000000‬(在32位中) 而且
2^14-1 = 16347 的二进制表示为 0000000000000000 0011111111111111‬ 因此有14个最低有效位设置为1。

4
因为变量mask的类型是无符号长整型,所以应该使用"%lu"来打印它。 - Solaine Charron
3
既然原帖是在询问如何构造位掩码,而不是打印它,那么这句话最好作为一条评论。如果问题不那么含糊不清的话,甚至都算不上一个回答。 - Keith Thompson
6
同样的道理,1000-1等于999。如果你想在十进制中表示N个9,可以用(10^N)-1来表示;如果你想在二进制中表示N个1,可以用(2^N)-1来表示。 - David Schwartz
2
如果你需要左边的位,我会给你一个提示:~ - Mark Ransom
我认为@MarkRansom的意思是~(-1<<n),但这可能只适用于二进制补码....等等他说从左边开始...即使如此,只需从位数中减去n而不要取反。 - technosaurus
显示剩余6条评论

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