CampusFlow
ArchitectureSigned Numbers

± Signed Number Representations

How computers represent negative numbers: sign-magnitude, one's complement, and two's complement. Two's complement is the dominant standard in modern computing.

Interactive Representation Explorer

Binary Representation
0101
Hexadecimal
0x5
Decoded Value
5

Representation Methods

Sign-Magnitude

MSB = sign, rest = magnitude

+5 = 0101

-5 = 1101

One's Complement

Negate by flipping all bits

+5 = 0101

-5 = 1010 (flip bits of +5)

Two's Complement

Negate: flip bits + 1

+5 = 0101

-5 = 1011 (flip bits + 1)

Range of Representable Numbers

Representation4-bit8-bit16-bitNotes
Sign-Magnitude[-7, +7][-127, +127][-32767, +32767]Two zeros (+0, -0)
One's Complement[-7, +7][-127, +127][-32767, +32767]Two zeros (+0, -0)
Two's Complement[-8, +7][-128, +127][-32768, +32767]One zero, asymmetric range
💡

Two's Complement Advantage

Two's complement has only one zero (so +0 = -0), and addition/subtraction work identically for signed and unsigned numbers at the binary level. This is why all modern CPUs use two's complement.

Addition & Overflow Detection

Two's complement addition

0011 = 3

+ 0101 = 5

1000 = 8

Overflow detected! Signs of A and B match but result sign differs.

⚠️

Overflow Detection Rule

In two's complement, overflow occurs when the carry into the sign bit differs from the carry out of the sign bit. A simpler check: if two positive numbers produce a negative result, or two negatives produce a positive result, overflow has occurred.

Detailed Comparison Table (4-bit)

DecimalSign-MagOne's CompTwo's Comp
7011101110111
6011001100110
5010101010101
4010001000100
3001100110011
2001000100010
1000100010001
0000000000000
0000000000000
-1100111101111
-2101011011110
-3101111001101
-4110010111100
-5110110101011
-6111010011010
-7111110001001
-81000

Code Example

python

def twos_complement(val: int, bits: int = 8) -> str:
    """Convert signed integer to two's complement binary string."""
    mask = (1 << bits) - 1
    masked = val & mask if val < 0 else val
    return format(masked, f'0{bits}b')

def from_twos_complement(bin_str: str) -> int:
    """Convert two's complement binary string to signed integer."""
    bits = len(bin_str)
    val = int(bin_str, 2)
    if bin_str[0] == '1':
        val -= (1 << bits)
    return val

def detect_overflow(a_bin: str, b_bin: str, result_bin: str) -> bool:
    """Detect signed overflow in two's complement addition."""
    a_sign, b_sign, r_sign = a_bin[0], b_bin[0], result_bin[0]
    return a_sign == b_sign and a_sign != r_sign

# Examples
print(twos_complement(-5, 4))           # 1011
print(from_twos_complement("1011"))      # -5
print(detect_overflow("0111", "0010", "1001"))  # True (7+2=-7)

Interview Questions

Why do most computers use two's complement instead of sign-magnitude?

Two's complement has several advantages: (1) only one representation for zero, avoiding the ambiguity of +0 and -0; (2) addition and subtraction hardware works identically for signed and unsigned numbers; (3) the ALU doesn't need special logic for signed operations; (4) the asymmetric range gives one extra negative value (-2^{n-1}).

How do you negate a number in two's complement?

To negate a two's complement number, invert all bits (bitwise NOT) and add 1. This is equivalent to taking the one's complement and adding 1. For example, +5 (0101) becomes -5: invert to 1010, add 1 → 1011.

What is the range of signed numbers in 8-bit two's complement and why is it asymmetric?

8-bit two's complement ranges from -128 to +127. It is asymmetric because zero takes one slot in the positive range. With 8 bits there are 2^8 = 256 possible values. If one is zero, the remaining 255 are split between negative and positive. Since the MSB is the sign bit, -128 (10000000) is a valid value with no positive counterpart.