22. Bity: &, %, !, LSH, RSH

Na čo to je

Bajt je osem bitov – ôsmich prepínačov, z ktorých každý je buď 0, alebo 1. Počítač Atari má veľa nastavení uložených tak, že každý bit bajtu znamená niečo iné: jeden zapína inverzné písmo, iný hovorí, či je stlačené tlačidlo. Bitové operácie dovolia pracovať s jednotlivými bitmi.

Kapitolu môžeš pri prvom čítaní preskočiť a vrátiť sa k nej, keď budeš bity potrebovať.

Dvojková sústava v skratke

Každý bit má svoju hodnotu – mocninu dvojky. Bity sa číslujú sprava, od 0:

Bit76543210
Hodnota1286432168421

Číslo je súčet hodnôt bitov, ktoré sú 1. Napríklad 12 je 00001100: bit 3 (hodnota 8) a bit 2 (hodnota 4), 8 + 4 = 12.

Ako sa to píše

OperátorSlovomČo robí s každou dvojicou bitov
a & ba AND bvýsledný bit je 1, len keď sú oba 1
a % ba OR bvýsledný bit je 1, keď je aspoň jeden 1
a ! ba XOR bvýsledný bit je 1, keď sú bity rôzne
a LSH nposunie bity o n miest doľava (násobenie dvoma, n-krát)
a RSH nposunie bity o n miest doprava (delenie dvoma, n-krát)

Znak a slovo sú to isté: a & b je a AND b. Sú to tie isté AND a OR ako v podmienkach (kapitola 9) – tam spájajú porovnania, tu pracujú s bitmi čísel.

K čomu sa hodia:

ChcemZápisPríklad
zistiť, či je bit zapnutýIF x & maska THENIF x&128 THEN
zapnúť bitx==%maskax==%128
vypnúť bitx==&(255−maska)x==&127
prepnúť bit na opačnýx==!maskax==!128

Maska je číslo, ktoré má jednotky na bitoch, o ktoré ide.

Celý program

Súbor examples/bits.act:

Action!
; Bits: looking inside a byte

PROC Bits(BYTE value)        ; write a byte as eight binary digits
  BYTE i, mask

  mask=128
  FOR i=1 TO 8
  DO
    IF value&mask THEN
      Put('1)
    ELSE
      Put('0)
    FI
    mask==RSH 1
  OD
RETURN

PROC Show(BYTE value)
  Bits(value)
  Print(" = ")
  PrintBE(value)
RETURN

PROC Main()
  BYTE a, b

  a=12
  b=10
  Print("a           ")  Show(a)
  Print("b           ")  Show(b)
  Print("a AND b     ")  Show(a&b)
  Print("a OR b      ")  Show(a%b)
  Print("a XOR b     ")  Show(a!b)
  Print("a LSH 1     ")  Show(a LSH 1)
  Print("a RSH 2     ")  Show(a RSH 2)

  a=5
  a==%128                    ; switch bit 7 on
  Print("bit 7 on    ")  Show(a)
  a==&127                    ; switch bit 7 off
  Print("bit 7 off   ")  Show(a)
RETURN

Preklad a spustenie

action26 bits.act --sim

Čo uvidíš

a           00001100 = 12
b           00001010 = 10
a AND b     00001000 = 8
a OR b      00001110 = 14
a XOR b     00000110 = 6
a LSH 1     00011000 = 24
a RSH 2     00000011 = 3
bit 7 on    10000101 = 133
bit 7 off   00000101 = 5

Ako to funguje

Porovnaj stĺpce nad sebou:

a        00001100
b        00001010
a AND b  00001000    jednotka len tam, kde ju majú obe
a OR b   00001110    jednotka tam, kde ju má aspoň jedno
a XOR b  00000110    jednotka tam, kde sa líšia

Procedúra Bits ukazuje, ako sa bity čítajú: maska začne na 128 (bit 7) a každým krokom sa posunie doprava (mask==RSH 1). value&mask je nenulové práve vtedy, keď je daný bit v value zapnutý – a podmienka bez porovnania platí, keď je výsledok nenulový.

Časté chyby

Čo sa staloČo sa stane
% v zmysle „percentá“ alebo „zvyšok po delení“v Action! je % bitové OR; zvyšok je MOD
! v zmysle „nie“v Action! je ! bitové XOR; opak podmienky sa píše obráteným porovnaním
posun BYTE hodnoty za 8 bitov (1 LSH 8)výsledok je 0 – počíta sa v BYTE a bit vypadne; pre väčšie posuny použi CARD premennú
x&mask=mask bez zátvoriekerror ACT023: illegal conditional expression – porovnanie má prednosť pred &; píš (x&mask)=mask

Vyskúšaj si

  1. Vypíš v dvojkovej sústave čísla 0 až 15.
  2. Napíš BYTE FUNC IsOdd(BYTE n), ktorá zistí nepárnosť bitovou operáciou (nepárne číslo má zapnutý bit 0).
  3. Kód malého písmena je o 32 väčší ako kód veľkého – líšia sa bitom 5. Preveď znak 'a na veľké písmeno vypnutím toho bitu.

Zhrnutie

Späť: 21. Záznamy · Ďalej: 23. Program vo viacerých súboroch