C 如何使用位运算符交错2个布尔值?

C 如何使用位运算符交错2个布尔值?,c,bit-manipulation,bitwise-operators,C,Bit Manipulation,Bitwise Operators,假设我有两个4位值,ABCD和ABCD。如何使用位运算符对其进行交织,使其成为AaBbCcDd?伪C中的示例: nibble a = 0b1001; nibble b = 0b1100; char c = foo(a,b); print_bits(c); // output: 0b11010010 注意:4位仅用于说明,我想用两个32位整数来实现这一点。这里是一个基于循环的解决方案,希望它比这里已有的一些解决方案更具可读性 #include <stdint.h> #include

假设我有两个4位值,
ABCD
ABCD
。如何使用位运算符对其进行交织,使其成为
AaBbCcDd
?伪C中的示例:

nibble a = 0b1001;
nibble b = 0b1100;
char c = foo(a,b);
print_bits(c); 
// output: 0b11010010

注意:4位仅用于说明,我想用两个32位整数来实现这一点。

这里是一个基于循环的解决方案,希望它比这里已有的一些解决方案更具可读性

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>


uint64_t interleave(uint32_t a, uint32_t b) {
    uint64_t result = 0;
    int i;
    for (i = 0; i < 31; i++) {
        result |= (a >> (31 - i)) & 1;
        result <<= 1;
        result |= (b >> (31 - i)) & 1;
        result <<= 1;
    }

    // Skip the last left shift.
    result |= (a >> (31 - i)) & 1;
    result <<= 1;
    result |= (b >> (31 - i)) & 1;
    return result;
}
void printBits(uint64_t a) {
    int i;
    for (i = 0; i < 64; i++)
        printf("%lu", (a >> (63 - i)) & 1);
    puts("");
}
int main(){
    uint32_t a = 0x9;
    uint32_t b = 0x6;
    uint64_t c = interleave(a,b);
    printBits(a);
    printBits(b);
    printBits(c);
}
#包括
#包括
#包括
uint64\u t交织(uint32\u t a,uint32\u t b){
uint64_t结果=0;
int i;
对于(i=0;i<31;i++){
结果|=(a>>(31-i))&1;
结果(31-i))&1;
结果(31-i))&1;
结果(31-i))&1;
返回结果;
}
无效打印位(uint64\u t a){
int i;
对于(i=0;i<64;i++)
printf(“%lu”,(a>>(63-i))&1);
认沽权(“”);
}
int main(){
uint32_t a=0x9;
uint32_t b=0x6;
uint64_t c=交织(a,b);
打印位(a);
打印位(b);
打印位(c);
}
像这样:

#include <limits.h>

typedef unsigned int       half;
typedef unsigned long long full;

full mix_bits(half a,half b)
{
    full result = 0;
    for (int i=0; i<sizeof(half)*CHAR_BIT; i++)
        result |= (((a>>i)&1)<<(2*i+1))|(((b>>i)&1)<<(2*i+0));
    return result;
}
#包括
typedef无符号整数半;
typedef无符号长满;
全混音位(半a、半b)
{
完整结果=0;
对于斯坦福大学“比特旋转黑客”页面中的(inti=0;i>i)&1)i)&1):

uint32_t x=/*…*/,y=/*…*/;
uint64_t z=0;
对于(int i=0;i
假设
x
是一个32位整数,
a
在其高阶16位,而
b
在其低阶16位:

   unsigned int x = (a << 16) | b;   /* put a and b in place */
无符号整数x=(a8)&0x0000FF00 | x&0xFF0000FF;
x=(x&0x00F000F0)>4)和0x00F000F0 | x&0xF00FF00F;
x=(x&0x0c)>2)和0x0c0c | x&0xc3c3;
x=(x&0x2222222)>1)和0x2222222 | x&0x9999999;
他还提供了另一种形式,这种形式在某些CPU上更快,并且(我认为)更加清晰和可扩展:

