Pohyblivá řádová čárkaComputerphile

Thumbnail play icon
Přidat do sledovaných sérií 10
93 %
Tvoje hodnocení
Počet hodnocení:217
Počet zobrazení:8 755

Počítače by měly být přeci dokonale přesné, tak proč nám tvrdí, že 0,1 + 0,2 = 0,3000...1?

Přepis titulků

Lidé očekávají, že počítače budou s čísly naprosto přesné. Vyrůstáte s kalkulačkou a očekáváte, že když napíšete 0,1 + 0,2, tak vyjde 0,3. A dříve či později každý programátor něco takového zkusí napsat. A napíšou to v programovacím jazyce. Něco jako 0,1 + 0,2. Stisknou Enter a počítač jim napíše něco jako 0,3000...1. A v ten moment se dozví o pohyblivé řádové čárce a začnou si trhat vlasy.

Pohyblivá řádová čárka je v podstatě vědecká notace. Řekněme, že jste astrofyzik a máte rychlost světla, což je tohle ohromné číslo s osmi nulami. A chceme ho vynásobit velmi krátkou vzdáleností. Ani nezáleží, co měříme, jde jen o velké a malé číslo. Třeba 0,000...15. Řekněme, že je chceme vynásobit.

Udělal jsem to schválně snadné. Mohli byste zkusit nějakou komplikovanou matematiku a vyřešit to, ale nemusíte. Protože ve vědecké notaci je tohle 3x10^8. A tohle je 1,5x10^-7. Nemusíte dělat nic moc složitého, abyste je vynásobili. Stačí jen vynásobit tyto, což je 4,5 a pak sečíst tyto exponenty. Takže 8 + (-7) = 1. Vyjde nám 4,5x10^1 neboli 4,5x10 neboli 45.

Paráda, to je o dost snazší než zkoušet pracovat s velkými čísly. A také nás to přivádí ke konceptu platných číslic, protože rychlost světla není přesně 3x10^8, ale 2,997...něco. Na konci je spousta číslic, které nejsou pro běžné výpočty podstatné. Zaokrouhlíme to a řekneme, že je to 3x10^8. Nebo abychom byli přesní, tak 2,997x10^8, ale čísla za tím nás moc nezajímají. Udržte tu myšlenku, k platným číslicím se vrátíme později.

Dvě hlavní výhody pohyblivé řádové čárky jsou rychlost a efektivita. Rychlost, protože pohyblivá řádová čárka se používá už mnoho let a počítače si s ní dnes poradí velmi rychle. A efektivita, protože se vypořádá s opravdu velkými čísly velikosti vesmíru a velmi malými čísly velikosti atomu bez potřeby ohromného množství prostoru. Pokud byste měli formát, který by zahrnoval velikost vesmíru a velikost atomu, tak byste potřebovali tolik nul na obou koncích, nebo něco obzvlášť komplikovaného, aby to počítač zpracoval, že by to bylo buď velmi neefektivní, ukládat jedno číslo jako megabajt, nebo byste potřebovali něco velmi složitého pro počítač, když by se pokoušel zpracovat všechna ta čísla.

Promluvme si o desítkové soustavě, o nás, lidech. O náhle zapnutých světlech, divný... V desítkové soustavě, našich normálních lidských číslech... Deset číslic, desítková soustava. Máme stovky, desítky, jednotky, což znáte ze základní školy.

A pak máme desetiny, setiny a tisíciny. Když máte v desítkové soustavě jednu desetinu, tak to znamená 0,1. To je normální a přirozené. V binární soustavě počítačů to tak ale není. Protože ty vidí čtyřky, dvojky, jedničky a pak poloviny, čtvrtiny, osminy a šestnáctiny. Není tam žádná 0,1. Vlastně, 0,1 v binární soustavě je 0,00011. A to 0011 je periodické.

Je to tedy 0,000110011... a tak dál až do nekonečna, což je zajímavé, protože 32-bitové počítače, které používáme, ukládají jen 23 platných číslic. Také ukládají, kde je desetinná čárka. Vlastně dělají vědecké notace v binární soustavě, což je pohyblivá řádová čárka. Takže máme tohle dlouhé binární číslo krát dvě na několikátou. A to je problém, protože tím ztrácí přesnost. Nerozumí periodicitě. A v desítkové soustavě je pro to analogie.

