-2

I am working on a mobile chess app and in creating the board there is this section of code, if (((row ^ col) & 1) == 0) continue;. what does the symbols ^ and & mean in this piece of code?

for (int row = 0; row < 8; row++)
    {
        for (int col = 0; col < 8; col++)
        {
            
            if (((row ^ col) & 1) == 0)
                continue;

            BoxView boxView = new BoxView
                {
                    Color = Color.FromRgb(0, 64, 0)
                };

            Rectangle rect = new Rectangle(col * squareSize,
                                           row * squareSize,
                                           squareSize, squareSize);

            absoluteLayout.Children.Add(boxView, rect);

        }
   }
Dathon Weber
  • 53
  • 2
  • 8
  • If so, please consider accepting an answer :) – Sweeper Oct 15 '20 at 03:29
  • 1
    I think combination of all *other* ways to draw chessboard with explanation what XOR is should be enough for future visitors... Indeed there are good answers here too explaining math (which is somewhat straight forward: result of `(row ^ col) & 1` is the same as `((row & 1) ^ (col & 1) & 1)` , same as `((row %2) ^ (col %2)) & 1`, same as `(row % 2 != col % 2)` or `((row % 2) == 0 && (col % 2 == 1)) || ((row % 2 == 0) && (col % 2 == 1)) ` or other variations of "parity is different". – Alexei Levenkov Oct 15 '20 at 03:45

3 Answers3

5

It's basically checking if both numbers are either odd or even, by looking the LSB (least significant bit)

In computing, the least significant bit (LSB) is the bit position in a binary integer giving the units value, that is, determining whether the number is even or odd.

10011010
       ^ least significant bit

Break down

(row ^ col) bitwise XOR.

XOR is the exclusive OR. XOR behaves like regular OR, except it’ll only produce a 1 if either one or the other numbers has a 1 in that bit-position.

    10011010
XOR 01000110
    -------- =
    11011100

(x & 1) bitwise AND with 1

AND takes two numbers and produces the conjunction of them. AND will only produce a 1 if both of the values it’s operating on are also 1.

    11011100
AND 00000001
    -------- =
    00000000 

Example

for (int row = 0; row < 8; row++)
for (int col = 0; col < 8; col++)
   if (((row ^ col) & 1) == 0)
      Console.WriteLine($"{row} {col} : {Convert.ToString(row, 2).PadLeft(8,'0')} {Convert.ToString(col, 2).PadLeft(8,'0')} ");

Output

0 0 : 00000000 00000000
0 2 : 00000000 00000010
0 4 : 00000000 00000100
0 6 : 00000000 00000110
1 1 : 00000001 00000001
1 3 : 00000001 00000011
1 5 : 00000001 00000101
1 7 : 00000001 00000111
2 0 : 00000010 00000000
2 2 : 00000010 00000010
2 4 : 00000010 00000100
2 6 : 00000010 00000110
3 1 : 00000011 00000001
3 3 : 00000011 00000011
3 5 : 00000011 00000101
3 7 : 00000011 00000111
4 0 : 00000100 00000000
4 2 : 00000100 00000010
4 4 : 00000100 00000100
4 6 : 00000100 00000110
5 1 : 00000101 00000001
5 3 : 00000101 00000011
5 5 : 00000101 00000101
5 7 : 00000101 00000111
6 0 : 00000110 00000000
6 2 : 00000110 00000010
6 4 : 00000110 00000100
6 6 : 00000110 00000110
7 1 : 00000111 00000001
7 3 : 00000111 00000011
7 5 : 00000111 00000101
7 7 : 00000111 00000111
halfer
  • 19,824
  • 17
  • 99
  • 186
TheGeneral
  • 79,002
  • 9
  • 103
  • 141
  • 1
    “*(row ^ col) logical or*“ ??? Is that not a bitwise XOR? – CoolBots Oct 15 '20 at 03:26
  • @CoolBots indeed correct, thanks – TheGeneral Oct 15 '20 at 03:27
  • no worries. Your explanation, example and output look good, but the math in the break down section seems off to me - it should also be an XOR, and then *the result* ANDed with 1 – CoolBots Oct 15 '20 at 03:33
  • @CoolBots good point as well, sorry i am debbuging a production system while i am writing this, i should do better to put actual example not just an example of the operation – TheGeneral Oct 15 '20 at 03:35
2

The if condition evaluates to true if row and col have the same parity i.e. are both even or both odd, and in that case executes continue to skip over to the next iteration.

Step by step:

  • row ^ col does a bitwise XOR, which sets each result bit to 0 iff the corresponding bits match between the operands;

  • & 1 does a bitwise AND with the lowest (least significant) bit;

  • the least significant bit indicates the parity of the number i.e. it is 0 for even numbers and 1 for odd numbers.

dxiv
  • 16,984
  • 2
  • 27
  • 49
1

^ and & are bitwise operations. ^ does an XOR on each of the bits of its operands. & does an AND on each of the bits of its operands.

& 1 is a bit mask, taking only the least significant bit (LSB) of (row ^ col). The least significant bit determines whether the number is odd or even. If it is 0, the number is odd.

The ^ operator computes the bitwise XOR of row and col, but since we have the bit mask here, we only care about the XOR of the LSB. We are checking whether the XOR of the LSB is 0. Well, it can only be 0 if both LSBs of row and col are the same, so in other words, we are checking if row and col are both even or both odd.

If row and col are both even or both odd, we skip to the next iteration of the loop (continue;). So we will only create a new rectangle when exactly one of row and col is even. If you look at a chessboard, that's where the black/white squares are.

Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • Okay That was what was confusing me, When would an iteration be skipped. thank you. – Dathon Weber Oct 15 '20 at 03:25
  • 1
    @DathonWeber The fact that it `continue`s when the condition is true doesn't _really_ matter. It will still create a chessboard pattern (a different one) if it creates a BoxView when they are both even or odd, and not do anything otherwise. – Sweeper Oct 15 '20 at 03:28