Datové typy a jejich reprezentace v počítači. Celá čísla. Reálná čísla. Semilogaritmický tvar. Komplexní čísla. Řetězce. Tomáš Bayer bayertom@natur.cuni.cz Katedra aplikované geoinformatiky a kartografie, Přírodovědecká fakulta UK. 1 / 27
Obsah přednášky 1 Celočíselné datové typy 2 Zobrazení v pevné/plovoucí řádové čárce 3 Zákonitosti při práci s reálnými čísly 4 Reálné datové typy 5 Retězce 2 / 27
1. Základní datové typy Přehled základních datových typů: celočíselné, logické, reálné a znakové. Nalezneme prakticky ve všech programovacích jazycích. U každého jednoduchého datového typu definována jeho velikost v bajtech a rozsah. Python patří mezi dynamicky typované jazyky, datový typ u proměnné nemusíme uvádět. Vyjádření v různých číselných soustavách: dvojková (binární) soustava: 0011, desítková (decimální) soustava (znaky 0-9): 1987, šestnáctková (hexadecimální) soustava (znaky 0-9, a-f): 16af. Celočíselné datové typy: Reprezentace diskrétních jevů, výpočty bezchybné. Reálné datové typy: Reprezentace spojitých jevů, výpočty zatíženy chybou. 3 / 27
Celočíselné datové typy 2. Celá čísla a jejich reprezentace v počítači Tyto datové typy, které nazýváme celočíselnými datovými typy. Liší se počtem cifer a tím pádem i rozsahem hodnot, které do nich lze uložit. Dělení podle přesnosti: Typy s nižší přesností bývají označovány jako short. Typy s vyšší přesností označovány jako long. Dělení podle znaménka: Celočíselné datové typy se rozdělují na typy se znaménka a bez znaménka. Typy bez znaménka označovány jako unsigned, Typy se znaménky označovány jako signed. V programovacím jazyku nemusí být zastoupeny všechny kombinace datových typů. U dynamicky typovaných jazyků se nerozlišují. 4 / 27
Celočíselné datové typy 3. Přehled celočíselných datových typů: Přehled celočíselných datových typů v programovacích jazycích: C++, Java, Python (v. 2.x) Velikost Rozsah Znaménko C++ Java Python 2.x 1B 128, 127 ano signed char byte - 1B 0, 255 ne unsigned char - - 2B 32768, 32767 ano int short integer 2B 0, 65536 ne unsigned - - 4B 2 31, 2 31 1 ano long int long 4B 0, 2 32 1 ne unsigned long - - 8B 2 63, 2 63 1 ano - long - 5 / 27
Celočíselné datové typy 4. Celočíselné hodnoty Rozsah představován maximální a minimální hodnotou, které může proměnná tohoto datového typu nabývat. Závisí na počtu bitů které jsou použity na uložení číselné hodnoty v paměti. Pokud nevíme, jaký datový typ použít, a nemáme nějaké speciální požadavky, zpravidla používáme typ int. Python v. 3: sjednocení int a long, nemají horní limit. Omezení pouze dostupnou pamětí. Typ Velikost Rozsah long 32b unbounded long 64b unbounded 6 / 27
5. Logické hodnoty Celočíselné datové typy Vyjádřeny jako booleovské proměnné, v Pythonu typ Boolean. Obor hodnot: pravda True, nepravda False. Mají také celočíselnou reprezentaci (z Pythonu 2.x): Příklad: 1 = True 0 = False. a = False b = True c = 2 * b + a; #Arithmeric operations Uplatňuje se zejména při konstrukci logických podmínek. if a: # do something 7 / 27
Zobrazení v pevné/plovoucí řádové čárce 6. Reálná čísla a jejich reprezentace v počítači Reálná čísla se používají pro reprezentaci desetinných čísel. Většina výpočtů probíhá právě s reálnými čísly. Reálná čísla R lze vyjádřit nekonečně dlouhým desetinným rozvojem. Používána pro vyjádření spojitých jevů. Výpočty v pomalejší než nad celými čísly. Důležitá volba správného datového typu. Reálná čísla lze v počítači reprezentovat dvěma způsoby: reprezentace s pevnou řádovou čárkou (FX), reprezentace s pohyblivou řádovou čárkou (FP). 8 / 27
Zobrazení v pevné/plovoucí řádové čárce 7. Zobrazení s pevnou řádovou čárkou Řádová čárka oddělující celou desetinnou část čísla od celé části je umístěna na pevné pozici. První bit znaménkový, pro celočíselnou část je vyhrazeno n bitů, pro desetinnou část m bitů. Rozsah zobrazitelných čísel je dán intervalem 2 n 1, 2 n 1 2 m. Přesnost znázornění čísel v pevné řádové čárce závisí na počtu bitů použitých pro jejich reprezentaci. Nevýhody: Všechna čísla jsou zobrazována se stejnou absolutní přesností. Malá čísla zobrazována s nízkou relativní přesností. Nelze reprezentovat taková čísla, která ve FP jdou. Při vědeckých výpočtech však požadujeme, aby byla všechna čísla uložena se stejnou relativní přesností. 9 / 27
8. Příklady Zobrazení v pevné/plovoucí řádové čárce Znázornění čísel čísel x 1 = 4.625 a x 2 = 4.6 v pevné řádové čárce. 8 bitová reprezentaci (3 4). První číslo lze reprezentovat s tímto počtem bitů přesně, druhé již nikoliv. Počet bitů pro znázornění desetinné části není dostatečný, dochází k přeplnění. ε x1 = δ x1 /x 1 = 0.0%, ε x2 = δ x2 /x = 0.8%. Vliv relativní chyby: Čísla x 1 = 1000.5, x 2 = 1.6. Přesnost reprezentace δ x1 = δ x2 = 0.05. Pak ε x1 = δ x1 /x 1 = 0.005%. ε x2 = δ x2 /x 2 = 3.1%. 10 / 27
9. Zobrazení čísel s pohyblivou řádovou čárkou (FP) Semilogaritmický tvar čísla: Při zobrazení čísel s pohyblivou (resp. s plovoucí řádovou čárkou) používáme semilogaritmický tvar čísla. Lze ho vyjádřit ve tvaru: a = q z e. (1) Hodnota q představuje mantisu čísla a, hodnota z je základ číselné soustavy, e představuje exponent. Mantisa je zobrazována vždy přímým kódem. Splňuje normalizační podmínku ve tvaru Levá část nerovnosti zajišt uje, aby nedošlo ke ztrátě přesnosti. Pravá část zajišt uje, aby nedošlo k přeplnění. Číslo splňující normalizační podmínku nazýváme normalizované. 1 q < 1. (2) z Mantisu zobrazujeme v celočíselné části řádové mřížky, exponent v desetinné části. Výhodou efektivnější ukládání dat a stejná relativní přesnost všech čísel. FP vhodná pro příliš malá nebo příliš velká čísla (nelze použít FX).
Zobrazení v pevné/plovoucí řádové čárce 10. Semilogaritmický tvar v praxi Zpravidla pro reprezentaci reálných čísel použity 4 byty (float). Definice v normě IEEE 754. Znaménko: 1 bit Mantisa: 23 bitů Exponent: 8 bitů. Důsledky: Poslední bit: 2 22 2.38 10 7. Maximálně sedm platných cifer. Pro přesnější reprezentaci používán datový typ double s délkou 8 byty. 15 platných cifer. Znaménko: 1 bit Mantisa: 47 bitů (2 46 1.42 10 14.) Exponent: 16 bitů. 12 / 27
Zobrazení v pevné/plovoucí řádové čárce 11. Příklad znázornění čísla v plovoucí řádové čárce Znázornění čísla 2 16 = 65536 v FX reprezentaci (1,5): x = (65536) 10 = ((65536/2 17 )2 17) ( = +0, 5 2 +17) = (0.100011) 10 10 2, δ = (65536 0, 5 2 +17 ) = 0.0, ε x1 = δ/x = 0.0%.Přesné. 0 1 0 0 0 1 1 Znázornění čísla 4.625 v FX reprezentaci (6+4): x = (4.625) 10 = ((4.625/2 3 )2 3 ) 10 = ( +0, 578125 2 +3) 10 = (0.100101 1000) 2, δ = (4.625 (2 1 + 2 4 + 2 6 )8) = 0, ε x = δ/x = 0%.Přesné. 0 1 0 0 0 1 0 0 1 0 1 Znázornění čísla 4.6 v FX reprezentaci (6+4): x = (4.600) 10 = ((4.600/2 3 )2 3) ( = +0, 575 2 +3) (0.100100 1000) 10 10 2, δ = (4.600 (2 1 + 2 4 )8) = 0.100, ε x = δ/x = 2.2%.Nepřesné. 0 1 0 0 0 1 0 0 1 0 0 Tomáš V FX Bayer reprezentaci bayertom@natur.cuni.cz (rámcově) srovnatelná (Katedra přesnost. Datové aplikované typy a jejich geoinformatiky reprezentacea kartografie, v počítači. Přírodovědecká fakulta UK.) 13 / 27
12. Přetečení, podtečení Dochází k nim při práci s příliš velkými či příliš malými čísly. Podtečení: Pokud je číslo a < a min, dochází k podtečení. Přetečení: Pokud je a > a max, dochází k přetečení. Důsledkem obou operací je ztráta přesnosti, dojde k zaokrouhlení čísla. Důsledek přetečení: Výsledek nevejde do počtu bitů určených pro exponent. Přetečení do znaménkového bitu, změna znaménka. Znázornění čísla 2 32 = 4294967296 v FX reprezentaci (1,5): x = (4294967296) 10 = ((4294967296/2 33 )2 33) ( = +0, 5 2 +33) = (1.100011) 2, 10 10 δ = ( 65536 0, 5 2 +33 ) = 4.3 10 9, ε x1 = δ/x = 100.0%.Přetečení. 1 1 0 0 0 1 1 Důsledek podtečení: Pokud dojde k podtečení, je výsledkem operace hodnota +0 nebo 0.
Zákonitosti při práci s reálnými čísly 13. Problémy při práci s reálnými čísly (1/2): Rovnost dvou čísel: Porovnáváme -li dvě reálné hodnoty a, b, pak podmínka a = b (3) v obecném případě nebude pravdivá. V průběhu výpočtů dochází k zaokrouhlování a následné ztrátě přesnosti. Nebudeme testovat rovnost dvou čísel a, b, ale absolutní hodnotu jejich rozdílu a b s hodnotou ε 0: a b < ε. (4) Komutativní zákon: Vzhledem k tomu, že při práci s reálnými čísly dochází k jejich zaokrouhlení, nemusí platit komutativní zákon pro sčítání a násobení. a + b b + a a b a + ( b) (a + b) a b ab ba ( a)b (ab) Tomáš Bayer bayertom@natur.cuni.cz (Katedra Datové aplikované typy a1a jejich geoinformatiky reprezentace a a kartografie, v počítači. Přírodovědecká fakulta UK.) 15 / 27
Zákonitosti při práci s reálnými čísly 14. Problémy při práci s reálnými čísly (2/2): Asociativní zákon. Z výše uvedených důvodů nemusí platit ani asociativní zákony pro sčítání a násobení: a + (b + c) (a + b) + c a(bc) (ab)c Distributivní zákon. Z výše uvedených důvodů nemusí platit ani distributivní zákon: (a + b)c ac + bc. Rychlost aritmetických operací. Rychlost aritmetických operací s celými čísly je řádově vyšší než u reálných čísel. Při návrhu algoritmu zvážit, které proměnné celočíselné, a které reálné. 16 / 27
Reálné datové typy 15. Reálná čísla a jejich reprezentace v počítači Přehled reálných datových typů v programovacích jazycích: C++, Java, Python. Velikost Rozsah Znaménko C++ Java Python 4B 1.4 10 45, 3.4 10 38 ano float float float 8B 4.9 10 234, 1.7 10 308 ano double double - 10B 1, 190 10 4932 ano long double - - ano - - complex 17 / 27
16. Hodnoty INF a NaN Reálné datové typy Při práci s čísly se setkáme se dvěma speciálními hodnotami INF a NaN. Hodnota INF: Hodnota INF představuje nekonečno, získáme ho jako výsledek některých aritmetických operací, např. dělení nulou. math.sqrt(1/0) >>> ZeroDivisionError: division by zero Hodnota NaN: Představuje akronym Not a Number. Vzniká jako výsledek operací, který není definován, např. odmocnina ze záporného čísla. math.sqrt(-1) >>> ValueError: math domain error Vznikají jako důsledek použití hodnoty mimo definiční obor či neošetřených singularit. V některých programovacích jazycích nelze tyto stavy detekovat. 18 / 27
Reálné datové typy 17. IEEE 754 Definice standardů pro dvojkovou aritmetiku v FP. Vznikl v roce 1985. Jednoduchá přesnost (32 bit), dvojitá (64 bit), dvojitá rozšířená (80 bit)- Nečíselný výsledek: NaN. Nekonečno: Inf (kladné / záporné nekonečno). Mezní hodnoty: x min = 2 126, x max = 2 127. Neexistuje reprezentace: x < 0 x < x max : negative overflow, x < 0 x > x min : negative underflow, x > 0 x < x min : positive underflow, x > 0 x > x max : negative overflow. 19 / 27
18. Problémy Problém 1: Odečtení malého čísla od jiného čísla Výsledek operace je špatný. x = 1.0; y = 0.0000000000000000005 z = x - y >>> 1.0 Problém 2: Přičtení malého čísla k velkému číslu Porovnání dá špatný výsledek. x = 1.0e20 x == x + 1 >>> True Problém 3: Nefunkčnost asociativity pro malá a velká čísla a = 1 b = 1e20 c = -1e20 a + ( b + c ) ( a + b ) + c >>> 1.0 >>> 0.0
Reálné datové typy 19. Reálná čísla s volitelnou přesností Přesnost poskytovaná float reprezentací nemusí být postačující. Zaručuje však velmi rychlé výpočetní operace. Pro přesnější výpočty existuje v Pythonu modul decimal. Pomalejší než float Před použitím nutno importovat... import decimal a = decimal.decimal(1234) b = decimal.decimal("5678.01234567890123456789") a+b >>> Decimal('6912.01234567890123456789') Použití pro vědecké výpočty. V geoinformatice např. práce se souřadnicemi [x, y]. 21 / 27
Reálné datové typy 20. Komplexní čísla v Pythonu Reprezentovány dvojicí reálných čísel. Imaginární část označena identifikátorem j. z = -2.3 + 3.4j z.real >>> -2.3 z.imag >>> 3.4 z.conjugate() >>>(-2.3-3.4j) print(abs(z)) >>> 4.104875150354758 print(pow(z,2)) >>> (-6.27-15.639999999999999j) 22 / 27
Retězce 21. Kódování ASCII (American Standard Code for Information Interchange). 127 znaků (písmena, číslice, spec. znaky), 7b + 1b. Tímto postupem šlo adresovat pouze základní znaky. Problémy s ČJ, celkem 6 speciálních kódování: CP 1250, ISO 8859-2, Latin 2... UNICODE: 16b kódování, 2 nástupce ASCII, 1 114 112 znaků. Příkladem např. UTF-8, nejčastější kódování. Umožňuje vyjádřit libovolný znak z libovolného jazyka. Ukázka Escape sekvencí: Escape sekvence UNICODE Význam \n \u000a Nová řádka \r \u000d Návrat na začátek řádku \t \u0009 Tabulátor \\ \u005c Zpětné lomítko \' \u002c Apostrof \" \u0022 Uvozovky 23 / 27
Retězce 22. ASCII tabulka 24 / 27
23. Řetězce v Pythonu Retězce Posloupnost znaků uzavřená v uvozovkách nebo apostrofech. Double quotes vs. Single Quotes. V Pythonu konstantní, nelze modifikovat. a = "Hello" b = 'Hello' V praxi není mezi oběma způsoby rozdíl. Sčítání řetězcových konstant prostřednictvím operátoru +. s = "Hello \n" + "world"; >>> Hello >>> world Délka řetězce: len(s) >>> 13 Výskyt podřetězce v řetězci: "wo" in len(s) >>> True 25 / 27
Retězce 24. Operace s řetězci v Pythonu (1/2) Práce s řetězci podobná práci s polem, každý znak má index Index obousměrný. s[-11] s[-10] s[-9] s[-8] s[-7] s[-6] s[-5] s[-4] s[-3] s[-2] s[-1] H e l l o w o r l d s[0] s[1] s[2] s[3] s[4] s[5] s[6] s[7] s[8] s[9] s[10] Lze vytvářet podřetězce (slices): Příklady: seq[index] #1 znak seq[start:end] #interval od-do seq[start:] #vsechny znaky od seq[:end] #vsechny znaky od seq[start:end:step] #Interval od-do s krokem s[0:10:2] >>> Hlwr s[::2] >>> Hlwl s[::-2] >>> drwolh 26 / 27
25. Operace s řetězci v Pythonu (2/2) Replikace řetězců: print(s * 3) >>> Hello worldhello worldhello world Konverze znaku na ASCII reprezentaci ord(d) >>> 100 Konverze ASCII reprezentace na znak chr(100) >>> d Znak s maximálním/minimálním ASCII kódem min(s) >>> #mezera max(s) >>> w Delimitace s = "Hello*my*new*world" s.split('*') >>> ['Hello', 'my', 'new', 'world'] Další užitečné funkce jsou v modulu string import string