unsigned int t;  /* an intermediate, temporary variable */
t = (x ^ (x >> 8)) & 0x0000FF00;  x = x ^ t ^ (t << 8);
t = (x ^ (x >> 4)) & 0x00F000F0;  x = x ^ t ^ (t << 4);
t = (x ^ (x >> 2)) & 0x0C0C0C0C;  x = x ^ t ^ (t << 2);
t = (x ^ (x >> 1)) & 0x22222222;  x = x ^ t ^ (t << 1);
unsigned int t;/*中间临时变量*/

t=(x^(x>>8))&0x0000FF00;x=x^t^(t>4))&0x00F000F0;x=x^t^(t>2))&0x0C0C0C;x=x^t^(t>1))&0x22222222;x=x^t^(t我使用了
在特定索引设置位和
检查特定索引位的两种技巧/操作

以下代码仅使用这2个操作实现

int a = 0b1001;
int b = 0b1100;
long int c=0;
int index;   //To specify index of c
int bit,i;

//Set bits in c from right to left.
for(i=32;i>=0;i--)
{
    index=2*i+1;   //We have to add the bit in c at this index

    //Check a

    bit=a&(1<<i);  //Checking whether the i-th bit is set in a
    if(bit)
      c|=1<<index; //Setting bit in c at index

    index--;

    //Check b

    bit=b&(1<<i);  //Checking whether the i-th bit is set in b
    if(bit)
      c|=1<<index; //Setting bit in c at index
}
printf("%ld",c);
inta=0b1001;
INTB=0b1100;
长整数c=0;
int index;//指定c的索引
int位,i;
//从右向左设置c中的位。
对于(i=32;i>=0;i--)
{
index=2*i+1;//我们必须在这个索引处添加c中的位
//检查

bit=a&(1但是两个32位的整数如果我们用你的方式连接起来就会得到64位,但是
半字节c
只能容纳32位。对吗?对不起,更新了(我想做一个64位的整数)。我认为
交错
可能比
混合
更好。事实上,它是更新的。你为什么说“布尔”(即1位值)在你的标题中,但在你的问题中谈论4位和32位值?但它应该接收32位int并返回一个日志…这只是返回一个int,对吗?所以我不明白…!@Viclib:抱歉,刚才注意到你提到了4位值作为一个例子。很有趣,但对我来说它仍然不够明显-那里有一些神奇的十六进制数。你怎么知道呢我是否扩展了它,使
x
实际上是64位,
a
b
是32位?编辑有帮助吗?它只是将相同的模式扩展到字长的两倍。我只是,现在,设法解码了它,自己做了!谢谢。
unsigned int t;  /* an intermediate, temporary variable */
t = (x ^ (x >> 8)) & 0x0000FF00;  x = x ^ t ^ (t << 8);
t = (x ^ (x >> 4)) & 0x00F000F0;  x = x ^ t ^ (t << 4);
t = (x ^ (x >> 2)) & 0x0C0C0C0C;  x = x ^ t ^ (t << 2);
t = (x ^ (x >> 1)) & 0x22222222;  x = x ^ t ^ (t << 1);
unsigned long long int t;  /* an intermediate, temporary variable */
t = (x ^ (x >> 16)) & 0x00000000FFFF0000ull;  x = x ^ t ^ (t << 16);
t = (x ^ (x >> 8))  & 0x0000FF000000FF00ull;  x = x ^ t ^ (t << 8);
t = (x ^ (x >> 4))  & 0x00F000F000F000F0ull;  x = x ^ t ^ (t << 4);
t = (x ^ (x >> 2))  & 0x0C0C0C0C0C0C0C0Cull;  x = x ^ t ^ (t << 2);
t = (x ^ (x >> 1))  & 0x2222222222222222ull;  x = x ^ t ^ (t << 1);
int a = 0b1001;
int b = 0b1100;
long int c=0;
int index;   //To specify index of c
int bit,i;

//Set bits in c from right to left.
for(i=32;i>=0;i--)
{
    index=2*i+1;   //We have to add the bit in c at this index

    //Check a

    bit=a&(1<<i);  //Checking whether the i-th bit is set in a
    if(bit)
      c|=1<<index; //Setting bit in c at index

    index--;

    //Check b

    bit=b&(1<<i);  //Checking whether the i-th bit is set in b
    if(bit)
      c|=1<<index; //Setting bit in c at index
}
printf("%ld",c);