在 C 中使用位运算符获取位值
Using Bitwise Operators to get Bit Values in C
我正在用 C 编写程序,比较两个字节的数据,然后查看字节是否不同,如果不同,在哪些位。
这是我目前拥有的:
int var1 = 81; //Binary: 0101 0001
int var2 = 193; //Binary: 1100 0001
int diff = var1 ^ var2; //diff = 1001 0000 / 144
基本上我知道如何使用 XOR 按位运算符来查看两个变量之间哪些位不同,但是从这里我不知道如何使用 diff 来找出哪些位是不同的。例如,在我上面的代码中,我想使用 diff 来输出 "Bit 5 and Bit 8 are different".
您可以使用 for loop
来理解这个想法,并使按位 AND
与 1
适当左移以获得设置的位位置
for(size_t i = 0; i < sizeof(int)*8; i++){
if( diff & (1U << i))
printf("%zu is different\n",i+1);
}
要获得 different bits
位置,假设您有 4 byte
个整数
for(int bit_index = sizeof(diff) - 1; bit_index >= 0;bit_index-- ) {
if((diff >> bit_index & 1) == 1 ){ /* if particular bit is 1, that bit_index value you can use */
printf("[%d] bit is different or 1 \n",bit_index);
}
使用unsigned int
代替int
;那么你可以使用
for (unsigned int pos = 0; diff; ++pos) {
if (diff & 1)
printf("difference in pos %u\n", pos);
diff >>= 1;
}
或
while (diff) {
int pos = ffs(diff);
printf("difference in pos %d\n", pos);
diff &= ~(1u << pos);
}
在进行位操作时,开始 unsigned
类型要容易得多。
由于 询问了跨各种平台的解决方案,甚至是不常见的解决方案:
使用int
:
当 int diff
为负数时,转换为 unsigned
(通过使用 unsigned
进行掩码)可能 其位模式。
一个 int
每个 "byte" 可能有超过 8 位。降低 sizeof(int)*8
.
的正确性
各种整数类型可能有填充(很少见)。降低 sizeof(int)*CHAR_BIT
.
的正确性
// OP wants to report first bit index as 1. 0 is more common.
#define BIT_REPORT_OFFSET 0
int bit_position = 0;
int mask;
do {
mask = 1 << bit_position;
if (diff & mask) {
printf("Bit %d\n", bit_position + BIT_REPORT_OFFSET);
}
bit_position++;
} while (mask < INT_MAX/2);
if (diff < 0) {
printf("Bit %d\n", bit_position + BIT_REPORT_OFFSET);
}
为了获得最大的可移植性,避免更改类型、更改 diff
的值并使用 <limits.h>
中的常量而不是计算它们。
我正在用 C 编写程序,比较两个字节的数据,然后查看字节是否不同,如果不同,在哪些位。
这是我目前拥有的:
int var1 = 81; //Binary: 0101 0001
int var2 = 193; //Binary: 1100 0001
int diff = var1 ^ var2; //diff = 1001 0000 / 144
基本上我知道如何使用 XOR 按位运算符来查看两个变量之间哪些位不同,但是从这里我不知道如何使用 diff 来找出哪些位是不同的。例如,在我上面的代码中,我想使用 diff 来输出 "Bit 5 and Bit 8 are different".
您可以使用 for loop
来理解这个想法,并使按位 AND
与 1
适当左移以获得设置的位位置
for(size_t i = 0; i < sizeof(int)*8; i++){
if( diff & (1U << i))
printf("%zu is different\n",i+1);
}
要获得 different bits
位置,假设您有 4 byte
个整数
for(int bit_index = sizeof(diff) - 1; bit_index >= 0;bit_index-- ) {
if((diff >> bit_index & 1) == 1 ){ /* if particular bit is 1, that bit_index value you can use */
printf("[%d] bit is different or 1 \n",bit_index);
}
使用unsigned int
代替int
;那么你可以使用
for (unsigned int pos = 0; diff; ++pos) {
if (diff & 1)
printf("difference in pos %u\n", pos);
diff >>= 1;
}
或
while (diff) {
int pos = ffs(diff);
printf("difference in pos %d\n", pos);
diff &= ~(1u << pos);
}
在进行位操作时,开始 unsigned
类型要容易得多。
由于
使用int
:
当 int diff
为负数时,转换为 unsigned
(通过使用 unsigned
进行掩码)可能
一个 int
每个 "byte" 可能有超过 8 位。降低 sizeof(int)*8
.
各种整数类型可能有填充(很少见)。降低 sizeof(int)*CHAR_BIT
.
// OP wants to report first bit index as 1. 0 is more common.
#define BIT_REPORT_OFFSET 0
int bit_position = 0;
int mask;
do {
mask = 1 << bit_position;
if (diff & mask) {
printf("Bit %d\n", bit_position + BIT_REPORT_OFFSET);
}
bit_position++;
} while (mask < INT_MAX/2);
if (diff < 0) {
printf("Bit %d\n", bit_position + BIT_REPORT_OFFSET);
}
为了获得最大的可移植性,避免更改类型、更改 diff
的值并使用 <limits.h>
中的常量而不是计算它们。