FAV-ZCU/KIV PPA1/18. Zobrazení dat v počítači.md

12 KiB
Raw Permalink Blame History

Zobrazení dat v počítači

  • Všechna data uložená v počítači jsou uložena jako posloupnost binárních číslic (bitů) uspořádaná po bytech (8 bitů)
  • Způsob uložení dat se nazývá kódování
    • Je dán datovým typem dat
      • Určuje, jaký mají význam jednotlivé bity a byty
  • Rozsahy hodnot jednotlivých datových typů a počet bytů, které zabírají v paměti, byly zmíněny v Kap. 3.2
  • Jakým způsobem jsou jednotlivé datové typy uloženy (jaké kódování je použito), je popsáno v následujících podkapitolách

Převod čísel mezi soustavami

  • Nativní číselná soustava počítače, odpovídající uspořádání fyzické paměti, je dvojková (binární)
    • Ruční zápis binárních čísel je však dlouhý, proto se pro zápis binárních čísel často používá šestnáctková (hexadecimální) soustava, která pro stejné číslo potřebuje 4x méně číslic
      • Na jeden byte stačí 2 hexadecimální číslice, ale 8 binárních číslic
  • V běžném životě se většinou počítá v desítkové (dekadické) soustavě
  • Čísla lze mezi jednotlivými soustavami převádět pomocí kalkulačky či jiných programů (přepočet je dostupný např. v PSPadu)
  • Algoritmy pro ruční převod čísel mezi dvojkovou, desítkovou a šestnáctkovou soustavou jsou v následujících podkapitolách

Převod z desítkové do dvojkové soustavy (univerzální postup)

  • Celou a desetinnou část řešíme zvlášť
  • Celá část
    • Celou část dělíme 2, píšeme si zbytky po dělení
    • Poslední číslice výsledku (0 nebo 1) a zbytky přečtené odzadu dají celou část binárního čísla
  • Desetinná část
    • Desetinnou část násobíme 2, píšeme si číslici vlevo od desetinné čárky (v celé části)
    • Číslice přečtené popředu dají desetinnou část binárního čísla

Převod z desítkové do dvojkové soustavy („intuitivní“)

  • „Intuitivní“ postup pro celá čísla
  • Napsat si vyčíslené mocniny 2, nalézt největší menší nebo stejnou mocninu 2, zapsat pod ní 1 a odečíst ji od převáděného čísla
  • Opakovat, dokud z čísla nezbude 0
  • Příklad převodu 69 na jeho reprezentaci v binární soustavě
    • Odečtu 64, protože 64 < 69, pod 64 zapíšu 1, zbude 5
    • Odečtu 4, protože 4 < 5, pod 4 zapíšu 1, zbude 1
    • Odečtu 1, protože 1 = 1, pod 1 zapíšu 1, zbude 0
    • Zbytek pozic doplním 0

Převod z dvojkové do desítkové soustavy

  • Převod z dvojkové soustavy do desítkové (pro celá i reálná čísla)
    • Každou číslici označit zprava doleva jako zvyšující se mocninu 2
    • Mocniny u číslic 1 vyčíslit a sečíst

Převod z dvojkové do šestnáctkové soustavy

  • Převod z dvojkové soustavy do šestnáctkové (pro celá i reálná čísla)
    • Rozdělit číslo na čtveřice od desetinné čárky (na obě strany)
    • Každá čtveřice je jedna číslice šestnáctkové soustavy (0 až F)
      • Vyčíslit hodnotu čtyř binárních číslic jako při převodu do desítkové soustavy

Převod z šestnáctkové do dvojkové soustavy

  • Převod z šestnáctkové do dvojkové soustavy (pro celá i reálná čísla)
    • Každou šestnáctkovou číslici převést do desítkové soustavy
    • Použít pro každou číslici intuitivní postup pro převod z desítkové do dvojkové soustavy

Kódy pro uložení celočíselných datových typů

  • Pro uložení celočíselných datových typů existuje několik kódů
    • Bezznaménkové
    • Znaménkové
      • Přímý kód
      • Inverzní kód
      • Doplňkový kód
      • Kód s posunutou nulou

Uložení celých čísel bez znaménka

  • Zápis ve dvojkové soustavě zarovnaný na násobky bytů
  • Pouze pro nezáporná čísla
  • Např. 131 je 1000 0011, 3 je 0000 0011

Přímý kód

  • Kladná čísla stejná jako u bezznaménkového kódování
  • Znaménko určeno v MSB (Most Significant Bit ten nejvíce vlevo)
  • Např. -3 je 1000 0011
  • Nevýhody
    • Dvojí nula 1000 0000 (záporná) a 0000 0000 (kladná)
  • Používá se pro zobrazení mantisy u reálných čísel

