ukotvit menu |
Číslo představuje hodnotu něčeho, třeba množství, rychlost nebo váhu. Lidstvo si během věků vytvořilo řadu různých číselných soustav, v kterých je stejná hodnota uvedena jiným číslem. Dnes se běžně a převážně používá desítková (decimální) soustava, v které se všechny čísla skládají z deseti cifer 0 až 9.
Programátoři ale používají i další soustavy a to dvojkovou (binární), osmičkovou (oktalovou) a šestnáctkovou (hexadecimální). Obecně lze také hovořit o číselné soustavě o základu 2, 8, 10 a 16. Čistě teoreticky lze mít i soustavy o jiném základu, ale jestli se někde používají, tak velmi vzácně. Základ soustavy nám říkám, kolik používá samostatných cifer.
Další kapitolou je zápis čísla. My jsme zvyklí používat arabské číslice, (ale známe třeba i římská čísla), které používáme k zápisu všech soustav. U soustav se základem větším než 10 si pak pomáháme písmeny abecedy. U šestnáctkové soustavy tak znak A nese hodnotu deset, B jedenáct a končí to znakem F, který nese hodnotu patnáct. Oproti tomu u dvojkové soustavy se veškerá čísla zapisují jen pomocí dvou znaků, jedna a nula. Pro lepší představu uvádím tabulku 32 prvních hodnot v různých soustavách
Soustava o základu | ||||||||
---|---|---|---|---|---|---|---|---|
10 | 2 | 8 | 16 | 10 | 2 | 8 | 16 | |
0 | 0 | 0 | 0 | 16 | 10000 | 20 | 10 | |
1 | 1 | 1 | 1 | 17 | 10001 | 21 | 11 | |
2 | 10 | 2 | 2 | 18 | 10010 | 22 | 12 | |
3 | 11 | 3 | 3 | 19 | 10011 | 23 | 13 | |
4 | 100 | 4 | 4 | 20 | 10100 | 24 | 14 | |
5 | 101 | 5 | 5 | 21 | 10101 | 25 | 15 | |
6 | 110 | 6 | 6 | 22 | 10110 | 26 | 16 | |
7 | 111 | 7 | 7 | 23 | 10111 | 27 | 17 | |
8 | 1000 | 10 | 8 | 24 | 11000 | 30 | 18 | |
9 | 1001 | 11 | 9 | 25 | 11001 | 31 | 19 | |
10 | 1010 | 12 | A | 26 | 11010 | 32 | 1A | |
11 | 1011 | 13 | B | 27 | 11011 | 33 | 1B | |
12 | 1100 | 14 | C | 28 | 11100 | 34 | 1C | |
13 | 1101 | 15 | D | 29 | 11101 | 35 | 1D | |
14 | 1110 | 16 | E | 30 | 11110 | 36 | 1E | |
15 | 1111 | 17 | F | 31 | 11111 | 37 | 1F | |
32 | 100000 | 40 | 20 |
Jak je možno si všimnout, tak číslo zapsané jako 10 v různých soustavách znamená různou hodnotu. Dva v binární, osm v oktalové, deset v desítkové a šestnáct v hexadecimální. Proto když někde vidíme zapsané číslo, musíme vědět v jaké je soustavě, abychom rozuměli jeho hodnotě.
Python umí přímo pracovat se všemi výše uvedenými soustavami. Aby Python mohl rozlišit v které soustavě je číslo zapsáno, zapisuje se před samotnou hodnotu rozlišovací prefix. Tyto prefixy jsou standardní a používají se i v jiných programovacích jazycích. Číslo zapsané do zdrojového kódu s prefixem je literál čísla. Více se o literálech dočtete v kapitole o datových typech.
soustava | základ | prefix | příklady | poznámka |
---|---|---|---|---|
binární | 2 | 0b | 0b1, 0b0001, 0b1111, 0b... | od Pythonu 3.0 |
oktalová | 8 | 0 | 01, 010, 01234, 0... | do Pythonu 2.x včetně |
oktalová | 8 | 0o | 0o1, 0o10, 0o1234, 0o... | od Pythonu 3.0 |
decimální | 10 | 0, 1, 10, 1234, ... | ||
hexadecimální | 16 | 0x | 0x1, 0x10, 0xFF, 0x89AB, 0x... |
Nyní už by mělo být jasné, že tato čísla se rovnají, protože mají stejnou hodnotu:
0b1010 == 0o12 == 10 == 0xA
A naopak, že tato čísla se nerovnají, protože mají různou hodnotu:
0b10 != 0o10 != 10 != 0x10
Zvláště varuji před "okrasným" přidáváním nul na začátek čísla. To je chyba, která by laika mohla pěkně potrápit a možná by tento mohl Python zavrhnout, jako naprosto neschopný jazyk, který neumí sečíst ani dvě jednoduchá čísla:
>>> 010 + 010 16
Pamatujte si, že přidáním nuly na začátek čísla změníte u Pythonu do verze 2.x jeho hodnotu. U Pythonu 3.0 to není povoleno a dojde k vyvolání výjimky "SyntaxError: invalid token".
Interně má Python hodnotu celého čísla uloženu jako datový objekt typu int (u Pythonu 2.x byla ještě možnost long). Na tento datový objekt se automaticky převádí libovolný literál celého čísla. Při převodu datového objektu typu int na řetězec (třeba pro výpis na obrazovku) se tento převádí na číslo v decimální podobě (ať byl literál jakékoli soustavy, protože datový objekt typu int si nepamatuje informaci o číselné soustavě literálu, na základě kterého byl vytvořen). To je možno si jednoduše vyzkoušet:
>>> str(0b10), str(0o10), str(10), str(0x10) ('2', '8', '10', '16')
Python načte literál čísla, převede ho na datový typ int a předá ho funkci str(). Ta u každého datového objektu volá metodu __str__(), která slouží pro převod datového objektu do textové podoby. Tato je pak vypsána na terminál.
Pokud bychom potřebovali textovou podobu v jiné číselné soustavě,
máme na to v Pythonu k dispozici speciální funkce bin()
,
oct()
a hex()
. Funkce bin()
je k dispozici pouze u Pythonu 3 a vyšším. Ve starších Pythonech nejsou
binární literály k dispozici. Příklad použití:
>>> bin(10), oct(10), hex(10), bin(0xA), oct(0xA) ('0b1010', '0o12', '0xa', '0b1010', '0o12')
Jak je vidět, tyto funkce jako parametr přijímají literál libovolné
číselné soustavy a tak lze tyto soustavy převádět navzájem. Povšimněte si
rovněž, že funkce hex()
používá v literálu malá písmena
abecedy. Je to jedno, u hexadecimálních literálů Python velikost znaků
nerozlišuje.
Je nutno si uvědomit, že literály čísel nejsou textové řetězce a Python s nimi pracuje jako s čísly. Tedy je umí např. sečíst:
>>> 10 + 0xAA 180
Když Pythonu předložíme řetězce, tak je nesečte, ale spojí:
>>> '10' + '0xAA' '100xAA'
Proto je důležité rozlišovat mezi literály čísel a textovými řetězci
obsahující literály čísel. Pokud máte k dispozici literál celého čísla v
řetězci (tedy datovém objektu typu str), musíte si ho před použitím
převést na číslo (tedy datový objekt typu int). K tomu slouží funkce
int()
. Tato funkce umí převádět na int čísla všech soustav
o základu 2 až 36. Základ se musí uvádět jako parametr s výjimkou
základu 10, který je přednastavená. V řetězci může být číslo s prefixem
literálu i bez něj. Ale i v případě že je s prefixem, je nutno základ
uvést, protože funkce int()
se základ čísla podle prefixu
nesnaží zjistit.
int('10') => 10 # typické použití převodu řetězce na číslo int('10', 10) => 10 # to samé s uvedeným základem 10 int('10', 2) => 2 # se základem 2 text '10' znamená jiné číslo int('0b10', 2) => 2 # to samé, správný prefix není na závadu int('0b10', 8) => err # toto nelze, nesprávný prefix pro základ 8 int('0o10', 8) => 8 # toto už lze, prefix a základ je v souladu int('10', 8) => 8 # taky žádný problém, prefix není nutný int('20', 16) => 32 # hexadecimální soustava také není problém int('0x20', 16) => 32 # ani s prefixem int('x', 36) => 33 # v soustavě o základu 36 znak 'x' má hodnotu 33
Teď už si tedy umíme poradit i s touto úlohou. Máme textový řetězec s číslem 0x123456789ABCDEF. Převeďte jej na řetězec, kde je toto číslo v binární podobě.
>>> bin(int('0x123456789ABCDEF', 16)) '0b100100011010001010110011110001001101010111100110111101111
A kdyby nám vadil ten binární prefix, tak potom takto:
>>> bin(int('0x123456789ABCDEF', 16))[2:] '100100011010001010110011110001001101010111100110111101111'
Pro úplnost. V Pythonu jsou i jiné funkce pro převod textového řetězce na
číslo. Např. funkce float()
slouží pro převod desetinného
čísla v řetězci. Např: float('10.0') =>
10.0
Desetinná čísla nejsou jiná číselná soustava, ale jiný datový typ.
Python umožňuje pracovat s desetinnými čísly jen v desítkové soustavě.
To znamená, že např. neexistuje literál pro zápis čísla 0.5 v oktalové
soustavě, kterému by Python rozuměl. Proto i zápis oct(0.5)
skončí s chybou.