19

I was watching this video on the maximum and minimum values of signed integers.

Take an example of a positive signed value - 0000 0001 The first bit denotes that the number is positive and the last 7 bits are the number itself. So it is easily interpreted as +1.

Now take an example of a negative signed value - 1000 0000 which comes out to be -8. Okay, the computer can understand that it is a negative value because of the first bit but how the hell does it understand that 000 0000 means -8?

In general, how are negative signed values stored/interpreted in a computer?

5
  • 2
    nl.wikipedia.org/wiki/Two%27s_complement is how binary number are stored in computers.
    – Pieter B
    May 14, 2014 at 9:37
  • 2
    @PieterB Maybe your computer. And a lot of other people's. For good reasons! But don't imply it's the only way. Apr 17, 2016 at 13:18
  • Any way you like. I can think of at least 256! ways of storing (8 bit) binary numbers on computers. However most of those are incredibly silly.
    – Caleth
    Feb 19, 2019 at 14:17
  • C doesn't specify, it's largely how the chip manufacturer decides to represent the data. C gets compiled to machine code, and it takes care not to redefine how the chip stores numbers. Same rules apply to floating point numbers. It's up to the chip manufacturer to define how they are stored. Most chip manufacturers use 2's complement, but I'm sure there are exceptions. Feb 20, 2019 at 15:03
  • 1
    it seems that the question contains an error : +1 is presented using sign magnitude representation, and -8 should be 1 0001000 in this representation. Jun 6, 2022 at 9:05

4 Answers 4

39

The C standard doesn't mandate any particular way of representing negative signed numbers.

In most implementations that you are likely to encounter, negative signed integers are stored in what is called two's complement. The other major way of storing negative signed numbers is called one's complement.

The two's complement of an N-bit number x is defined as 2^N - x. For example, the two's complement of 8-bit 1 is 2^8 - 1, or 1111 1111. The two's complement of 8-bit 8 is 2^8 - 8, which in binary is 1111 1000. This can also be calculated by flipping the bits of x and adding one. For example:

 1      = 0000 0001
~1      = 1111 1110 (1's complement)
~1 + 1  = 1111 1111 (2's complement)
-1      = 1111 1111

 21     = 0001 0101
~21     = 1110 1010
~21 + 1 = 1110 1011
-21     = 1110 1011

The one's complement of an N-bit number x is defined as x with all its bits flipped, basically.

 1      = 0000 0001
-1      = 1111 1110

 21     = 0001 0101
-21     = 1110 1010

Two's complement has several advantages over one's complement. For example, it doesn't have the concept of 'negative zero', which for good reason is confusing to many people. Addition, multiplication and subtraction work the same with signed integers implemented with two's complemented as they do with unsigned integers as well.

3
  • In the part where you say "The two's complement of an N-bit number x is defined as 2^N - x" what is the valid range of x?
    – Jack
    Aug 19, 2021 at 7:09
  • @Jack From -2^(N-1) to 2^(N-1) - 1. E.g. a 8-bit signed number in two's complement can range from -128 to +127 (inclusive). Aug 19, 2021 at 10:32
  • 1
    The C Standard requires that one of four methods is used: Signed magnitude, one’s complement, two’s complement, and two’s complement without the largest negative number.
    – gnasher729
    Aug 20, 2021 at 6:26
24

There are three well known methods for representing negative values in binary:

  1. Signed magnitude. This is the easiest to understand, because it works the same as we are used to when dealing with negative decimal values: The first position (bit) represents the sign (0 for positive, 1 for negative), and the other bits represent the number. Although it is easy for us to understand, it is hard for computers to work with, especially when doing arithmetic with negative numbers.
    In 8-bit signed magnitude, the value 8 is represented as 0 0001000 and -8 as 1 0001000.

  2. One's complement. In this representation, negative numbers are created from the corresponding positive number by flipping all the bits and not just the sign bit. This makes it easier to work with negative numbers for a computer, but has the complication that there are two distinct representations for +0 and -0. The flipping of all the bits makes this harder to understand for humans.
    In 8-bit one's complement, the value 8 is represented as 00001000 and -8 as 11110111.

  3. Two's complement. This is the most common representation used nowadays for negative integers because it is the easiest to work with for computers, but it is also the hardest to understand for humans. When comparing the bit patterns used for negative values between one's complement and two's complement, it can be observed that the same bit pattern in two's complement encodes for the next lower number. For example 11111111 stands for -0 in one's complement and for -1 in two's complement, and similarly for 10000000 (-127 vs -128).
    In 8-bit two's complement, the value 8 is represented as 00001000 and -8 as 11111000.

4
  • 8
    Signed magnitude also has two zeroes. May 14, 2014 at 11:42
  • +1 for mentioning sign/magnitude. uncommon and inconvenient (for CPUs if not humans!), but worth knowing. Apr 17, 2016 at 13:19
  • Almost all of us work with signed magnitude, especially with FP numbers.
    – Paulo1205
    Sep 12, 2016 at 7:47
  • There's also the biased representation used for the exponents of IEEE 754 floating point numbers. Double precision numbers e.g. have an 11-bit exponent with bias 2^10−1 = 1023, so 00000000000 means -1022 and 11111111111 means +1023. Aug 19, 2021 at 11:23
2

The signed integers are stored using http://en.wikipedia.org/wiki/Two%27s%20complement

Then you get :

000   0
001   1
010   2
011   3
100   -4
101   -3
110   -2
111   -1

Basically it's very easy counting, you count till half the max of the signed integer. Do a +1, make it negative and start counting down.

-2

The simple way to understand this is: For positive number we know that number is converted into binary and then stored in the memory.

For storing negative numbers:

  1. Forget the sign of the number

  2. Take the 2's complement

To find 2's complement: For example let's take 1000 0000 the starting bit indicates it is negative

1's complement

           1000 000
           0111 111
                 +1
          __________
           1000 000 ----->>this represents the number  -8
1
  • 2
    Have you even read the previous answers? Aug 19, 2021 at 9:54

Not the answer you're looking for? Browse other questions tagged or ask your own question.