Inverzní kód

  • Kladná čísla stejná jako u bezznaménkového kódování
  • Pro záporná čísla se mění všechny 0 na 1 a 1 na 0
  • Např. -3 je 1111 1100
  • Nevýhody
    • Dvojí nula 1111 1111 (záporná) a 0000 0000 (kladná)
  • Používá se v bitových operacích, případně jako mezikrok v doplňkovém kódu

Doplňkový kód (dvojkový doplněk)

  • Matematická definice
    • D(x) = x pro x ≥ 0
    • D(x) = x + K pro x < 0, kde K = 2^{n} (kapacita soustavy)
  • Kladná čísla stejná jako u bezznaménkového kódování
  • Záporná čísla jsou uložena jako „inverzní kód + 1“
  • Např. -3 je 1111 1101
  • Používá se výhradně pro uložení celých znaménkových čísel
    • Např. typy byte, short, int, long v Javě
  • Výhody
    • Pouze jedna nula 0000 0000
    • Odečítání je přičítání záporného čísla
  • Pozor na nesymetrický rozsah -128 až 127 (pro 1 byte)
    • Absolutní hodnota nejmenšího záporného čísla je mimo rozsah
  • Přetečení
    • Nastává, když nám aritmetickými operacemi vyjde hodnota, která se nevejde do daného rozsahu
    • Např. 127 + 1 (pro 1 byte) = -128
      • MSB se přičtením 1 k maximálnímu číslu nastaví na 1, což indikuje záporné číslo, proto vyjde -128
    • Možné reakce na přetečení
      • Přerušení výpočtu jako reakce na chybu
      • Pokračování výpočtu s nesprávným výsledkem používá Java
    • Zda přetečení nastane, závisí na vstupních číslech někdy může program fungovat správně a někdy ne => špatně se hledá

Kód s posunutou nulou

  • Lineární posun nuly po celočíselné ose
    • 0000 0000 je nejmenší (záporné) číslo
    • Nula je ve středu rozsahu, tedy 2^{n-1} 1, např. 0111 1111
    • 1111 1111 je největší kladné číslo
  • Podobně jako u doplňkového kódu je rozsah nesymetrický
  • Nevýhoda
    • Kladná čísla jsou odlišná od bezznaménkového kódování
    • Např. 3 je 1000 0010
  • Používá se pro uložení exponentu u reálných čísel

Kódy pro uložení reálných datových typů

  • Aproximace reálných čísel
  • Též nazýváno „zobrazení v pohyblivé řádové čárce“ (floating point)
  • Dle normy IEEE 754 na 4 nebo 8 bytech (v Javě float 4 byty a double 8 bytů)
    • Kromě samotného kódování norma IEEE 754 definuje i standardní chování základních aritmetických operací (sčítání, odčítání, násobení, dělení, …)

IEEE 754 na 4 bytech

  • Formát v pohyblivé řádové čárce s jednoduchou přesností (single-precision floatingpoint format)
  • Používá 4 byty (32 bitů)
    • Rozsah v absolutní hodnotě cca 10-45 až 10+38
    • Přesnost na cca 6 až 7 (dekadických) desetinných míst
    • Rozdělení na znaménko, exponent a mantisu
  • Znaménkový bit patří mantise (nikoliv exponentu)
    • 0 odpovídá +
    • 1 odpovídá -
  • Mantisa (23 bitů)
    • Uložena v přímém kódu (znaménkový bit je oddělen exponentem)
    • Je normovaná
      • 1 ≤ mantisa < základ (tj. 2)
      • Její první bit v normovaném tvaru musí tedy být vždy 1 (1 před desetinou čárkou) a proto se neukládá
    • Určuje přesnost čísla
  • Exponent (8 bitů)
    • Uložen v kódu s posunutou nulou, kde 0 je 0111 1111
    • Určuje rozsah čísla
  • Hodnota 0 je uložena jako samé nuly
  • Hodnota čísla se dá vypočítat
  • Určení, jak bude vypadat zápis v IEEE 754 na 4 bytech pro číslo -258,125
  • Přesnost uložených čísel je omezená
  • Některá čísla jsou zaokrouhlená
  • Pokud je hodnota čísla menší než minimum, číslo nelze zobrazit, zaokrouhluje se automaticky na 0 => podtečení
  • Pokud je hodnota čísla v absolutní hodnotě větší než maximum, číslo nelze zobrazit, zaokrouhluje se automaticky na (kladné nebo záporné) nekonečno => přetečení
  • NaN (Not a Number)
    • Definovaná hodnota při chybné operaci s reálným číslem (např. dělení nuly nulou)
  • Operace s reálnými čísly
    • Sčítání
      • Porovnáním exponentů se zjistí menší číslo, tomu se zvětší exponent na úroveň většího čísla => zmenšuje se přesnost (mantisa)
      • Pro exponentem hodně odlišná čísla se může v důsledku místo menšího čísla přičítat nula
    • Násobení
      • Exponenty se sečtou
      • Mantisy se vynásobí
  • Obecně platí
    • Nepoužívat reálná čísla tam, kde stačí celá
      • Výpočty nemusí být přesné (zaokrouhlovací chyby)
      • Výpočty s celými čísly mohou být rychlejší
    • Nepoužívat pro reálná čísla porovnání na rovnost (operátor „==“)

