C 如何使用位运算符实现模式2^n-1

C 如何使用位运算符实现模式2^n-1,c,bit-manipulation,bit,C,Bit Manipulation,Bit,在使用位操作编程时,我有一个疑问。也就是说,在我的项目中,某个时间点我需要像这样设置位,如果我键入“1”,则表示设置了第一位。如果我键入“2”,则表示设置了前2位 所以 1-12-11 3-111 4-1111 同样的道理。由此我分析了以下模式,即1-1,11-3111-71111-15 也就是说2^1-1=1,2^2-1=3,2^3-1=7 现在我需要在一行中为这种格式编写位操作 非常感谢您的帮助。1对于无符号int(比如32位),您可以从bitcount获得如下值: value = 0xff

在使用位操作编程时,我有一个疑问。也就是说,在我的项目中,某个时间点我需要像这样设置位,如果我键入“1”,则表示设置了第一位。如果我键入“2”,则表示设置了前2位

所以

1-12-11 3-111 4-1111

同样的道理。由此我分析了以下模式,即1-1,11-3111-71111-15

也就是说2^1-1=1,2^2-1=3,2^3-1=7

现在我需要在一行中为这种格式编写位操作

非常感谢您的帮助。

1对于无符号int(比如32位),您可以从bitcount获得如下值:

value = 0xffffffffU >> (32-bitcount);
例如,让我们使用3的
位计数

  0xffffffff >> (32-bitcount)
= 0xffffffff >> 29
= 0x00000007
以下程序显示了此操作:

#include <stdio.h>

int cvt (int bc) {
    return 0xffffffffU >> (32-bc);
}

int main (void) {
    for (int bc = 1; bc <= 32; bc++)
        printf ("%2d: 0x%08x %u\n", bc, cvt (bc), cvt (bc));
    return 0;
}
到目前为止,我们已经有了“主要的两个答案”,你通常会得到这个问题。它们的边缘条件不同。假设32位无符号整数采用公共值,
(1u(32-n)
答案可以处理1到32

一个经常出现的问题是,我们能有0到32吗

你可以,但很自然,它更复杂,特别是如果你不接受条件。通过将任何一种方法与三元运算符相结合,很容易得到完整的范围,但是没有条件,仍然有方法

请注意,
n=32
是在
n
中设置位
0b00100000
的唯一情况

因此,我们可以做的一件事是提取该位,将其反转,然后向左移位(注意不要执行未定义的移位),如下所示:

((n >> 5 ^ 1) << (n & 31)) - 1
或在具有BMI2的x86上:

or rax, -1
bzhi rax, rax, rcx

太好了。谢谢你的回答:)嗨,有趣的是你的答案比我的慢1/3倍。。我很想发布时间安排和一些分析,我应该将它们发布在这里还是其他地方?@starrify,我不担心优化。除非你必须每秒做数百万次,否则这不太重要。我的设备(用户+系统)上的CPU时间根本没有注册(所有32个输入值都小于0.001s),这是零优化。64000次呼叫使CPU时间达到0.016s。任何分析都最好是查看生成的asm代码,而不是试图使用轶事证据,但如果愿意,您可以在答案中添加分析。当然,我会保留回复权:-)@paxdiablo请查看此::)是的,在大多数情况下,我并不关心性能neigher,但调查总是很有趣。:谢谢。对于您在本文中的解释,@VINAYAK只是想提醒您,只有怪人才关心在这样一个可能不经常使用的函数上在这样的级别进行优化。除息的。如果任何其他选项在运行稍慢的情况下提供更好的可读性或类似的良好特性,请选择较慢的选项,只要您没有从事疯狂的优化工程师的工作:p问题特别提到1是第一种可能性,因此可能没有必要处理0。如果您必须处理0,那么这将是一个特殊的边缘情况,比如
If(bc==0)返回0
@paxdiablo我想不会。它并没有专门针对0或32个案例,只是一小部分示例。也许两者都不是必需的,OP似乎确实喜欢这两个答案。我一直在使用
(n==32)?0xFFFFFF:(1)
((n >> 5 ^ 1) << (n & 31)) - 1
or rax, -1
shl ecx, 8
bextr rax, rax, rcx
or rax, -1
bzhi rax, rax, rcx