That’s right, 32767 plus 1 equals minus 32768.

The class (and students reading this posted up outside my room, as a conversation-starter) offer a few suggestions for why this might be so: mathematical weirdness, crazy teacher, magic.

There are a few ways I can explain this to a class.

**Option 1: The “I’m clever, you’re not” method.**

It goes like this: “Take my word for it, that’s how it works in 16-bit two’s complement maths. Just learn it.”

*This has precisely zero educational benefit.* It does, however make sure my class-sizes get smaller.

**Option 2: I’ll baffle you with science.**

I can describe, at great length and in abstract terms, how 16-bit numbers have a sign-and-magnitude bit at the far-left. This can simply be 1 for negative and zero for positive. So, reading right-to-left the powers of two in a 32 bit register are 1,2,4,8,16,32… 8192, 16384, +/-. In a two’s complement register, the far-left is worth -32768.

*At some point in this, their eyes glaze over and they start whispering to each other, “What is he talking about?”*

They end up knowing I’m someone who knows a lot about binary. They learn nothing else.

**Option 3:** **Let them see something counting on-screen**

It’s easy for me to write a simple program that counts 1, 2, 3, 4, 5…. 32766, 32767. -32768. I can demonstrate it on-screen and have them all going “Eh?” It’s the programming equivalent of a big bang in a chemistry lab. Do something weird, get their attention.

Better still, I can ask the class to write a program using a *while *loop, to start counting at 1 and keep going. Hopefully, they all come up with something that looks like this (this uses Object Pascal, other languages are available).

var

i: smallint;

begin

i := 1;

while i > 0 do

begin

i:=i+1;

writeln (i);

end;

end.

The output is a pile of numbers on-screen, ending like this:

32765

32766

32767

-32768

So why is that? It’s like a car’s odometer. One day it starts at 00000, then ten years later it is at 99999. The next day, it is back at 00000. If you get a really fancy car with a 6-digit odometer, it will one day go 999998, 999999, 000000. The calculation has ‘overflowed’ the space you have given it, and the counter loops back. We use a *smallint* because the alternative, *integer* would take too long to run. They’d get bored waiting. *smallint* uses 16 bits, or 16 on/off signals to store the number – 65536 options (half of the positive, the other half negative)

Though, while we discuss what 16-bit integers are, I can tell them to change i to be an *integer*. integer is a whole 32 bits – around 4 billion possible numbers.

2147483647

-2147483648

Once the class see how it works, they can be a little more receptive to binary numbers, and trying to figure out how fractions and really big numbers (like, Bill Gates’ bank balance and Greece’s national debt) get stored.

If you really want them to “get it”, have them print out the binary next to the integer.

You can show them the odometer rolling over, not just tell them. 🙂

If you want them to “get it”, maybe you can provide a simplified version in decimal. Like this:

Suppose we have a very limited number system (machine constrained). In this system we can only represent numbers with digits (0-9) and we do not have any symbols (+,-,decimal). Also we can only count up to 1999.

This system works very well for doing most basic math, within limits.

18 + 12 = 30

30 – 12 = 18

4 * 5 = 20

But it fails (does unexpected things) when we exceed our limits.

12 – 18 = *undefined*

1900 + 500 = *undefined*

What are some rules we could use for these exceptions? What should we show for these calculations? *discuss*

Clipping:

12 – 18 = 0

1900 + 500 = 1999

Rollover:

12 – 18 = 1994

1900 + 500 = 400

Clipping is bad because it loses information.

Rollover is bad because it can cause bad results when we go outside our allowed range. But rollover can also be useful. Consider this:

12 – 18 = 1994

(12 – 18) + 20 = 1994 + 20 = 14

See how this result is actually “good” when used further in the equation.

Now suppose we only work with numbers less than 1000. Any number greater than 1000 in our answer indicates it is really a negative number. And because of our rollover, it works like a negative number.

12 – 18 = 1994 –> -6

12 – 999 = 1012 –> -987

We call this 10’s complement, and we can interpret it in our usual number system simply, like so:

Any number greater than 1000 is considered negative.

Its magnitude can be found by removing the leading 1, subtracting it from 999, and then add 1.

For example, 1994:

Drop the leading 1: 994

Subtract it from 999: 005

Add 1: 006

So, 1994 ==> -6

10’s complement is confusing to read at first, but it is useful in further mathematical functions.

12 – 18 = 12 + (-18) = 12 + 1982 = 1994 –> -6

12 – 999 = 12 + (-999) = 12 + 1000 = 1012 –> -987

Etc.

And then make the leap to binary and 2’s complement.