It uses a binary representation called two's complement. This system is pretty much ubiquitous - almost any computer you're likely to come across, whether it's a PC, mainframe, or a cellphone, is likely to use this system.

You can indeed tell the sign by looking at the top bit, but it's not as simple as saying that '00000010' is 2 and '10000010' is minus 2 - that's not how it works. Instead, negative numbers are created by inverting all the bits and then adding 1.

So let's take 2. Positive 2 is '00000010'. Flip the bits - you get '11111101'. Finally add 1. You get '11111110'.

Why do this Two reasons. First, it means you don't waste a bit pattern by having two different zeros. (You don't need both a negative zero and a positive zero.) Secondly, and more importantly, it means you can use exactly the same hardware to perform signed arithmetic and unsigned arithmetic. Let's look at what happens if you add 4 to '11111110':

11111110

+00000100

--------

100000010

Notice that the result doesn't fit into 8 bits. Truncating into 8 we get '00000010'. So in other words, by adding 4, we ended up with 2. That's what we'd expect given that we started with -2!

So that's the major appeal of 2's complement. Using hardware designed to add unsigned numbers together, and then truncating the results turns out to produce the correct results for signed numbers too!

So, why -128 rather than -127 Well the short answer is because we add 1 after flipping the bits, so negative numbers end up getting one extra number.

The alternative way of looking at it though is that 0 throws a spanner in the works. You can represent 128 numbers with the top bit set and another 128 numbers with the top bit cleared. Zero has to come somewhere, and we represent that as all zero digits, obviously enough. This means that zero gets to 'steal' one of the values with the top bit clear. There are 128 non-negative numbers: 0 through 127.

It would be a waste to have a separate representation for negative zero. (Actually, floating point does support that, but FP is different.) So we get to use all 128 top-bit-set bit patterns for negative numbers. Since we don't 'waste' one pattern for 0, this means we can go from -1 to -128.

Hope that helps.