What is “2's Complement”?

2018-12-31 01:41发布

I'm in a computer systems course and have been struggling, in part, with Two's Complement. I want to understand it but everything I've read hasn't brought the picture together for me. I've read the wikipedia article and various other articles, including my text book.

Hence, I wanted to start this community wiki post to define what Two's Complement is, how to use it and how it can affect numbers during operations like casts (from signed to unsigned and vice versa), bit-wise operations and bit-shift operations.

What I'm hoping for is a clear and concise definition that is easily understood by a programmer.

17条回答
几人难应
2楼-- · 2018-12-31 01:57

Imagine that you have a finite number of bits/trits/digits/whatever. You define 0 as all digits being 0, and count upwards naturally:

00
01
02
..

Eventually you will overflow.

98
99
00

We have two digits and can represent all numbers from 0 to 100. All those numbers are positive! Suppose we want to represent negative numbers too?

What we really have is a cycle. The number before 2 is 1. The number before 1 is 0. The number before 0 is... 99.

So, for simplicity, let's say that any number over 50 is negative. "0" through "49" represent 0 through 49. "99" is -1, "98" is -2, ... "50" is -50.

This representation is ten's complement. Computers typically use two's complement, which is the same except using bits instead of digits.

The nice thing about ten's complement is that addition just works. You do not need to do anything special to add positive and negative numbers!

查看更多
余欢
3楼-- · 2018-12-31 01:59

Lets get the answer 10 – 12 in binary form using 8 bits: What we will really do is 10 + (-12)

We need to get the compliment part of 12 to subtract it from 10. 12 in binary is 00001100. 10 in binary is 00001010.

To get the compliment part of 12 we just reverse all the bits then add 1. 12 in binary reversed is 11110011. This is also the Inverse code (one's complement). Now we need to add one, which is now 11110100.

So 11110100 is the compliment of 12! Easy when you think of it this way.

Now you can solve the above question of 10 - 12 in binary form.

00001010
11110100
-----------------
11111110  
查看更多
栀子花@的思念
4楼-- · 2018-12-31 02:00

I had the same problem a couple of weeks ago. I ended up reading about it on-line from various sources, trying to put the pieces together, and writing about it myself just to make sure that I understood it correctly. We use two's complement for mainly two reasons:

  1. To avoid multiple representations of 0
  2. To avoid keeping track of carry bit (as in one's complement) in case of an overflow.
  3. Carrying out simple operations like addition and subtraction becomes easy.

If you want a more detailed explanation of the matter at hand, try the article written by me here. Hope it helps!

查看更多
明月照影归
5楼-- · 2018-12-31 02:05

2’s Complements: When we add an extra one with the 1’s complements of a number we will get the 2’s complements. For example: 100101 it’s 1’s complement is 011010 and 2’s complement is 011010+1 = 011011 (By adding one with 1's complement) For more information this article explain it graphically.

查看更多
泛滥B
6楼-- · 2018-12-31 02:05

REFERENCE: https://www.cs.cornell.edu/~tomf/notes/cps104/twoscomp.html

I invert all the bits and add 1. Programmatically:

  // in C++11
  int _powers[] = {
      1,
      2,
      4,
      8,
      16,
      32,
      64,
      128
  };

  int value=3;
  int n_bits=4;
  int twos_complement = (value ^ ( _powers[n_bits]-1)) + 1;
查看更多
明月照影归
7楼-- · 2018-12-31 02:10

Many of the answers so far nicely explain why two's complement is used to represent negative number, but do not tell us what two's complement number is, particularly not why a '1' is added, and in fact often added in a wrong way.

The confusion comes from a poor understanding of the definition of a complement number. A complement is the missing part that would make something complete.

The radix complement of an n digit number x in radix b is, by definition, b^n-x. In binary 4 is represent by 100, which has 3 digits (n=3) and a radix of 2 (b=2). So its radix complement is b^n-x = 2^3-4=8-4=4 (or 100 in binary).

However, in binary obtaining a radix's complement is not as easy as getting its diminished radix complement, which is defined as (b^n-1)-y, just 1 less than that of radix complement. To get a diminished radix complement, you simply flip all the digits.

100 -> 011 (diminished (one's) radix complement)

to obtain the radix (two's) complement, we simply add 1, as the definition defined.

011 +1 ->100 (two's complement).

Now with this new understanding, let's take a look of the example given by Vincent Ramdhanie (see above second response)

/* start of Vincent

Converting 1111 to decimal:

The number starts with 1, so it's negative, so we find the complement of 1111, which is 0000. Add 1 to 0000, and we obtain 0001. Convert 0001 to decimal, which is 1. Apply the sign = -1. Tada!

end of Vincent */

Should be understood as

The number starts with 1, so it's negative. So we know it is a two's complement of some value x. To find the x represented by its two's complement, we first need find its 1's complement.

two's complement of x: 1111 one's complement of x: 1111-1 ->1110; x = 0001, (flip all digits)

apply the sign -, and the answer =-x =-1.

查看更多
登录 后发表回答