How does a computer know 2 + 3 = 5?

Ivy Tsoi
8 min readAug 19, 2018

--

At first glance, this may sound like a silly question—isn’t it just like how we know 2 + 3 = 5? We somehow learned how to count (1, 2, 3, 4, 5…) and we understand addition through counting (and the natural number series). We know that 2 + 3 = 5 because we know that if we start counting at 2, after we count 3 times, we would get to 5. Doesn’t a computer just count in binary numbers?

A conventional computer stores and processes everything in 0s and 1s. (Source: Wikipedia)

Well, no.

While a computer can represent numbers in their binary form—combinations of 0s (off/false) and 1s (on/true), how does a computer know the relations between, say, 10 (2), 11 (3), and 101 (5)? How does it know that 10 is followed by 11, 11 is followed by 100, and 100 is followed by 101? A computer knows the logical relations between combinations of 0 and 1 in virtue of how we construct its logic circuits, but how can it go from this sort of relations—which are essentially relations between Booleans—to the relations between numbers? If it doesn’t know the relations between numbers, how does it add?

To put the question differently, how does a computer know that adding 10 and 11 should result in 101? We can arbitrarily decide that a certain combination of 0s and 1s represents addition, but what is the computer supposed to do upon seeing its version of the “+” sign? In other words, how should the computer manipulate the 0s and 1s in the two input numbers to yield a new number, a new combination of 0s and 1s?

Before answering these questions, let’s consider how we, humans, add two binary numbers together.

Binary Addition by Human

The addition of binary numbers is very much like the addition of “normal” (decimal) numbers. Suppose we add 10 and 11. The first digit of 10 is 0 and the first digit of 11 is 1. 1 + 0 = 1, so we know that the first digit of the result should also be 1:

   10       10
+ 11 -> + 11
= ??? = __1

The second digits of 10 and 11 are both 1. 1 + 1 = 10 (remember, we are adding in binary—there is no 2 in the binary system). So we know that in the result, there is a 1 that gets carry over to the third digit, and there is nothing left for the second digit:

   10       10      `10
+ 11 -> + 11 -> + 11
= ??? = __1 = _01

The third digits of 10 and 11 are both 0. So the third digit of the result will be 0 + 1 (the carry) = 1

   10       10      `10       10
+ 11 -> + 11 -> + 11 -> + 11
= ??? = __1 = _01 = 101

Notice that while we do know the relations between binary numbers 10, 11 and 101 (e.g., 10 is followed by 11, 101 is greater than 11…), such knowledge is not necessary for performing the operation above.

How may a computer mimic this operation? We can think of this operation as embodying two kinds of “sub-operation”—adding 0 and 1 (no carry) and adding 1 and 1 (carry). Adding 0 and 1 at the nth digit of the input numbers yields a 1 at the nth digit of the resulting output. Adding 1 and 1 at the nth digit of the input adds 1 to the (n+1)th digit of the output. A computer can mimic these sub-operations by logic and shift operations. Before we dive into exactly how that works, let’s review what logic and shift operations are.

Logic and Shift Operations

Logic operators: AND and XOR

A logic operation takes input(s) that is/are either true or false (represented as 0 and 1 in a computer) and produces an output that is either true or false. For the purpose of this article, we will only look at two logic operators: AND and XOR.

To understand AND, let’s consider its analogue in English—“and.” We often use “and” to connect two declarative sentences together to form a new declarative sentence (e.g., “Cody is a pug and a pug is a dog”). A declarative sentence can be true or false (e.g., if Cody is not a pug, then the sentence “Cody is a pug” is false).

Now, “Cody is a pug and a pug is a dog” is true if, and only if, both “Cody is a pug” and “A pug is a dog” are true. In other words, whether “Cody is a pug and a pug is a dog” is true depends on whether the parts that form the sentence are true.

Abstract away the content of these English sentences, we have something like the following:

  • If A is true and B is true (where A and B represent certain declarative sentences), A and B is true.
  • If A is true and B is false, A and B is false.
  • If A is false and B is true, A and B is false.
  • If A is false and B is false, A and B is false.

