我想构造由二进制字符串 10101010101010101010101010101010 (即 16 个 1 和 16 个 0)表示的无符号整数(4 个字节)。
有没有一种有效的方法来使用位操作来构造这个值?我可以在 for 循环中做到这一点,但我觉得这效率低下。
任何语言都适合我。我个人知道c和C++。
我想构造由二进制字符串 10101010101010101010101010101010 (即 16 个 1 和 16 个 0)表示的无符号整数(4 个字节)。
有没有一种有效的方法来使用位操作来构造这个值?我可以在 for 循环中做到这一点,但我觉得这效率低下。
任何语言都适合我。我个人知道c和C++。
只需读取 4 位 4 位并将它们视为十六进制:
你的号码只是 0xAAAAAAA。
使用固定数量的位数,这有点明显......
但是对于可变位数,可以通过整数除法获得这种模式,如下所示http://smallissimo.blogspot.fr/2011/07/revisiting-sieve-of-erathhostenes.html
编辑下面更详细的解释:
这个想法是:
2r01 * 2r11 -> 2r11
2r0101 * 2r11 -> 2r1111
2r010101 * 2r11 -> 2r111111
所以反过来,我们可以应用一个精确的除法:
2r111111 / 2r11 -> 2r010101
如果我们想要2r101010
而不是2r010101
,只需再添加 1 位(但除法不精确,我假设商由 // 给出,就像在 Smalltalk 中一样):
2r1111111 // 2r11 -> 2r101010
2r1111111
可以很容易地构造,它是 2 减 1 的幂,2^7-1
也可以通过位移来获得(1<<7)-1
。
在您的情况下,您的常量是((1<<33)-1)//3
,或者如果您用 C/C++ 编写它((1ULL<<33)-1)/3
(在 Smalltalk 中,我们不关心整数长度,它们是任意长度,但在大多数语言中,我们必须确保操作数适合本机整数长度)。
请注意,除法也适用于较长长度的位模式,例如2r100100100
除以2r111
,对于长度为 p 的位模式,除以2^p-1
即(1<<p)-1