◄ WORLD V · SONNY 5DART 477 · a helldive at the net

ZERO EXTENSION widen with zeros — correct for unsigned, wrong for signed

Sign extension’s twin, and the reason the two must be distinguished. Zero extension widens a value by filling the new high bits with zeros: 0x80 → 0x0080 = 128. For an unsigned byte that is exactly right; for a signed byte it is a silent bug, turning −128 into +128. Same input bits, same widening machinery, different fill — and the compiler must pick the right one from the value’s type. It is the MOVZX instruction, and the everyday hazard of mixing signed and unsigned across a width change.

THE TECHNIQUE fill the new high bits with zeros (MOVZX) — unsigned only

The demo zero-extends 0x80 to 128 and shows sign extension of the same byte gives 65408 — same input, different fill: live demo


HISTORY & CREDIT zero extension · MOVZX

“Widening is widening.” — zero-fill and sign-fill give different values for the same bits; picking wrong is a classic bug. cited

the rule · fill the new high bits with zeros — 0x80 → 0x0080 = 128.
the hazard · on a signed byte it turns −128 into +128 — a silent bug.
the pair · MOVZX (zero) vs MOVSX (sign) — the type decides which is correct.

The same bits widened two ways — zeros for unsigned, the sign bit for signed, and woe if you swap them. width

RECOMMEND FOR I-13 zero vs sign fill, on the compiler

On the canonical compiler, zero-extending 0x80 gives 128, while sign-extending the same byte gives 65408:

$ i13 run ln_zeroextension.i13 # zero-fill vs sign-fill RUN OK · 39 step(s) · peak stack 3 · call depth 1 z = 128 -- 0x80 zero-extended (unsigned) s = 65408 -- 0x80 sign-extended (signed) same_input_diff_fill = 1
Recommend as a NULL — the encoding twin of dart 476. Zero extension is the other fill rule for a width change (B44); which one is correct is a matter of the value’s type, not a new invariant. NULL — it exists in the batch to make sign extension’s subtlety visible: same bits, two widenings, and the type is the difference.