Rectangle 27 1

binary Why prefer two's complement over sign and magnitude for signed numbers?


In other words, adding is the same, wether or not the number is negative.

Nothing changes when writes or reads. Only applicable when addition or subtraction.

Sir , if i write char a = 12 ; and unsigned char b = 12 , is the underlying bit patter same , what really happens ?

The two's-complement system has the advantage of not requiring that the addition and subtraction circuitry examine the signs of the operands to determine whether to add or subtract. This property makes the system both simpler to implement and capable of easily handling higher precision arithmetic. Also, zero has only a single representation, obviating the subtleties associated with negative zero, which exists in ones'-complement systems.

Note
Rectangle 27 1

binary Why prefer two's complement over sign and magnitude for signed numbers?


0001 (one, in four bits)
00000001 (one, in eight bits)
    1010 (negative two, in four bits)
10000010 (negative two, in eight bits)
0010
+ 1001
= 1011
0010
+ 1111
=10001
= 0001 (discard the carry)
0000  "zero"
1000  "negative zero"
how we arrived at 2s compliment the first place.

0001 is 1, which is the expected result of "2+(-1)" to be.

@Nathan Fellman: Two's complement math isn't hard. I wrote most of it within my 5-minute edit window.

Additionally, in the "intuitive" storage method, there are two zeroes:

Did you actually type this up in two minutes?? The original question was asked 8 minutes ago, and this answer was posted 6 minutes ago. Are you truly the Fastest Gun in the West?

For this "intuitive" storage method, subtraction is a different operation than addition, requiring additional checks on the numbers before they can be added. Since you want the most basic operations (addition, subtraction, etc) to be as fast as possible, you need to store numbers in a way that lets you use the simplest algorithms possible.

It's done so that addition doesn't need to have any special logic for dealing with negative numbers. Check out the article on Wikipedia.

It's just a matter of looking at the sign bit of the smaller word and repeating it until it pads the width of the bigger word.

