Home

Binary Numbers


Bases and Positional Notation

To understand binary numbers, we first have to understand a little more about our own number system, which is based on Base 10. In Base 10, we have a total of 10 digits (0, 1, 2, 3, 4, 5, 6, 7, 8, and 9), which we use in conjunction with something called positional notation to write our numbers. If we write some number, say 6,283.475, we are saying that there are 6 thousands, 2 hundreds, 8 tens, 3 ones, 7 tenths, 4 hundredths, and 5 thousandths. We use the digits to relate how many of each place value we have, and then add them all up. These place values may have seemed a bit arbitrary when you first learned them, but there is actually a very special reason we use those numbers: each position (the 1s, 10s, 100s, etc) is a power of 10. For further clarification, see the below table:

103 's 102 's 101 's 100 's 10-1 's 10-2 's 10-3 's
1000's 100's 10's 1's 0.1's 0.01's 0.001's
6, 2 8 3. 7 4 5

In the above table, we see the number 6,283.745; what this means is that we have 6 103 's, 2 102 's, 8 101 's, 3 100 's, 7 10-1 's, 4 10-2 's, and 5 10-3 's, all added together. This can also be written as we did before, as 6 thousands, 2 hundreds, 8 tens, 3 ones, 7 tenths, 4 hundredths, and 5 thousandths, or as 6*1000 + 2*100 + 8*10 + 3*1 + 7/10 + 4/100 + 5/1000. So what does this have to do with binary? Binary is just Base 2. That means that we only have 2 digits, 1 and 0, to use in our positional notation place value system. Let's look at another table:

23 's 22 's 21 's 20 's 2-1 's 2-2 's 2-3 's
8's 4's 2's 1's 1/2's 1/4's 1/8's
1 0 1 1. 0 1 1

What does this mean? We now have the binary number 1011.011; it has only two digits, representing how many of each positional value we have. We have 1 eight, 0 fours, 1 two, 1 one, 0 halves, 1 fourth, and 1 eighth. We could also say that we have 1 23 's, 0 22 's, 1 21 's, 1 20 's, 0 2-1 's, 1 2-2 's, and 1 2-3 's, all added together. In base ten, we would represent this number as 8 + 2 + 1 + 1/4 + 1/8 = 11 + 3/8 = 11.375. That is to say, 1011.0112 = 11.37510. As you can see, we use subscripts to clarify what base a number is in. You can assume that if there is a subcript 2 like this: 1011010011012, it is in base 2, while if there is no subscript, it is in base 10. Extra challenge: what is 1011010011012 in base 10? Hover here to reveal the answer: | 2893 |

Binary as Data

Binary is really nice for usage within digital systems, such as computers, because they only have two states: 1 and 0; true and false; on and off. A circuit with high voltage is considered a 1, while a circuit with low or no voltage is considered a 0. When we write binary numbers in the context of computers, we have a few special terms to use with them: we call a single digit in a binary number a bit, we call a sequence of 8 bits a byte, and we call a sequence of four bits, half a byte, a nibble. So in the number 101101002, each 1 or 0 is a bit, therefore there are eight bits in the number. This means that the number is a single byte of data, or two nibbles of data. I don't know the origins of those terms, but they are very important for a thorough understanding of binary.

Operators

Now, we need to talk about arithmetic and logical operations on binary numbers. An operation is something which tells you what to do with a value or several values, called operands. Operators can be unary, meaning they only operate on one operand, or binary, meaning they operate on two operands. Operators which operate on n values are called n-ary operators, but we won't worry about anything beyond unary or binary for now. Examples of binary operators are the arithmetic operations (addition, subtraction, multiplication, and division) and exponentiation. Examples of unary operators would be absolute value (|x|), factorial (x!), or inverse (the additive inverse is -x while the multiplicative inverse is 1/x).

For binary numbers, we actually have some other operations which we didn't have for base 10: NOT, AND, OR, and XOR, all of which are binary except for NOT, which is unary. These are known as bitwise operators, because they operate on pairs of bits between two binary numbers.

NOT

NOT (also known as the logical complement) is a unary bitwise operator which effectively flips each bit of the operand. For example, the operation NOT 11012 results in 00102. Likewise, NOT 00102 results in 11012. This tells us that NOT NOT n is equal to the original n, meaning that it effectively undoes itself. NOT NOT NOT NOT NOT n = NOT n, because the first four NOT's cancel out. Please note that NOT is generally symbolized by an exclamation point, so !x means NOT x.

AND

AND is a binary bitwise operator which compares each pair of bits in the same position in the two operands, setting the output bit in that position based on the values of the pair of input bits. If both input bits are 1, so operand 1's bit AND operand 2's bit are both 1, the result's bit in that same place will be 1. If either operand's bit is a 0 (or if both are 0), the output bit in that place will be 0. So for example, 11012 AND 10012 results in 10012. This can be seen better by stacking the two numbers on top of each other:

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

