views:

1413

answers:

7

In a TC++ compiler, the binary representation of 5 is (00000000000000101). I know that negative numbers are stored as 2's complement, thus -5 in binary is (111111111111011). The most significant bit (sign bit) is 1 which tells that it is a negative number.

So how does the compiler know that it is -5? If we interpret the binary value given above (111111111111011) as an unsigned number, it will turn out completely different?

Also, why is the 1's compliment of 5 -6 (1111111111111010)?

+2  A: 

The first bit is set only for negative numbers (it's called the sign bit)

Detailed information is available here

Brann
But for unsigned int first bit can be set and it is still positive number.
klew
A: 

It's exactly that most significant bit -- if you know a number is signed, then if the MSB=1 the compiler (and the runtime!) knows to interpret it as negative. This is why c-like languages have both integers (positive and negative) and unsigned integers -- in that case you interpret them all as positive. Hence a signed byte goes from -128 to 127, but an unsigned byte from 0 to 255.

Andrew Jaffe
Actually, a signed byte goes from -128 to 127.
RobH
+8  A: 

The compiler doesn't know. If you cast -5 to unsigned int you'll get 32763.

vartec
Yep, the cast tells the compiler how to interpret bits at a certain memory location. Generally it has its own idea of what resides where, but a cast throws a wrench into things.
Dan
Well, you don't even have to do explicit cast.
vartec
yeah the compiler just does the math. if u cast -5 to unsigned int, result is always UINT_MAX+1-5, whether it has sign-magnitude/two-complement/one complement is irrelevant.
Johannes Schaub - litb
+1  A: 

If the number is declared as a signed data type (and not type cast to an unsigned type), then the compiler will know that, when the sign bit is 1, it's a negative number. As for why 2's complement is used instead of 1's complement, you don't want to be able to have a value of -0, which 1's complement would allow you to do, so they invented 2's complement to fix that.

RobH
I believe the real reason was to allow machine language add/subtract algorithms to ignore the sign of the oeprands and simply do a bitwise addition or subtraction, carrying bit when necessary...
Charles Bretana
+5  A: 

The compiler knows because this is the convention the CPU uses natively. Your computer has a CPU that stores negative numbers in two's complement notation, so the compiler follows suit. If your CPU supported one's complement notation, the compiler would use that (as is the case with IEEE floats, incidentally).

The Wikipedia article on the topic explains how two's complement notation works.

greyfade
+1: Quote some useful docs; +1: it's hardware; +1: the compiler doesn't "know" anything about the number -- you declared it signed or unsigned -- you have to then use it consistently with the declaration.
S.Lott
+3  A: 

The processor implements signed and unsigned instructions, which will operate on the binary number representation differently. The compiler knows which of these instructions to emit based on the type of the operands involved (i.e. int vs. unsigned int).

The compiler doesn't need to know if a number is negative or not, it simply emits the correct machine or intermediate language instructions for the types involved. The processor or runtime's implementation of these instructions usually doesn't much care if the number is negative or not either, as the formulation of two's complement arithmetic is such that it is the same for positive or negative numbers (in fact, this is the chief advantage of two's complement arithmetic). What would need to know if a number is negative would be something like printf(), and as Andrew Jaffe pointed out, the MSBit being set is indicative of a negative number in two's complement.

Matt J
+2  A: 

The kewl part of two's complement is that the machine language Add, and Subtract instructions can ignore all that, and just do binary arithmetic and it just works...

i.e., -3 + 4

in Binary 2's complement, is

   1111 1111 1111 1101   (-3)
+  0000 0000 0000 0100   ( 4)
   -------------------
   0000 0000 0000 0001   ( 1)
Charles Bretana
You know, I completely forgot about that property of 2's complement. That's probably another good reason why it was invented.
RobH
exactly the reason
Charles Bretana