Když se pokusíte zapsat třetinu decimálně, tak máme stovky, desítky, jednotky, desetiny, setiny, tisíciny a pak to zkusíme a skončíme s 0,333... periodických. A teď si představte, že nerozumíte periodickým číslům. Jako počítač, jako když je z vědecké notace vyjmuta ta perioda. Stejně jako pohyblivá řádová čárka nerozumí. Tady dáme všechno dohromady. Když jste v desítkové soustavě, tak řekněme, že máte 1/3 + 1/3 +1/3.

Jako lidé počítáme, 0,3 periodických + 0,3 periodických + 0,3 periodických, což je 1. Ale řekněme, že jste počítač a nerozumíte periodicitě, protože pohyblivá řádová čárka jsou v základu platné číslice. Takže počítač by počítal 0,33333... + 0,333... + 0,333... a sečte to na 0,999999... A po chvíli přestane, protože mu dojdou číslice. A právě tomu se říká zaokrouhlovací chyba pohyblivé řádové čárky.

Zkusme to v binární soustavě. Zkusme 1/10 + 2/10. Což je 0,000110011... až nám dojdou číslice, protože aritmetika pohyblivé řádové čárky na 32-bitových počítačích ukládá jen 23 číslic. A pak přičteme 2/10, což je 0,00110011... Nebudou to zkoušet, protože by to trvalo věky, ale stane se přesně to samé co tady. Po 23 číslicích v 32-bitové aritmetice, v 64-bitech by to bylo 56 číslic, se to usekne, protože to nerozumí periodicitě. Takže pohyblivá řádová čárka se podívá na 1/10 + 2/10, což jste právě napsali, 0,1 + 0,2 v desítkové soustavě, a řekne, že 1/10 + 2/10 ≠ 3/10.

Protože pro pohyblivou řádovou čárku se to nerovná. Téměř ve všech případech je to dostatečně přesné. Většinou nepotřebujete víc než 23 čísel 32-bitové přesnosti, pokud ano, tak použijete 64-bitů. Když děláte 3D hru a potřebujete vědět, kde něco na obrazovce zobrazit, tak nezáleží, jestli je to o setinu nebo tisícinu pixelu mimo, protože to bude na správném místě.

A když děláte velké výpočty, tak nezáleží, pokud malinký zlomek, něco malého jako molekula, je mimo, protože to bude vypadat víceméně správně. Správně podle každé přesnostní tolerance, kterou by mohl skutečný svět potřebovat. Ale znamená to, že když se zabýváte měnou a sčítáte 10 pencí neboli 0,1 liber k 20 pencím, tak na tohle každý programátor dříve či později narazí.

My počítáme takhle, snadné. Počítač ale řekne, že je to vlastně tolik pencí. A pak u těchto specifických lidských věcí si té chyby všimneme, protože je nám to najednou opravdu zřejmé. To je problém s pohyblivou řádovou čárkou a pro opravu při práci s měnami buď použijete decimální datový typ v pokročilejších programovacích jazycích nebo vše uložíte jako celé číslo (integer) v případě pencí nebo centů a na konci vydělíte stem.

Pohyblivá řádová čárka je něco, co opravdu mate hodně lidí. Dokud si neuvědomíte, že je to jen vědecká notace. Stejná věc, jakou jsme se učili ve škole. Jen v binární soustavě. Jsou to poloviny, čtvrtiny a osminy. A jakmile si uvědomíte, že to ukládá danou délku čísla a pak zjišťuje, kde má být desetinná čárka a jsou to jen platné číslice. Začne to být o dost snazší. A začnete si uvědomovat, proč když napíšete 0,1 + 0,2, tak nedostanete 0,3.

Překlad: Foxtrot www.videacesky.cz

Komentáře (25)

Zrušit a napsat nový komentář

Odpovědět

To mi priponulo tú hádanku:
Do hotelu přišli tři lordi. V recepci si řekli za jeden pokoj 10 liber, které každý z gentlemanů zaplatil - dohromady 30 liber.
Když měl poslíček odnést pánům zavazadla, přispěchal ředitel hotelu, že měli hosté zaplatit jen 25 liber. Dal tedy poslíčkovi pět liber, ať je lordům vrátí.
Poslíček nevěděl, jak rozdělit 5 liber mezi tři osoby, tak dal každému po libře a dvě si nechal.
Každý tedy zaplatil 9 liber (deset původně, jednu dostal zpět). 3x9=27. Dvě libry si nechal poslíček. 27+2=29. Kam zmizela jedna libra?