If a 1 and a 1 are on top of each other, the result in that place is a 1. Otherwise the result is a 0 there. Pretty simple. Notice that the symbol for the AND operation is the &. Another example where each operand is a full byte:

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

OR

OR, like AND, is a binary bitwise operator which compares each pair of bits in the same position in the two operands, setting the output bit in that position based on the values of the pair of input bits. If one input bit (or both) are 1, so operand 1's value at that place OR operand 2's value at that place is 1, the result in that place will be a 1. The only way to get a 0 is to get two input 0's. So for example, 11012 OR 10012 results in 11012. This can be seen better by stacking the two numbers on top of each other:

1 1 0 1
| 1 0 0 1
= 1 1 0 1

If either place has a 1, the result is a 1. If both are 0, the result is a 0. Notice that the symbol for the OR operation is the |. Another example where each operand is a full byte:

1 0 1 1 0 0 1 1
| 1 1 1 1 0 0 0 1
= 1 1 1 1 0 0 1 1

XOR

XOR, like AND and OR, is a binary bitwise operator which compares each pair of bits in the same position in the two operands, setting the output bit in that position based on the values of the pair of input bits. XOR is like a restrictive form of OR, so if either operand 1's value OR operand 2's value are 1, the result is a 1. However, if both operands' values are 1, the result is a 0. If both operands' values are 0, the result is also 0. So for example, 11012 XOR 10012 results in 01002. This can be seen better by stacking the two numbers on top of each other:

1 1 0 1
^ 1 0 0 1
= 0 1 0 0

If a 1 and another 1 are on top of each other, or if a 0 and another 0 are on top of each other, the result is a 0. To get a 1, only one input can be a 1. Notice that XOR is represented by a ^. Another example where each operand is a full byte:

1 0 1 1 0 0 1 1
^ 1 1 1 1 0 0 0 1
= 0 1 0 0 0 0 1 0

I also strongly suggest that you visit the wikipedia page on bitwise operators for more in-depth information: Bitwise Operations

Two's Complement

You may have read all of this and wondered "Hey, where are the negative numbers? How can you perform a bitwise operation on the minus sign?". Well, the short answer is that you don't. You have to use the bits in the number to represent both positive and negative numbers, and the way you do that is with Two's Complement.

To understand Two's Complement, we have to first recognize that in a 4 bit number, there are 16 possible values (0 - 15 or 00002 - 11112). Similarly, in an 8 bit number, there are 256 possible values: 0 - 255 or 000000002 - 111111112. However, what we do with Two's Complement is decide that the first half of those values, 0 to 127 in the 8 bit case, will represent the numbers 0 to 127, while the numbers 128 to 256 will represent the numbers -128 to -1. A little confusing, right? Let's use a chart to see what happens as we go up in values in a 4 bit number, and hopefully make it a little more clear.

0000 0 0 0000
0001 1 1 0001
0010 2 2 0010
0011 3 3 0011
0100 4 4 0100
0101 5 5 0101
0110 6 6 0110
0111 7 7 0111
1000 8 -8 0111
1001 9 -7 0110
1010 10 -6 0101
1011 11 -5 0100
1100 12 -4 0011
1101 13 -3 0010
1110 14 -2 0001
1111 15 -1 0000

We have four columns: from the left, the first one is the binary numbers from 0 to 15; the second one is the decimal numbers from 0 to 15; the third column is the two's complement meaning of each number; the fourth column is the binary representation of the two's complement number but inverted. As you can see, we can use 4 bits, which would normally represent the numbers 0 to 15, to represent the numbers -8 to +7. Another thing that you can notice is that for the negative numbers, the fourth column is exactly the inverse of the first one.

What this means is that if you want to convert from a positive number to it's respective negative number in two's complement representation, just subtract one from the binary representation of the positive number and then invert it. To get -2 from 2, take 00102, subtract 1 to get 00012, and then invert it to get 11102. This gives you the binary representation of -2 using two's complement. Similarly, to convert from a two's complement negative number to a positive number, subtract one and then invert it. For example, to get from -3 to 3, we take the two's complement representing -3, which is 11012, subtract one to get 11002, and then invert it to get 00112, which indeed does equal 3. Basically, to convert back and forth, first subtract one, then apply logical complement (NOT) to invert it.

This might seem really convoluted as a method of writing negative numbers, but it has the advantage that performing the arithmetic operations on unsigned (non-two's complement/only positive) binary numbers is identical to performing it on two's complement numbers. Knowing the ins and outs of binary numbers isn't important as a rule when programming, and you could probably get by without it, but depending on what type of work you end up doing, it comes in very handy. In any case, I'm a firm believer in knowing things for the sake of knowing more about the world, so in my opinion knowing this information is inherently valuable, no justification required.

Additionally, I strongly encourage a visit to the wikipedia page on two's complement for further information, as well as more nice charts: Two's Complement.


Home    Back to Top