1

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.

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. For example, in my above code I'd want to use diff to output "Bit 5 and Bit 8 are different".

1
  • 5
    They're (usually) not bits 5 and 8, but 4 and 7. Commented Feb 18, 2018 at 16:39

4 Answers 4

3

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(size_t i = 0; i < sizeof(int)*8; i++){
  if( diff & (1U << i))
    printf("%zu is different\n",i+1);
}
Sign up to request clarification or add additional context in comments.

11 Comments

damn, you beat me, I discarded my answer as it was the same :)
What is the 1U inside the if statement? I haven't seen that before.
@Skitzafreak it means that the 1 should be consider as an unsigned int.
@chux.: Is it wise to use CHAR_BIT..almost all architectures today have CHAR_BIT as 8
That is a style issue. Style issues are best determined by your group/company style guide as it is more important to follow that than spend much effort doing what is "best".
|
2

Far easier to start with unsigned types when doing bit manipulations.


As @coderredoc inquired about solutions across various platforms, even uncommon ones:

Using int:

When int diff is negative, conversion to an unsigned (via masking with an unsigned) may change its bit pattern.

An int may have more than 8 bits per "byte". Diminishes correctness of sizeof(int)*8.

Various integer types may have padding (rare). Diminishes correctness of 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.

1 Comment

Thank you very much for the well thought out answer. I learned a lot in that.
0

use unsigned int instead of 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);
}

Comments

0

To get the different bits position, lets say you have 4 byte integer

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);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.