IEEE 754 na 8 bytech

  • Formát v pohyblivé řádové čárce s dvojitou přesností (double-precision floating-point format)
  • Používá 8 bytů (64 bitů)
    • Přesnost na cca 15 (dekadických) desetinných míst
  • Způsob uložení je úplně stejný jako u 4 bytů, jen se liší velikost exponentu a mantisy
    • Znaménko 1 bit
    • Mantisa 52 bitů
    • Exponent 11 bitů

Kódy pro uložení znaků a řetězců

Uložení znaků

  • Přiřazují každému znaku zvolené abecedy nezáporné celé číslo
  • Existuje mnoho kódů

Uložení řetězců

  • Řetězec je složen z jednotlivých znaků (v daném kódování)
  • Řetězec má délku udávanou v počtu znaků
  • Způsob uložení v paměti závisí především na použitém programovacím jazyce
    • Java
      • String
        • Řetězec je neměnná (immutable) instance třídy
        • Znaky řetězce jsou v instanci uloženy jako pole znaků (char[])
        • Řetězec tak může mít libovolnou délku
      • StringBuilder/StringBuffer
        • Měnitelný řetězec
        • Kromě délky má i kapacitu (kolik znaků lze do řetězce uložit), která je rovněž proměnná
        • Znaky řetězce jsou v instanci rovněž uloženy jako pole znaků (char[])
        • Řetězec tak může mít libovolnou délku
    • C
      • Řetězec je pole bytů začínající indexem 0
      • Za posledním platným znakem řetězce je přidán znak s hodnotou 0 (tj. '\0' nikoliv znak '0')
      • Řetězec tak může mít libovolnou délku
      • V řetězci se nesmí vyskytnout znak '\0'
    • Pascal
      • Řetězec je pole bytů, znaky jsou uloženy od indexu 1
      • Na indexu 0 je uložena délka řetězce, která je tak omezena na maximálně 255 znaků
      • Platí pro původní specifikaci jazyka Pascal
        • Jeho novější mutace (např. FreePascal) obsahují i další typy řetězců

Uložení logického datového typu (boolean)

  • Též booleovský datový typ
  • Ukládají se jen dvě hodnoty
    • true (pravda, logická 1)
    • false (nepravda, logická 0)
  • Prakticky se realizují pomocí celočíselného bezznaménkového typu
  • Některé jazyky specifický logický typ nemají a používají místo něj celočíselný typ
    • Např. C

Problém ukládání dat do fyzické paměti

  • Týká se všech datových typů, jejichž hodnoty jsou uloženy na více než jednom bytu tj. většina)
    • Demonstrujeme na uložení neznaménkového čísla na 4 bytech (01A2B3C4)H počínaje adresou 1000
  • Pokud má datový typ větší délku než jeden byte, pak jsou dvě možnosti, jak tyto byty uložit do fyzické paměti
    • Big Endian (BE) „vyšší řády na nižší adrese“ „přirozené“ uložení
      • Číslo bude uloženo jako 01 A2 B3 C4
        • Adresa 1000: 01
        • Adresa 1001: A2
        • Adresa 1002: B3
        • Adresa 1003: C4
    • Little Endian (LE) „vyšší řády na vyšší adrese“ „obrácené“ uložení
      • Číslo bude uloženo jako C4 B3 A2 01
        • Adresa 1000: C4
        • Adresa 1001: B3
        • Adresa 1002: A2
        • Adresa 1003: 01
  • Obecně se nedá říct, s kterým způsobem se setkáme více
    • Je běžné, že se oba způsoby vyskytují na jednom počítači
  • Může způsobit potíže při zápisu a následném čtení binárních souborů
    • Je potřeba vědět, zda je soubor zapsán jako LE nebo BE
  • Způsob záleží na
    • Procesoru
      • Např. Intel LE, Motorola BE
    • Operačním systému
      • Windows LE
    • Programovacím jazyce
      • Java BE
        • Zaručuje přenositelnost binárních souborů
          • Pokud však byly zapsány i přečteny programem napsaným v Javě
      • V mnoha programovacích jazycích není určen a přebírá se způsob od operačního systému