Home > Back-end >  Trouble understanding syntax in C code for masking and bit conversion
Trouble understanding syntax in C code for masking and bit conversion

Time:11-28

Below is a code which returns the signed value of the last 6 bits in an 8 bit binary value however I am struggling to understand how the code does this? Any help would be greatly appreciated.

I understand that (b&0x20) returns the last 6 bits however the ? b afterwards and hence the subsequent code has me a little confused.

return (b & 0x20) ? b | ~0x3F : b & 0x3F;

CodePudding user response:

This code is probably written for circumstances in which:

  • b is an int or narrower.
  • Two’s complement is used to represent negative numbers.

The ? and : form a conditional operation. Generally, in X ? Y : Z, X is tested. If X is not zero, Y is evaluated and used as the result of the expression. If X is zero, Z is evaluated and used as the result.

So, in (b & 0x20) ? b | ~0x3F : b & 0x3F, (b & 0x20) is tested. b & 0x20 isolates from b the single bit in 0x20, so this is testing whether the bit in that position is on.

Let’s consider the “off” result first, when b & 0x3F is used. 0x3F is an int value with the low six bits set to 1 and all higher bits set to 0. When this is ANDed with b, in b & 0x3F, the result is the low six bits of b, with all higher bits set to 0. As an int, this result has the value of the low six bits of b.

For the “on” result, b | ~0x3F is used. The ~ operator flips each bit. Since 0x3F has the low six bits set to 1 and all higher bits set to 0, ~0x3F has the low six bits set to 0 and all higher bits set to 1. When that is ORed with b, in b | ~0x3F, the result is the low six bits of b with all higher bits set to 1.

What this does is “sign extend” the low six bits of b: If the bit in position 5 (0x20) is clear, the result of (b & 0x20) ? b | ~0x3F : b & 0x3F is the low six bits of b with all higher bits cleared. If the bit in position 5 is set, the result is the low six bits of b with all higher bits set. So the effect is the bit in position 5 is copied to all higher bits.

When two’s complement is used, extending the sign bit of narrower type yields the same value in a wider type.

For example, in three-bit two’s complement:

  • 011 represents 3.
  • 010 represents 2.
  • 001 represents 1.
  • 000 represents 0.
  • 111 represents −1.
  • 110 represents −2.
  • 101 represents −3.
  • 100 represents −4.

When we sign-extend those to 5 bits, we have:

  • 00011 represents 3.
  • 00010 represents 2.
  • 00001 represents 1.
  • 00000 represents 0.
  • 11111 represents −1.
  • 11110 represents −2.
  • 11101 represents −3.
  • 11100 represents −4.

A five-bit integer has other bit patterns, of course, but those are the ones we get by sign-extending from a three-bit integer.

  • Related