11

code

The "value" ranges from 0 to 15 (its possible values). When will those 4 "if" conditions be met? If my (int)value = 2 does this mean 0010?

            if  ((int)value & 0x1) 
            {
                //statement here
            }
            if  ((int)value & 0x2) 
            {
                //statement here
            }
            if  ((int)value & 0x4) 
            {
                //statement here
            }
            if  ((int)value & 0x8) 
            {
                //statement here
            }
2
  • 3
    Those are bitmasks checking for individual bits of value (read if(value & 0x4) as "Is the 3rd bit of value set (=1)). As you seemingly have problems understanding the code, I assume it is not yours. This (and the fact that you are not asking for review) makes this question off-topic for CR.SE. Commented Jul 2, 2014 at 8:41
  • For better understanding, similar code that has been ported to C# will use the Enum.HasFlag method to test for bits. See: Enum.HasFlag.
    – rwong
    Commented Jul 2, 2014 at 13:18

3 Answers 3

12

Each number can be expressed as value = b0*2^0 + b1*2^1 + b2*2^2 + b3*2^3 + ... with each b being either 0 or 1 (these are the bits of the representation). This is the binary representation.

The binary AND (&) takes each of those b pair wise and performing AND on them. This has the following outputs:

0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1

Using powers of 2 (which have only a single bit on) we can isolate and test the individual bits:

  • value & 1 is true when value is odd {1, 3, 5, 7, 9, 11, 13, 15}.

  • value & 2 is true when value/2 is odd {2, 3, 6, 7, 10, 11, 14 ,15}.

  • value & 4 is true when value/4 is odd {4, 5, 6, 7, 12, 13, 14 ,15}.

  • value & 8 is true when value/8 is odd {8, 9, 10, 11, 12, 13, 14 ,15}.

The 0x prefex on the numbers means it should be interpreted as a hexadecimal number. It is a bit superfluous when you only go up to 0x8 but tells maintainers it is probably used as a bitmask.

2
  • 1
    The wording may suggest that it can be extended to all numbers, which is not true: 8/6 is odd, while 8&6 yields false.
    – Sjoerd
    Commented Jul 2, 2014 at 11:13
  • @Sjoerd that's why I said "powers of 2" Commented Jul 2, 2014 at 11:25
5

These if-statements check if a specific bit of value is set.

The hexadecimal value 0x4, for example, has the 3rd bit from the right set to 1 and all other bits set to 0. When you use the binary-and operator (&) with two operants, the result will have all bits set to 0 except for those bits which are 1 in both operants.

So when you do the calculation value & 0x4, you either get binary 00000000 or binary 00000100, depending on whether or not the 3rd bit of value is 1 or 0. The first evaluates to false, and the second to true, so the if-block is only executed for values where the 3rd bit is set.

1

There are two interesting things to note here.

First, this is a common pattern for checking each of the low-order 4 bits of an integral value. The if condition is met if the corresponding bit is set. For the value 2 the bit pattern is indeed 0010.

The other more interesting question is why the (int) cast? Apart from the bad style of using C-casts in C++, no integer or character values require this cast. A bool makes no sense, a double/float would be converted to an integer temporary and it would be unusual to use literal values to test an enum. It might make sense with a pointer, but that would be a very specialised use. Conclusion: the cast makes no sense.

Your Answer

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