4

I am trying to combine three bit operations in one line of C. For a 8 bit char, I have to set bits 2, 4, 6; clear bits 1, 3, 7 and toggle bit 0 and 5 all in one line code of C. I could do these in three line but I cannot combine these. Below is what I have done so far:

x= x & 0xD5;
x = x | 0x51;
x = x ^ 0x84;

They give the right answer for a given value of x. But I tried

x = (x & 0xD5) | (x | 0x51) | (x ^ 0x84)

And

x = x & 0xD5 | 0x51  ^ 0x84

Those do not work. Any suggestion would be appreciated.

ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
Aurora427
  • 53
  • 3

2 Answers2

4

It's simply this

x = (((x & 0xD5) | 0x51) ^ 0x84)

Your first try is wrong, because the values of x are not updated so all the operations work on the same value, besides oring the values is not equivalent to assigning the result of the operation to x.

The second, is wrong because or operator precedence, so you just need parentheses.

Iharob Al Asimi
  • 52,653
  • 6
  • 59
  • 97
  • @iharob: there is a slightly more efficient alternative, cf my answer, unlike even recent `gcc`, `clang` does the transformation and generates better code. – chqrlie Jan 24 '16 at 20:30
3

Your second solution fails because of operator precedence. You can fix it this way:

x = ((x & 0xD5) | 0x51) ^ 0x84;

But there is a more efficient solution:

x = (x & (0xD5 & ~0x51)) ^ (0x84 | 0x51);

You clear the bits you want to clear and the bits you want to set and then toggle both the bits you want to toggle and the bits you want to set. It compiles to one less operation because the constant operations are folded at compile time.

chqrlie
  • 131,814
  • 10
  • 121
  • 189