52

Odpovědět

Je to sranda ako sa dá zblbnúť mozog a nevšimnúť si, že namiesto odčítania, niekto sčíta to čo páni vytiahli z peňaženky s tým, čo si naopak poslíček do peňaženky dal. Skrátene, páni hotel obohotili o 27 libier a poslíček hotel obral o 2. čiže 27-2. Ja som sa nad tým príkladom tiež vminulosti pozastavil a nechápal som, čo sa to deje :D

41

Odpovědět

+RododendronA nebo : Meli dohromady zaplatit 25,- ale zaplatili 27, protože si poslíček 2Kč nechal. Cílová částka 30kč v tu chvíli nehraje roli. Pokud budu bazirovat na 30kč musím počítat jinak. 30 zaplaceno = 25+5vráceno ředitelem => 25+3vráceno poslíčkem+2ponecháno

31

Odpovědět

To si človek najprv trochu ponadáva, kým na to príde sám. Porovnávať float operátorom == je čistá programátorská samovražda.

111

Odpovědět

praise be

11

Odpovědět

Má to něco společného s tím, že když platím v bance, tak mi to odečte z účtu vždy o 0.0011 Kč víc? Například platím 150Kč, tak do potvrzovací sms mi dojde, že jsem zaplatil 150,0011Kč.

112

Odpovědět

Ne, to znamená, že posíláte 150,00 a ta 11 na konci znamená měnu CZK nikoliv hodnotu. A ještě to znamená, že máte pravděpodobně účet u Raiffeisenbank :-D

551

Odpovědět

Velmi zajímavé video, ocením nějaké další od tohoto člověka.

361

Odpovědět

Jak tu někdo psal, že stále po zhlednutí videa nechápe, proč to tak vyjde, tak je to proto, že to nejdůležitější vynechal. Právě v tom sčítání, co by řekl že je hrozně zdlouhavé, tak v podstatě se binární kód "uřízne" v určitých mocninách dvou, a tudíž když to pak sčítáte, sečtou právě ty nuly a jedničky pod sebou jak on to měl, a to se zpět převede do desítkové soustavy, ale protože bylo číslo uřízlé těsně "za jedničkami" a ne "za nulami", tak se číslo zdá trochu větší, takže při sečtení vyjde číslo o malinko větší ve dvojkové soustavě, a když se převede zpět na desítkovou, znamená to součet mocnin dvou, tedy jak říkal poloviny, čtvrtiny osminy atd, a ty vyjdou celkově o malinko více, než je desítkové číslo 3. A právě proto že to neukázal názorně na tom příkladu, což by mi přišlo celkem jednoduché (23 cifer neni zas tolik a sčítání ve dvojkové soustavě je celkem jednoduché) a pak by bylo vidět, že při převedení zpět vyjde číslo o malinko větší.
Teda přišlo by to zřejmé člověku, kdo rozumí dvojkové soustavě a video by bylo maximálně o minutu delší.
Ale snad jsem to trochu osvětlil pro ty, co tomu ještě trochu nerozuměli.

343

Odpovědět

Myslím že pro většinu lidí by musel vysvětlit proč 1 + 1 = 10 :)

261

Odpovědět

+MalkyInu, lidé se dělí na 10 částí - ti kteří rozumí dvojkově soustavě a ti, kteří ne... :)

131

Odpovědět

+Malkyne na "10 částí" ale "do 10 skupin" .... zní i vypadá to lépe a dává to oproti "částem" i logiku .-)

01

Odpovědět

9 minutové video kde je pouze řečeno, že i jiné soustavy než desítková mají periodická čísla.
A popis videa vyvolává dojem, že většina lidí považuje pc za nějakou kouzelnou krabičku, kterou ovládá národ skřítků. Takže by jim spíše prospělo video o tom, jak funguje tranzistor a jak se z něj staví základní logické hradla.

920

Odpovědět

Odpovědět

Cítím se fakt hloupě, ale ani po zhlédnutí videa pořád nechápu, proč by počítač při sčítání 1/10 + 2/10 napsal 0,300000...1.

134

Odpovědět

ze stejného důvodu, jako když překládáš text z češtiny do angličtiny a při reverzním překladu dostaneš něco jiného