Say you have two numbers, 2 and -1. In your "intuitive" way of representing numbers, they would be 0010 and 1001, respectively (I'm sticking to 4 bits for size). In the two's complement way, they are 0010 and 1111. Now, let's say I want to add them.

There's another bonus with storing ints this way, and that's when you need to extend the width of the register the value is being stored in. With two's complement, storing a 4-bit number in an 8-bit register is a matter of repeating its most significant bit:

Two's complement addition is very simple. You add numbers normally and any carry bit at the end is discarded. So they're added as follows:

Which are intuitively the same number but have two different values when stored. Every application will need to take extra steps to make sure that non-zero values are also not negative zero.

Which is -3, right? Simple addition doesn't work in this case. You need to note that one of the numbers is negative and use a different algorithm if that's the case.

With your method you would need to clear the existing bit, which is an extra operation in addition to padding:

You still need to set those extra 4 bits in both cases, but in the "intuitive" case you need to clear the 5th bit as well. It's one tiny extra step in one of the most fundamental and common operations present in every application.

cool thanks. that's been bugging me for a while

Note
Rectangle 27 1

binary Why prefer two's complement over sign and magnitude for signed numbers?


@SurajJain: On two's-complement systems where "char" is smaller than "int" [i.e. the vast majority of systems], the signed and unsigned char types will behave identically except that signed types will be sign-extended when read and unsigned types won't. On such a system, storing the value 194 or -62 into a signed char will write the same bit pattern as storing 194 or -62 into an unsigned char (i.e. 11000010). Reading that bit pattern from a signed char will yield -62, and reading it from an unsigned char will yield 194.

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 are 00000001 from any other integer whose lowest 8 bits are 0000000 will yield an integer whose lowest 8 bits are 11111111. 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.

Please Format Your Answer In Paragraph and mark code as code , it would be more readable and you will get upvote.

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.

Yeah , better than what it earlier was , i want to ask you one thing what is the difference between signed char a = 1 and unsigned char a = 1 , how are they represented in memory.

Note
Rectangle 27 1

binary Why prefer two's complement over sign and magnitude for signed numbers?


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.

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.

Note
Rectangle 27 1

binary Why prefer two's complement over sign and magnitude for signed numbers?


// 10111101 as a PLAIN BINARY number equals 189
printf( "l_Just4Bytes as unsigned char  -> %hi\n", *( ( unsigned char* )l_Just4Bytes ) );

// 10111101 as a 2'S COMPLEMENT number equals -67
printf( "l_Just4Bytes as signed char    -> %i\n", *( ( signed char* )l_Just4Bytes ) );
// 1011110110111101 as a PLAIN BINARY number equals 48573
printf( "l_Just4Bytes as unsigned short -> %hu\n", *( ( unsigned short* )l_Just4Bytes ) );

// 1011110110111101 as a 2'S COMPLEMENT number equals -16963
printf( "l_Just4Bytes as short          -> %hi\n", *( ( short* )l_Just4Bytes ) );
// 10111101101111011011110110111101 as a PLAIN BINARY number equals 3183328701
printf( "l_Just4Bytes as unsigned int   -> %u\n", *( ( unsigned int* )l_Just4Bytes ) );

// 10111101101111011011110110111101 as a 2'S COMPLEMENT number equals -1111638595
printf( "l_Just4Bytes as int            -> %i\n", *( ( int* )l_Just4Bytes ) );

// 10111101101111011011110110111101 as a IEEE 754 SINGLE-PRECISION number equals -0.092647
printf( "l_Just4Bytes as float          -> %f\n", *( ( float* )l_Just4Bytes ) );
// BD(hexadecimal) = 10111101 (binary)
unsigned char   l_Just4Bytes[ 4 ]   =   { 0xBD, 0xBD, 0xBD, 0xBD };
char
float
int
short
signed char
unsigned char
unsigned int
unsigned short
  • how many bytes have to be considered
  • how those bytes have to be interpreted
  • int's and float's are 4 bytes long
  • short: 2 bytes in 2's complement

+1. One thing you might consider doing, @mw215, is making this question/answer pair a Community Wiki entry on its own, because it's useful for people who might be interested in raw byte interpretation outside of the context of two's complement math.

2's complement of 0100(4) will be 1100. Now 1100 is 12 if I say normally. So, when I say normal 1100 then it is 12, but when I say 2's complement 1100 then it is -4? Also, in Java when 1100 (lets assume 4 bits for now) is stored then how it is determined if it is +12 or -4 ?? hagrawal Jul 2 at 16:53

@Suraj Jain The system establishes how to interpret a sequence of bytes through types. Types define: how many bytes have to be considered and how those bytes have to be interpreted. An int is 4 bytes in 2's complement and an unsigned int is 4 bytes in plain binary notation (check the actual type size on your system using the sizeof operator).

@Suraj Jain When using int types, the signed modifier is default. This means that int and signed int are exactly the same type. Thus the two definitions int i = -4; and signed int i = -4; have the same meaning.

ANSWER The system establishes how to interpret a sequence of bytes through types. Types define

Again, we tell the system how to interpret them through types.

EXAMPLE Below we assume that

First of all we define an array containing 4 bytes and initialize all of them to the binary number 10111101, corresponding to the hexadecimal number BD.

For instance, above we have used the following types to interpret the contents of the l_Just4Bytes array

I Just want to know is 2's complement always follow , i mean if i have int x = -4 , and i then do printf("%d" , x) how does it get interpreted ? Also what is the difference between unsigned int and signed int and %d and %u ... this has been bugging me for a long time now .Thanks.

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.

Please 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.

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?

That code blob needs an edit so readers don't have to keep scrolling back and forth. Better, that massive comment at the top should become plain old text and let the renderer take care of the formatting. You should also add a caveat to the bit near the end where you discuss the sizes and formatting because the sizes are not fixed.

The 4 bytes in RAM (l_Just4Bytes[ 0..3 ]) always remain exactly the same. The only thing that changes is how we interpret them.

Then we read the array content using different types.

Note
Rectangle 27 1

binary Why prefer two's complement over sign and magnitude for signed numbers?


It's worthwhile to note that on some early adding machines, before the days of digital computers, subtraction would be performed by having the operator enter values using a different colored set of legends on each key (so each key would enter nine minus the number to be subtracted), and press a special button would would assume a carry into a calculation. Thus, on a six-digit machine, to subtract 1234 from a value, the operator would hit keys that would normally indicate "998,765" and hit a button to add that value plus one to the calculation in progress. Two's complement arithmetic is simply the binary equivalent of that earlier "ten's-complement" arithmetic.

Note
Rectangle 27 1

binary Why prefer two's complement over sign and magnitude for signed numbers?


this is to simplify sums and differences of numbers. a sum of a negative number and a positive one codified in 2's complements is the same as summing them up in the normal way.

Note