And we can describe English sentential connective “and” in a table—a truth table—like this:

A | B | A and B
---------------
T | T | T
T | F | F
F | T | F
F | F | F

Now, we can understand logic operator AND in a similar fashion. The input has two bits and the output has one bit. Whether the output is 0 or 1 depends on the “truth” of the input bits. So AND can be described by the following truth table (A and B represent the input bits):

A | B | A AND B
---------------
1 | 1 | 1
1 | 0 | 0
0 | 1 | 0
0 | 0 | 0
The logic gate symbol of AND. (Source: Wikipedia)

Similarly, XOR has an English analogue—the exclusive “or,” as in “either A is true or B is true, but not both.” XOR can be described by the following truth table:

A | B | A XOR B
---------------
1 | 1 | 0
1 | 0 | 1
0 | 1 | 1
0 | 0 | 0
The logic gate symbol of XOR. (Source: Wikipedia)

Bit Shifting

Metaphorically speaking, a shift operation “moves” a combination of bits to the “left” or to the “right.” For example, if we shift 10101 to the left by one bit, we get 101010. If we shift 10101 to the right by one bit, we get 1010.

When a computer represents a binary number with a combination of bits, shifting the bits to the left by one bit would in effect multiplies the binary number by 2, and shifting the bits to the right by one bit would in effect divides the binary number by 2.

Shifting a byte to the left by one bit. (Source: School Coders)

Now that we understand what logic and shift operations are, let’s talk about how a computer actually adds.

Binary Addition by Computer

Suppose a computer is to add 10 and 11 together (for the sake of readability, let’s assume that the computer represents each number in four bits). What should happen next? Remember, the computer is going to mimic the following “sub-operations”: 0 + 1 = 1 (no carry) and 1 + 1 = 10 (carry).

To begin, let’s stack the two numbers up and compare them digit by digit:

0010
0011

There are two things to notice. First, there is a 0 + 1 = 1 operation at the first digit of the input numbers. The computer can see that using the XOR operator:

XOR 0010
0011
= 0001

Second, there is a 1 + 1 = 10 operation at the second digit of the input numbers. The computer can see that using the AND operator:

XOR 0010 | AND 0010
0011 | 0011
= 0001 | = 0010

After that, the computer can carry the 1 over from the second digit to the third digit by shifting the result of the AND operation (i.e. 0010) to the left by one bit:

XOR 0010 | AND 0010 | << 0010
0011 | 0011 |
= 0001 | = 0010 | = 0100

Then the computer can add the result of the shift operation (the carry, 0100) to the result of the XOR operation (i.e. 0001) by another XOR operation:

XOR 0010 | AND 0010 | << 0010
0011 | 0011 |
= 0001 | = 0010 | = 0100
XOR 0001
0100
= 0101

Now, to check and see whether there is any more carry to handle after handling the carry it found above, the computer can perform another AND operation on the result of the shift operation and the result of the first XOR operation:

XOR 0010 | AND 0010 | << 0010
0011 | 0011 |
= 0001 | = 0010 | = 0100
XOR 0001 | AND 0001
0100 | 0100
= 0101 | = 0000 <- No carry

Then, boom! The computer gets the result of adding 10 and 11 together, 101, using logic and shift operations only.

To summarize, from a computer’s perspective, adding two numbers together is a sequence of logic and shift operations. Unlike us, a computer need not know that 5 is 3 numbers after 2 before it can figure out 2 + 3 = 5. In other words, a computer need not know the relations between numbers before it can add. It just needs to know Boolean logic (and how to move bits left and right).

An Illustration in JavaScript

Bitwise operators operate on binary numerals at the level of their individual bits. JavaScript has bitwise operators for both logic and shift operations. These operators treat a numerical value as a 32-bit binary integer. Here is an illustration in JavaScript of what we have talked about so far.

Try running this Repl.

A philosophical note: I am not taking a side in the debate about whether a computer can actually know, see or figure out anything. I just think that putting quotation marks everywhere would be obnoxious.

--

--