BitLab vzorek, který se někdo zeptá

Tohle je statická kopie kapitoly pro vyhledávače. Interaktivní verze má animované obrázky, kontrolní otázky a tlačítka, která příklad načtou do kalkulačky.

Záporná čísla: dvojkový doplněk a ta jedna chybějící kladná

V bajtu je osm bitů a žádný z nich není „mínus“. Znaménko se musí někam vejít, a existují tři způsoby, jak to udělat. Dva se nepoužívají a stojí za to vědět proč.

způsobjakproč se nepoužívá
přímý kódnejvyšší bit je znaménko, zbytek velikostdvě nuly (+0 a −0), a sčítačka musí porovnávat znaménka
jedničkový doplněkzáporné = všechny bity otočenétaky dvě nuly, a přenos se musí obtočit zpátky
dvojkový doplněkotočit a přičíst jedničku

Dvě nuly nejsou estetický problém. Znamenají, že if (x == 0) musí testovat dva vzorky, a že jeden ze 256 stavů se plýtvá na duplikát.

11111011−5−x
  1. 0000 0101 = 5

    Pět v osmi bitech. Nic zvláštního — váhy 4 a 1 jsou zapnuté.

  2. ~0000 0101 = 1111 1010

    Jednobitová negace, NOT. Zatím to nic neznamená — je to jen opačný vzorek.

  3. 1111 1010 + 1 = 1111 1011

    A tohle je celý trik. Nic víc v tom není.

  4. 0000 0101 + 1111 1011 = 10000 0000 → 0000 0000

    Součet původního a nového vzorku je 256 — a 256 se do osmi bitů nevejde, takže z něj zbude nula. Přesně to, co se od −x čeká.

  5. a − b = a + (~b + 1)

    Odčítání je sčítání s doplňkem. Procesor nemá zvlášť obvod na mínus — to je ta úspora, kvůli které tahle reprezentace vyhrála.

Odvození dvojkového doplňku, krok po kroku. Poslední dva kroky říkají, proč to není trik, ale nutnost.

Ta asymetrie

Osmibitový rozsah se znaménkem je −128 až +127. Ne −127 až +127. Chybí jedna kladná hodnota, a důvod je banální: nula zabírá místo na kladné straně. Vzorků je 256, jeden padne na nulu, zbývá 255 na rozdělení mezi kladné a záporné — a lichý počet nejde rozdělit na půl.

−2n−1  …  2n−1 − 1rozsah se znaménkem, n bitů

Praktický důsledek, který kousne: −(−128) je v osmi bitech pořád −128. Není kam to napsat. Otočíte bity, přičtete jedničku a jste tam, kde jste byli. Kdo píše abs(x) nad osmibitovým vstupem, má tam jeden případ, kdy výsledek vyjde záporný — a je to případ, který se v testech s náhodnými daty objeví jednou z dvou set padesáti šesti.

Proč to vyhrálo

Protože procesor pak nepotřebuje odčítačku. Odečíst znamená přičíst doplněk, a přenos, který uteče přes horní hranu, se prostě zahodí:

a − b = a + (~b + 1)jedna sčítačka na obojí

To je úspora poloviny aritmetické jednotky výměnou za jedno pravidlo navíc. V roce 1949, kdy to poprvé postavil EDSAC, to bylo hodně; dnes je to zvyk, který se už nezmění.

Vzorce v této kapitole

rozsah — rozsah se znaménkem
−2ⁿ⁻¹ … 2ⁿ⁻¹ − 1 [—] kap. 3
−x — dvojkový doplněk
−x = ~x + 1 [—] kap. 3