# Sign extension

*Widening a signed number without changing it*

Sign extension is how a two's-complement number is widened to more bits without changing its value: copy the sign bit (the top bit) into all the new high bit positions, so a negative number stays negative rather than becoming a large positive value.

Group: Number & logic
URL: https://digiwleea.wleeaf.dev/learn/sign-extension/

> **KEY:** You met this idea at the end of [two's complement](https://digiwleea.wleeaf.dev/learn/twos-complement/); it gets its own page because it is a step a CPU takes constantly, every time it loads a narrow value into a wider register or adds an 8-bit number to a 16-bit one.

When you copy a value into a wider slot, you have to fill the new high bits **without changing the number**. How you fill them depends on whether the value is unsigned or signed [two's complement](https://digiwleea.wleeaf.dev/learn/twos-complement/).

- **Unsigned** number: pad the new high bits with `0` (**zero extension**). `0000 0101` (5) widened to 16 bits is `0000 0000 0000 0101`, still 5.
- **Signed** two's-complement number: copy the **top (sign) bit** into every new bit (**sign extension**). A negative value must stay negative.

## Worked example

Take `-3` in 4-bit two's complement. `+3` is `0011`, so `-3` is invert-and-add-one: `1100 + 1 = 1101`. To widen it to 8 bits, copy the sign bit (`1`) into the four new positions:

```
1101 (-3, 4-bit)  ->  1111 1101 (-3, 8-bit)
```

Check with negative weights: `1111 1101 = -128 + 64 + 32 + 16 + 8 + 4 + 1 = -128 + 125 = -3`. Still `-3`. Now see what goes wrong if you zero-extend a negative by mistake: `0000 1101` reads as `+13`, a completely different number. That is why the fill bit must match the sign.

| 4-bit | signed value | sign-extended 8-bit |
| --- | --- | --- |
| 0101 | +5 | 0000 0101 |
| 0111 | +7 | 0000 0111 |
| 1101 | -3 | 1111 1101 |
| 1010 | -6 | 1111 1010 |

_Positive values (top bit 0) fill with 0; negative values (top bit 1) fill with 1. In both cases the new bits just repeat the existing sign bit._

Why copying the sign bit is safe: in two's complement the top bit carries a negative weight. Extending `1101` to `1111 1101` replaces the single `-8` weight with a larger `-128`, but the extra `1` bits at `64, 32, 16, 8` add back `120`, and `-128 + 120 = -8`, the same contribution the original sign bit made. The value is preserved exactly.

> **WARN:** **Common mistakes.** Never zero-extend a signed negative number (it becomes a large positive). Never sign-extend an unsigned value (its top bit is data, not a sign, so copying it corrupts the number). A bit pattern has no sign by itself: whether to sign- or zero-extend is decided by the **instruction** (many CPUs have both a `LOAD signed` and a `LOAD unsigned` for exactly this). And extend from the real top bit of the *narrow* value, not of the wide slot.

**Q (Try it):** Sign-extend the 4-bit value `1010` to 8 bits. What decimal number is it, and does widening change that value?

**A:** The top bit is `1`, so copy it into the four new positions: `1111 1010`. Its value: 4-bit `1010 = -8 + 2 = -6`; 8-bit `1111 1010 = -128 + 64 + 32 + 16 + 8 + 2 = -128 + 122 = -6`. Same value, `-6`, before and after widening, which is the whole point of sign extension.

### FAQ

**Q:** What is sign extension?

**A:** Sign extension widens a signed [two's-complement](https://digiwleea.wleeaf.dev/learn/twos-complement/) number to more bits by copying its top (sign) bit into every new high bit. This keeps a negative number negative: `-3` in 4 bits (`1101`) becomes `1111 1101` in 8 bits, still `-3`.

**Q:** What is the difference between sign extension and zero extension?

**A:** **Zero extension** fills the new high bits with `0` and is correct for **unsigned** numbers. **Sign extension** fills them with a copy of the sign bit and is correct for **signed** two's-complement numbers. Choosing the wrong one changes the value.

**Q:** Why does copying the sign bit preserve the value?

**A:** In two's complement the top bit has a negative weight. When you extend, the new sign bit takes a larger negative weight, but the added `1` bits below it make up the difference exactly, so the total (the weighted sum) is unchanged.

> **KEY:** Sign extension is what lets one adder mix numbers of different widths; the flip side, when a result is too wide to hold at all, is [carry versus overflow](https://digiwleea.wleeaf.dev/learn/carry-vs-overflow/).
