C 如何使用位运算符交错2个布尔值?
假设我有两个4位值,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
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);