简体   繁体   English

使用按位运算符获取C中的位值

[英]Using Bitwise Operators to get Bit Values in C

I am writing a program in C where I am comparing two bytes of data, and then seeing if the bytes are different, and if so, at which bits. 我正在用C编写一个程序,在其中比较两个字节的数据,然后查看字节是否不同,如果不同,则在哪位。

This is what I have so far: 这是我到目前为止的内容:

int var1 = 81;  //Binary: 0101 0001
int var2 = 193; //Binary: 1100 0001
int diff = var1 ^ var2; //diff = 1001 0000 / 144

Basically I know how to use the XOR bitwise operator to see which bits are different between the two variables, but from here I don't know how to use diff to figure out which bits are the differences. 基本上,我知道如何使用XOR按位运算符来查看两个变量之间的哪些位不同,但是从这里开始,我不知道如何使用diff来找出哪些位是不同的。 For example, in my above code I'd want to use diff to output "Bit 5 and Bit 8 are different". 例如,在我上面的代码中,我想使用diff输出“位5和位8不同”。

You can use a for loop to get that idea and make bitwise AND with 1 properly left shifted to get the set bits positions 您可以使用for loop来获得该想法并进行按位AND运算AND并将1适当左移以获得设置的位位置

for(size_t i = 0; i < sizeof(int)*8; i++){
  if( diff & (1U << i))
    printf("%zu is different\n",i+1);
}

Far easier to start with unsigned types when doing bit manipulations. 在进行位操作时, unsigned类型开始要容易得多。


As @coderredoc inquired about solutions across various platforms, even uncommon ones: 正如@coderredoc询问有关各种平台的解决方案,甚至是不常见的解决方案:

Using int : 使用int

When int diff is negative, conversion to an unsigned (via masking with an unsigned ) may change its bit pattern. int diff是否定的,转化为unsigned (经由与掩蔽unsigned )可以改变它的位模式。

An int may have more than 8 bits per "byte". 一个int每个“字节”可能有8位以上。 Diminishes correctness of sizeof(int)*8 . 减小sizeof(int)*8正确性。

Various integer types may have padding (rare). 各种整数类型可能具有填充(稀有)。 Diminishes correctness of sizeof(int)*CHAR_BIT . 减小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);
}

For maximum portability, avoid changing types, changing the value of diff and use constants from <limits.h> rather than compute them. 为了获得最大的可移植性,请避免更改类型,更改diff的值并使用<limits.h>常量,而不要计算它们。

To get the different bits position, lets say you have 4 byte integer 要获得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);
}

use unsigned int instead of int ; 使用unsigned int代替int ; then you can use 那么你可以使用

for (unsigned int pos = 0; diff; ++pos) {
     if (diff & 1)
         printf("difference in pos %u\n", pos);
     diff >>= 1;
}

or 要么

while (diff) {
    int pos = ffs(diff);
    printf("difference in pos %d\n", pos);

    diff &= ~(1u << pos);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM