**What is Binary**

Like our decimal number system, binary is another way of representing numbers. Instead of counting in 10s (decimal), you count in 2s (binary). Each value in a binary number is either 0 or 1. You can add, subtract, multiply, and do other types of arithmetic on binary numbers, just like you can with decimal numbers.

**In decimal: **45,939 = 40,000 + 5,000 + 900 + 30 + 9

4 |
4 * 10 ^ 4 |
40,000 |

5 |
5 * 10 ^ 3 |
5,000 |

9 |
9 * 10 ^ 2 |
900 |

3 |
3 * 10 ^ 1 |
30 |

9 |
9 * 10 ^ 0 |
9 |

**In binary: **101010 =32 + 0 + 8 + 0 + 2 + 0 = 42

1 |
1 * 2 ^ 5 |
32 |

0 |
0 * 2 ^ 4 |
0 |

1 |
1 * 2 ^ 3 |
8 |

0 |
0 * 2 ^ 2 |
0 |

1 |
1 * 2 ^ 1 |
2 |

0 |
0 * 2 ^ 0 |
0 |

**So, what’s your point?**

So, that’s great, we can now count in a different language… but why do we care? Well, when you’re coding, even when you type in regular decimal numbers, the compiler is converting them to binary before the computer has a chance to read them. That’s right… your computer reads binary!

Let’s say you want to store the number 27 (11011) as a variable for your program. Your compiler will tell you computer that it needs to reserve 1 byte of memory (or, 8 bits), and ask it to store the following binary number there: 0001 1011. Each digit takes up one bit of data. The extra zeros at the front don’t affect the value of the number; they just pad out the rest of the 8-bit sized byte. Each digit signals the computer off (0) or on (1). So, when you write 27, what you’re actually telling the computer is off-off-off-on-on-off-on-on, which the computer knows means 27.

So, to review:

- Binary numbers are padded at the front so that they will take up memory in byte-sized chunks (11011 becomes 0001 1011)
- These extra zeros don’t change the value, they just reserve the space in memory so the computer doesn’t mix up this value with another value

**Bitwise Operations in C#**

Now that we understand how binary numbers are stored in memory, let’s talk about C# bitwise operators. In our example from before, our variable that stores the number 27 is stored as 0001 1011 in memory. These individual bits make up 27, but the bits can also be acted on individually. That’s where bitwise operators come in. These are logical operator similar to && (logical and) and || (logical Or) that you’ve probably used in programming before. Here is how they work:

**Logical And ( & )**

Returns a value where there is a 1 if both original numbers had a 1 in that position. If not, there is a 0 in that position.

Example: 0110 1001 & 0000 1111 = 0000 1001

**Logical Or ( | )**

Returns a value where there is a 1 if at least one of the original numbers had a 1 in that position.If not, there is a 0 in that position.

Example: 0110 1001 & 0000 1111 = 0110 1111

**Exclusive Or ( ^ )**

Returns a value where there is a 1 if only one of the original numbers had a 1 in that position.If not, there is a 0 in that position.

Example: 0110 1001 & 0000 1111 = 01100110

**Complement ( ~ )**

Returns a value that is the exact opposite of the bit values of the given values; 1 becomes 0 and 0 becomes 1.

Example ~1100 1101 = 0011 0010

**Shift Left ( << )**

Takes in a value and a number that represents how many digits to shift. The result is a new binary number where the original number has been shifted x amount of positions to the left, and then padded out with zeros on the far right side.

Example: 0010 1001 << 2 = 1010 0100

**Shift Right ( >> )**

Takes in a value and a number that represents how many digits to shift. The result is a new binary number where the original number has been shifted x amount of positions to the right, and then padded out with zeros on the far left side.

Example: 0010 1001 >> 3 = 0000 0101

**Negative Numbers**

Up until now, we’ve only worked with positive numbers in binary, but there are actually a couple of different ways to express negative numbers in binary. The most common way is via Two’s Complement. Here are the rules:

- When working with two’s compliment binary numbers, we must predetermine what size number we’re working with (4-bite, 8-bite, 16-bite, etc), and then pad out with zeros as needed.
- The left most bit, known as the Most Significant Bit, in addition to representing a number, now also represents whether the entire number is positive or negative.
- Numbers that use Two’s Complement are known as ‘signed,’ whereas the numbers we’ve been working with up until this point are known as ‘unsigned.’
- To get the Two’s Complement version of an unsigned binary number, you simply invert it (reverse the 1s and 0s), and then add 1 to the final result.

-13 |
Start with a negative number |

13 |
Take the absolute value |

1101 |
Convert the positive number to binary |

0000 1101 |
Pad out the number with extra 0s to be the amount of bits as established (8 bit in this case) |

1111 0010 |
Invert the number |

1111 0011 |
Add 1 to the final result |

-13 |
Convert back to decimal (-128 + 64 + 32 + 16 + 2 + 1 = -13) |

**Real World Application**

Using bitwise operators to determine if an item exists within a collection of items. This first example makes it pretty simple to understand because of the enum. However, enum also has a build in method (Enum.HasFlag(Enum flag)) that does the same thing. Still a good example!

public class Program
{
// Each item in the enum aligns with a base 2 number
public enum Animals {Cat=1, Dog=2, Elephant=4, Hippo=8, Rhino=16, Giraffe=32};
public static void Main(string[] args)
{
// Use bitwise OR operator to get binary value 0011 1100
Animals myFavAnimals = Animals.Elephant | Animals.Hippo | Animals.Rhino | Animals.Giraffe;
// Do an AND compare between our collection (0011 1100) and the item we're checking for (0000 0001).
// In this case, & will return 0000 0000, so the check will be false
if ((myFavAnimals & Animals.Cat) == Animals.Cat){
Console.WriteLine("Cats are one of my favorite animals");
} else {
Console.WriteLine("Cats are NOT one of my favorite animals");
}
// ((0011 1100) & (0000 0100) = 00000100 == 0000 0100) evaluates to true
if ((myFavAnimals & Animals.Elephant) == Animals.Elephant){
Console.WriteLine("Elephants are one of my favorite animals");
} else {
Console.WriteLine("Elephants are NOT one of my favorite animals");
}
}
}

Another example uses binary operators to help solve a Sudoku. This method takes in a collection of Sudoku values (a row, a column, or the values in a square) and then validates if there are any repeats

private bool ValidateValues(int[] values)
{
int flag = 0;
foreach (int value in values)
{
if (value != 0)
{
// get the bit that will represent n, where the flagged value (the 1) is in the value-th position in the binary number
int thisBit = 1 << value;
if ((thisBit & flag) != 0)
{
// there is a duplicate, because n lined up with a bit that has already been accounted for in values
return false;
}
// No duplicate. Glad this value in the overall flag for next time
flag |= thisBit;
}
}
return true;
}

**Resources**

This topic is especially difficult to grasp at first. When I first learned this stuff, my exact thought was “Why do I care?” It seemed irrelevant and way too difficult to make it worth it. Coming back to it a few months later, it’s so much easier to understand, and I was able to get the real-world application. Here are a few of the links that I found the most helpful: