I'm just curious if there's a reason why in order to represent -1 in binary, two's complement is used: flipping the bits and adding 1?
-1 is represented by 11111111 (two's complement) rather than (to me more intuitive) 10000001 which is binary 1 with first bit as negative flag.
Disclaimer: I don't rely on binary arithmetic for my job!
The usual implementation of the operation is "flip the bits and add 1", but there's another way of defining it that probably makes the rationale clearer. 2's complement is the form you get if you take the usual unsigned representation where each bit controls the next power of 2, and just make the most significant term negative.
Taking an 8-bit value a7 a6 a5 a4 a3 a2 a1 a0
The usual unsigned binary interpretation is:
27*a7 + 26*a6 + 25*a5 + 24*a4 + 23*a3 + 22*a2 + 21*a1 + 20*a0
11111111 = 128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 = 255
The two's complement interpretation is:
-27*a7 + 26*a6 + 25*a5 + 24*a4 + 23*a3 + 22*a2 + 21*a1 + 20*a0
11111111 = -128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 = -1
None of the other bits change meaning at all, and carrying into a7 is "overflow" and not expected to work, so pretty much all of the arithmetic operations work without modification (as others have noted). Sign-magnitude generally inspect the sign bit and use different logic.
To expand on others answers:
In two's complement
Division does require a different mechanism.
All these are true because two's complement is just normal modular arithmetic, where we choose to look at some numbers as negative by subtracting the modulo.
One satisfactory answer of why Two2's Complement is used to represent negative numbers rather than One's Complement system is that Two's Complement system solves the problem of multiple representations of 0 and the need for end-around-carry which exist in the One's complement system of representing negative numbers.
For more information Visit https://en.wikipedia.org/wiki/Signed_number_representations
For End-around-carry Visit https://en.wikipedia.org/wiki/End-around_carry
A major advantage of two's-complement representation which hasn't yet been mentioned here is that the lower bits of a two's-complement sum, difference, or product are dependent only upon the corresponding bits of the operands. The reason that the 8 bit signed value for -1 is
11111111
is that subtracting any integer whose lowest 8 bits are00000001
from any other integer whose lowest 8 bits are0000000
will yield an integer whose lowest 8 bits are11111111
. Mathematically, the value -1 would be an infinite string of 1's, but all values within the range of a particular integer type will either be all 1's or all 0's past a certain point, so it's convenient for computers to "sign-extend" the most significant bit of a number as though it represented an infinite number of 1's or 0's.Two's-complement is just about the only signed-number representation that works well when dealing with types larger than a binary machine's natural word size, since when performing addition or subtraction, code can fetch the lowest chunk of each operand, compute the lowest chunk of the result, and store that, then load the next chunk of each operand, compute the next chunk of the result, and store that, etc. Thus, even a processor which requires all additions and subtractions to go through a single 8-bit register can handle 32-bit signed numbers reasonably efficiently (slower than with a 32-bit register, of course, but still workable).
When using of the any other signed representations allowed by the C Standard, every bit of the result could potentially be affected by any bit of the operands, making it necessary to either hold an entire value in registers at once or else follow computations with an extra step that would, in at least some cases, require reading, modifying, and rewriting each chunk of the result.
Reading the answers to this question, I came across this comment [edited].
In my opinion, the question asked in this comment is quite interesting and so I'd like first of all to rephrase it and then to provide an answer and an example.
QUESTION – How can the system establish how one or more adjacent bytes have to be interpreted? In particular, how can the system establish whether a given sequence of bytes is a plain binary number or a 2's complement number?
ANSWER – The system establishes how to interpret a sequence of bytes through types. Types define
EXAMPLE – Below we assume that
char
's are 1 byte longshort
's are 2 bytes longint
's andfloat
's are 4 bytes longPlease note that these sizes are specific to my system. Although pretty common, they can be different from system to system. If you're curious of what they are on your system, use the sizeof operator.
First of all we define an array containing 4 bytes and initialize all of them to the binary number
10111101
, corresponding to the hexadecimal numberBD
.Then we read the array content using different types.
unsigned char
andsigned char
unsigned short
andshort
unsigned int
,int
andfloat
The 4 bytes in RAM (
l_Just4Bytes[ 0..3 ]
) always remain exactly the same. The only thing that changes is how we interpret them.Again, we tell the system how to interpret them through types.
For instance, above we have used the following types to interpret the contents of the
l_Just4Bytes
arrayunsigned char
: 1 byte in plain binarysigned char
: 1 byte in 2's complementunsigned short
: 2 bytes in plain binary notationshort
: 2 bytes in 2's complementunsigned int
: 4 bytes in plain binary notationint
: 4 bytes in 2's complementfloat
: 4 bytes in IEEE 754 single-precision notation[EDIT] This post has been edited after the comment by user4581301. Thank you for taking the time to drop those few helpful lines!
Two's complement allows negative and positive numbers to be added together without any special logic.
If you tried to add 1 and -1 using your method
10000001 (-1)
+00000001 (1)
you get
10000010 (-2)
Instead, by using two's complement, we can add
11111111 (-1)
+00000001 (1) you get
00000000 (0)
The same is true for subtraction.
Also, if you try to subtract 4 from 6 (two positive numbers) you can 2's complement 4 and add the two together 6 + (-4) = 6 - 4 = 2
This means that subtraction and addition of both positive and negative numbers can all be done by the same circuit in the cpu.