tak zde je ten překlad je o mnoho snazší, ale má také své limity, rozdíl ve "zbytcích"
zde nastává problém, že jakákoliv číselná soustava obsahuje čísla, která nemají ukončený rozvoj (desetinný např. číslo 1/3, binární např. číslo 1/10 převedené do binární soustavy 0,0001100110011...)...tzn. překlad programu z dekadických vstupů do binárních a zpět do dekadických přináší úskalí, protože počítač si nemůže pamatovat číslo až do nekonečna, ale má proto vyhrazen jistý prostor (32-bit...23 řádů, 64-bit 50+ řádů), takže ten rozdíl, ta chyby, např. u těch třetin bude na posledním digitu (např. u 32-bitového na 23. místě)

ztraceno v překladu

321

Odpovědět

1) Výsledek sčítání dvou periodických čísel číslici po číslici bude v některých případech více či méně zaokrouhlený (0.33333333333... + 0.33333333333...).
2) 1/3 je příklad periodického čísla v desítkové soustavě.
3) 1/10 je příklad periodického čísla ve dvojkové soustavě.

01

Odpovědět

+Tomáš Jeziorskýtady někdo dělal výpisky z odkazu nad :D

01

Odpovědět

Proč 1/10 = 0,000110011... ?

159

Odpovědět

je to úplne jednoduché , zoberieš desatinú časť číslo , a postupuješ:
1/10 = 0.100 = 100

100 *2
0|200 *2
0|400 *2
0|800
1|600
1|200
0|400
0|800
1|600
1|200

atd

107

Odpovědět

+anffPřesněji:

0 *1/2 celkpvě 0
0 *1/4 celkově 0
0 *1/8 celkově 0
1 *1/16 celkově 1/16=0,0625
1 *1/32 celkově 1/16+1/32=0,0625+0,3125=0,09375
0 *1/64 celkově 0,09375
0 *1/128 celkově 0,09375
1 *1/256 celkově 0,09375+1/256=0,09765625
1 *1/512 celkově 0,09765625+1/512=0,099609375

A proto je tam ta periodicita. Ve dvojkové soustavě čím více máš cifer za desetinou částkou, tím více se blížíš k racionálnímu číslu 0,1.
Zkrátka ve dvojkové soustavě je 0,1 zapsané jako iracionální číslo a tedy čím více řádů, tím blíže jsi 0,1 v desítkové soustavě.
Stejně jako 1/3 v desítkové soustavě se dá zapsat jako 0,3 nebo 0,33 nebo 0,333 atd, a čím víc cifer za desetinou řádkou, tím jsi blíže zlomku 1/3

151

Odpovědět

+anffanff: Možná bylo dobré říct, co to je a jak to funguje. Jedná se přímý výpočet binárního zápisu čísla za desetinnou čárkou. Je to analogie pro výpočet binárního zápisu celého čísla. Vysvětlovat proč to funguje nedokážu jednoduchým způsobem, ale zkrátka násobíte číslo dvěma, do dalšího kroku přenášíte jenom zbytek za desetinnou čárkou a cifry před desetinnou čárkou z jednotlivých kroků tvoří postupně binární zápis.

Mike: Ta periodicita je tam z trochu jiného důvodu. Aby číslo nebylo periodické, musel by existovat zlomek, který se danému číslu rovná s mocninou dvojky ve jmenovateli a nějakým celým číslem v čitateli. Např. 0.375 je zapsatelné jako 3/8, takže nebude periodické. Číslo 0.1 je ale rovno 1/10, což je 1/(2x5). Je to zlomek v základním tvaru, nelze jej nijak dál zjednodušit, a ať ho rozšíříš čímkoli, nedostaneš mocninu dvojky ve jmenovateli. Tím pádem takový zlomek neexistuje a musíš to zapsat periodicky.
Ale třeba v soustavě o základu 110 to lze provést, rozšíříš jej 11 a máš 11/110, 110 je mocnina 110 (první), takže v pohodě. Proto jsou 1/3,1/6,1/7 atd. všechno periodická čísla v desítkové soustavě, protože to nelze rozšířit, abychom dostali mocninu 10.

52

Odpovědět

Upřímně nechápu ty, kteří na normální zvídavou otázku kliknou palec dolů...

252

Odpovědět

První!!!! xDDDDD :DDDD :P ;) :DDDD x'DDDD

1348

Odpovědět

A určitě nejsi 1,000000001-tý? :D

895