Pevná řádová čárka
Používání pevné řádové čárky je ve výpočetní technice jeden ze způsobů, jak reprezentovat a zpracovávat čísla, která nejsou celá; zatímco při práci s celými čísly se pracuje pouze s číslicemi vlevo od řádové čárky a při práci s čísly s pohyblivou řádovou čárkou se uchovává určitý počet nejvýznamnějších číslic a informace o řádu první číslice, u čísel s pevnou řádovou čárkou se pracuje s určitým pevným počtem číslic (obvykle desítkových nebo dvojkových) za řádovou čárkou.
Potřeba práce s čísly s pevnou řádovou čárkou často vychází z finančnictví, kde se pracuje s částkami zaokrouhlenými na určitý zlomek měnové jednotky (typicky 1/100 koruny, dolaru, apod.) podle přesně daných pravidel.
Další příčinou používání čísel s pevnou řádovou čárkou byla velká výpočetní nebo obvodová náročnost práce s čísly s pohyblivou řádovou čárkou. V případě 16bitových mikroprocesorů byla rychlost provádění operací s celými čísly o jeden a dva řády vyšší než s čísly s pohyblivou řádovou čárkou při hardwarové realizaci (FPU) a až o tři řády vyšší při softwarové realizaci (numerické knihovny).
Obecněji lze reprezentaci s pevnou řádovou čárkou popsat jako metodu práce s čísly, která jsou vyjádřena jako celočíselné množství určité pevné malé jednotky. Opačným způsobem se pevná řádová čárka používá ve finančních výkazech, kde se částky uvádějí v celočíselných počtech násobků základní jednotky (např. tisíců Kč).
Při reprezentaci s pevnou řádovou čárkou je zlomková část často vyjádřena ve stejné číselné soustavě jako celočíselná část, ale pomocí záporné mocniny o základu b. Nejčastěji se používá desítková soustava (základ 10) nebo dvojková soustava (základ 2). Druhý případ se obvykle nazývá binární škálování. Pokud se tedy ukládá n číslic za řádovou čárkou, hodnota bude vždy celočíselným násobkem nějaké záporné mocniny n základu b, tj. celočíselným násobkem hodnoty b−n. Reprezentace s pevnou řádovou čárkou může také být použita pro zanedbání nejméně významných číslic celočíselné hodnoty, například při reprezentaci velkých částek v určité měně jako násobků 1000.
Při používání čísel s pevnou řádovou čárkou je časté používání desítkové soustavy a kódování BCD.
V češtině a dalších středoevropských jazycích se při zobrazování čísel s pevnou řádovou čárkou používá jako oddělovač celé a zlomkové části znak čárka, v anglosaské oblasti je obvyklejší tečka. Ve vnitřní reprezentaci však žádný oddělovač není.
Reprezentace s pevnou řádovou čárkou byla standardem v dobách používání mechanických kalkulátorů, na které navázaly děrnoštítkové stroje. Ještě mnohé sálové počítače měly strojové instrukce pro práci s čísly v pevné řádové čárce, u mikroprocesorů je podpora omezena na instrukce provádějící BCD korekce. Většina moderních procesorů má rychlou jednotku pro výpočty v pohyblivé řádové čárce (FPU), a reprezentaci s pevnou řádovou čárkou používají pouze ve speciálních situacích, např. v laciných vestavěných mikroprocesorech a mikrořadičích; v aplikacích, které vyžadují vysokou rychlost a/nebo nízkou výkonovou spotřebu nebo malou plochu čipu, jako při digitálním zpracování signálu, digitálním zpracování obrazu a digitálním zpracování videa, nebo když je použití čísel s pevnou řádovou čárkou přirozenější pro daný problém, např. v účetnictví, kdy se zlomky centů musí zaokrouhlovat na celé centy striktně předepsaným způsobem a funkce se vyhodnocují pomocí vyhledávacích tabulek.
Reprezentace
[editovat | editovat zdroj]Reprezentovaná hodnota |
Interní reprezentace |
---|---|
0,00 | 0 |
0,5 | 50 |
0,99 | 99 |
2 | 200 |
−14,1 | −1410 |
314,160 | 31416 |
Pro reprezentaci racionálního čísla s pevnou řádovou čárkou je v zásadě celé číslo, které je implicitně znásobené pevným měřítkem. Například hodnotu 1,23 lze reprezentovat jako celé číslo 1230 s implicitním měřítkem 1/1000 (s tím, že o posledních třech desítkových číslicích se implicitně předpokládá, že jde o desetinná místa); naopak hodnotu 1 230 000 lze reprezentovat jako 1230 s implicitním měřítkem 1000 (s minus třemi implicitními desítkovými číslicemi, což znamená, že desetinná čárka je o 3 řády vpravo). Tato reprezentace umožňuje, aby standardní celočíselná aritmeticko-logická jednotka prováděla výpočty s racionálními čísly.
Záporná čísla se v binárním formátu s pevnou řádovou čárkou obvykle reprezentují jako celé číslo se znaménkem ve formě dvojkového doplňku s implicitním měřítkem jak je popsáno výše. Znaménko hodnoty bude vždy indikováno prvním uloženým bitem (1 = záporné číslo, 0 = nezáporné číslo) i když počet zlomkových bitů je větší nebo roven celkovému počtu bitů. Například osmibitové dvojkové celé číslo se znaménkem (11110101)2 = −11, reprezentované s -3, +5 resp. +12 implicitními zlomkovými bity reprezentuje postupně hodnoty −11/2−3 = −88, −11/25 = −0,343 75, a −11/212 = −0,002 685 546 875.
Alternativně lze záporné hodnoty reprezentovat celým číslem s použitím dvojkového doplňku; v tomto případě znaménko nikdy není obsaženo v implicitních zlomkových bitech. Tato varianta se častěji používá v desítkové aritmetice s pevnou řádovou čárkou. Tedy pětimístné desítkové celé číslo se znaménkem (−00025)10 postupně s -3, +5, a +12 implicitními desetinnými číslicemi, reprezentuje hodnoty −25/10−3 = −25000, −25/105 = −0,00025 a −25/1012 = −0,000 000 000 025.
Programy obvykle předpokládají, že všechny hodnoty s pevnou řádovou čárkou, které se budou ukládat do dané proměnné, nebo které budou vytvořeny danou instrukcí, budou mít stejné měřítko. Měřítko obvykle může být zvoleno programátorem podle požadované přesnosti a rozsahu hodnot, které mají být uchovávány.
Měřítko proměnné nebo (mezi)výpočtu se v programu nemusí explicitně objevit. Je však dobrou programátorskou praxí je uvést v dokumentaci, alespoň ve formě komentáře ve zdrojovém kódu.
Volba měřítka
[editovat | editovat zdroj]Pro větší efektivitu se za měřítka často volí (kladné nebo záporné) mocniny základu b použitého v interní reprezentaci celých čísel. Často však je měřítko vynucené aplikací; Často se tedy používají měřítka, která jsou mocninou 10 (například 1/100 pro peněžní částky), dokonce i tehdy, když jsou celá čísla reprezentována interně ve dvojkové soustavě. Desítkové měřítko také vychází z použití Mezinárodní soustavy jednotek SI, protože volba měřítka při použití pevné řádové čárky je často ekvivalentní s volbou jednotky míry (např. centimetrů nebo mikrometrů místo metrů).
Příležitostně se však mohou používat jiná měřítka; například zlomky hodin mohou být reprezentovány celočíselným počtem sekund, tj. číslem s pevnou řádovou čárkou s měřítkem 1/3600.
I při sebepečlivějším zaokrouhlování může mít hodnota uloženého celého číslo s pevnou řádovou čárkou v reprezentaci s měřítkem S chybu až ±0,5, což odpovídá chybě hodnoty ±0,5.S. Proto použití menšího měřítka obecně dává přesnější výsledky.
Menší měřítko však znamená menší rozsah hodnot, které lze do dané proměnné uložit. Maximální hodnota reprezentovatelná určitou proměnnou s pevnou řádovou čárkou je rovna největší celočíselné hodnotě, kterou lze do proměnné uložit, znásobená měřítkem; stejně je tomu s minimální hodnotou. Následující tabulka ukazuje, jak závisí minimální a maximální reprezentovatelná hodnota Vmin a Vmax a přesnost δ = S/2 na počtu f implicitních zlomkových bitů, který udává implicitní měřítko S, při použití 16bitového dvojkového čísla se znaménkem pro reprezentaci s pevnou řádovou čárkou.
f | S | δ | Vmin | Vmax |
---|---|---|---|---|
−3 | 1/2−3 = 8 | 4 | −262 144 | +262 143 |
0 | 1/20 = 1 | 0,5 | −32 768 | +32 767 |
5 | 1/25 = 1/32 | < 0,016 | −1024,000 00 | +1023,968 75 |
14 | 1/214 = 1/16 384 | < 0,000 031 | −2,000 000 000 000 00 | +1,999 938 964 843 75 |
15 | 1/215 = 1/32 768 | < 0,000 016 | −1,000 000 000 000 000 | +0,999 969 482 421 875 |
16 | 1/216 = 1/65 536 | < 0,000 008 | 000 000 000 000 0 | +0,499 984 741 210 937 5 |
20 | 1/220 = 1/1 048 576 | < 0,000 000 5 | −0,031 250 000 000 000 000 00 | +0,031 249 046 325 683 593 75 |
Formáty s pevnou řádovou čárkou s měřítkem tvaru 2n-1 (pro n = 1, 3, 7, 15, 31, atd.) jsou vhodné pro zpracování obrazu a jiné úlohy při digitálním zpracování signálu. Předpokládá se, že poskytují konzistentnější konverze mezi hodnotami s pevnou a pohyblivou řádovou čárkou než použití obvyklého měřítka 2n. Programovací jazyk Julia implementuje obě verze.[1]
Přesné hodnoty
[editovat | editovat zdroj]Jakýkoli binární zlomek a/2m, např. 1/16 nebo 17/32, lze číslem s pevnou řádovou čárkou s mocninou měřítka 1/2n s jakýkoli n ≥ m reprezentovat přesně. V soustavě o základu 2 má však většina desítkových zlomků, jako 0,1 nebo 0,123, vyjádření s nekonečným periodickým rozvojem, a tímto způsobem tedy být přesně reprezentovány nemohou.
Obdobně jakýkoli desítkový zlomek a/10m, např. 1/100 nebo 37/1000, lze přesně reprezentovat číslem s pevnou řádovou čárkou s mocninou měřítka 1/10n s jakýkoli n ≥ m. Tímto desítkovým formátem lze reprezentovat jakýkoli dvojkový zlomek a/2m, např. 1/8 (0,125) nebo 17/32 (0,53125).
Obecněji, Racionální číslo a/b, s a a b nesoudělnými a b kladným, lze přesně reprezentovat dvojkovým číslem s pevnou řádovou čárkou pouze tehdy, pokud b je mocninou čísla 2; desítkovým číslem s pevnou řádovou čárkou pak pouze tehdy, pokud b nemá žádné prvočíselné dělitele kromě 2 a 5.
Porovnání zpracování s pohyblivou řádovou čárkou
[editovat | editovat zdroj]Výpočty s pevnou řádovou čárkou mohou být rychlejší a mohou vyžadovat jednodušší hardware než výpočty s pohyblivou řádovou čárkou. Pokud je rozsah hodnot, které mají být reprezentovány, znám předem a je dostatečně omezený, může použití čísel s pevnou řádovou čárkou zlepšit využití dostupných bitů. Pokud je například pro reprezentaci čísel mezi 0 a 1 dostupných 32 bitů, může mít reprezentace s pevnou řádovou čárkou chybu menší než 1,2 × 10−10, zatímco standardní reprezentace s pohyblivou řádovou čárkou může mít chybu až 596 × 10−10 – protože 9 bitů je zbytečně použito pro znaménko čísla a exponent. Pokud konkrétně, porovnáme použití 32bitových hodnot s pevnou řádovou čárkou s použitím pohyblivé řádové čárky pro audio data, bude mít záznam vyžadující rezervu dynamického rozsahu (headroom) menší než 40 dB bude mít při použití 32bitových čísel s pevnou řádovou čárkou větší odstup signálu od šumu.
Programy provádějící výpočty s pevnou řádovou čárkou jsou obvykle lépe přenositelné než programy, které používají pohyblivou řádovou čárku, protože nevyžadují přítomnost FPU. Tato výhoda byl obzvláště významná před rozšířením standardu IEEE 754, kdy výpočty v pohyblivé řádové čárce se stejnými daty dávaly na počítačích různých výrobců (nebo i různých modelech počítačů téhož výrobce) různé výsledky.
Mnoho vestavěných procesorů nemá FPU, protože celočíselná aritmetická jednotka vyžaduje podstatně méně logických členů a zabírá mnohem menší plochu čipu než FPU; softwarová emulace aritmetiky s pohyblivou řádovou čárkou na pomalém zařízení by pro většinu aplikací byla příliš pomalá. Starší mikroprocesory, jako Intel 80386 a 486SX, používané v osobních počítačích a herních konzolách také neobsahovaly FPU.
Absolutní rozlišení (rozdíl mezi následujícími hodnotami) jakéhokoli formátu s pevnou řádovou čárkou je v celém rozsahu konstantní, a je rovno hodnotě měřítka S. Naproti u formátu s pohyblivou řádovou čárkou je relativní rozlišení přibližně konstantní v celém rozsahu, proměnné podle faktoru o základu b; naproti tomu absolutní rozlišení se mění o mnoho řádů, jako hodnoty samy.
V mnoha případech lze chyby výpočtů s pevnou řádovou čárkou způsobené zaokrouhlováním a zkracováním analyzovat snáze než ekvivalentní výpočty s pohyblivou řádovou čárkou. Použití linearizačních technik na zkracování, např. ditheringu nebo tvarování šumu je v aritmetice s pevnou řádovou čárkou jednodušší. Použití pevné řádové čárky však vyžaduje od programátora větší péči: Aby nedocházelo k přetečení, musejí být odhady rozsahů proměnných a všech mezihodnot při výpočtu mnohem přesnější, a často je také potřeba zvláštní kód pro určení jejich měřítka. Programování s pevnou řádovou čárkou obvykle vyžaduje použití celočíselných typů různých velikostí.
Pokud je k dispozici aritmetika s pevnou řádovou čárkou, je možné se výpočtům, které vyžadují pohyblivou řádovou čárku, přiblížit použitím blokové plovoucí řádové čárky, což je přístup, při kterém se určitý rozsah reálných čísel mapuje na čísla s pevnou řádovou čárkou a s určitým exponentem.
Aplikace
[editovat | editovat zdroj]Používání desítkových čísel s pevnou řádovou čárkou je běžné pro ukládáním peněžních hodnot, pro které je třeba dodržovat závazná pravidla zaokrouhlování čísel s pohyblivou řádovou čárkou. Například aplikace GnuCash s otevřeným zdrojovým textem pro peníze správa/řízení, napsaný v jazyce C od verze 1.6 přešla z tohoto důvodu z používání pohyblivé řádové čárky na výpočty s pevnou řádovou čárkou.
Dvojková čísla s pevnou řádovou čárkou (s binárním měřítkem) se často používala od konce 60. let do 80. let 20. století pro matematicky intenzivní výpočty v reálném čase, např. pro letecké simulátory a pro algoritmy řízení jaderných elektráren. Dosud se používají v mnoha aplikacích pro digitální zpracování signálu (DSP) a v zákaznických mikroprocesorech. Výpočty obsahující úhly mohou používat binary angular measurement (BAM).
Dvojková čísla s pevnou řádovou čárkou se používají v řadě STM32G4 koprocesorů CORDIC a v algoritmech diskrétní kosinová transformace (DCT) používaných pro kompresi obrázků JPEG.
Elektronické přístroje jako elektroměry nebo digitální hodiny často pro kompenzaci chyb způsobených změnami teploty nebo změnou napájecího napětí používají polynomy, jejichž koeficienty se získávají polynomickou regresí. Pro rychlé výpočty na poměrně levných procesorech lze používat polynomy s dvojkovými čísly s pevnou řádovou čárkou, která mají větší přesnost než čísla s pohyblivou řádovou čárkou. Přesnost, která je pro přístroje klíčová, je srovnatelná s ekvivalentními výpočty s pohyblivou řádovou čárkou, pokud jsou polynomy s pevnou řádovou čárkou faktorizovány (například y = d + x(c + x(b + xa))) pro omezení počtu zaokrouhlování, a pokud násobení s pevnou řádovou čárkou využívá zaokrouhlovací sčítance.
Operace
[editovat | editovat zdroj]Sčítání a odčítání
[editovat | editovat zdroj]Pro sečtení nebo odečtení dvou hodnot se stejným implicitním měřítkem stačí sečíst nebo odečíst podkladová celá čísla; výsledek bude mít stejné implicitní měřítko, může tedy lze uložit v stejný program proměnné jako operandy. Tyto operace dává přesný matematický výsledek, pokud nedojde k přetečení – tj. pokud výsledné celé číslo lze uložit v cílové proměnné. Pokud hodnoty mají různá měřítka, pak musí být před provedením operace zkonvertovány na společné měřítko.
Násobení
[editovat | editovat zdroj]Pro znásobení dvou čísel s pevnou řádovou čárkou stačí znásobit obě podkladová celá čísla, a jako měřítko výsledku použít součin měřítek obou činitelů. Za předpokladu, že, Výsledek bude přesný, bez zaokrouhlování, nedojde k nepřetečení cílové proměnná.
Například násobení čísla 123 s měřítkem 1/1000 (0,123) a 25 s měřítkem 1/10 (2,5) dává celé číslo 123×25 = 3075 s měřítkem (1/1000)×(1/10) = 1/10000, což je 3075/10000 = 0,3075. Jako jiný příklad, násobení první číslo by 155 implicitně s měřítkem 1/32 (155/32 = 4,84375) dává celé číslo 123×155 = 19065 s implicitním měřítkem (1/1000)×(1/32) = 1/32000, což je 19065/32000 = 0,59578125.
Při reprezentaci čísel ve dvojkové soustavě je běžné používat měřítko, které je mocninou čísla dvě. Po násobení lze provést úpravu měřítka pomocí bitového posuvu vpravo. Tento proces je na většině počítačů jednoduchý a rychlý. Zaokrouhlování je možné provést přičtením 'zaokrouhlovacího sčítance', což je polovina měřítka před posuvem; Důkaz: round(x/y) = floor(x/y + 0,5) = floor((x + y/2)/y) = shift-of-n(x + 2^(n-1)) Podobná metoda je použitelná s jakýmkoli měřítkem.
Dělení
[editovat | editovat zdroj]Pro vydělení dvou čísel s pevnou řádovou čárkou se provede celočíselný podíl jejich podkladových celých čísel a předpokládáme, že měřítko je podíl jejich měřítek. První dělení obecně vyžaduje zaokrouhlování, a proto výsledek není přesný.
Například dělení čísla 3456 s měřítkem 1/100 (34,56) a 1234 s měřítkem 1/1000 (1,234) dává celé číslo 3456÷1234 = 3 (zaokrouhlený) s měřítkem (1/100)/(1/1000) = 10, což je 30. Další příklad: dělení prvního čísla číslem 155 s implicitním měřítkem 1/32 (155/32 = 4,84375) dává celé číslo 3456÷155 = 22 (zaokrouhleno) s implicitním měřítkem (1/100)/(1/32) = 32/100 = 8/25, což je 22×32/100 = 7,04.
Pokud výsledek není přesný, chyby způsobené zaokrouhlováním lze zmenšit nebo dokonce odstranit konvertováním dělitele na menší měřítko. Pokud je například hodnota r = 1,23 reprezentována jako 123 s měřítkem 1/100, a s = 6,25 jako 6250 s měřítkem 1/1000, pak jednoduché dělení celých čísel dává 123÷6250 = 0 (zaokrouhleně) s měřítkem (1/100)/(1/1000) = 10. Pokud r je nejprve zkonvertujeme na 1,230,000 s měřítkem 1/1000000, výsledek bude 1,230,000÷6250 = 197 (zaokrouhlený) s měřítkem 1/1000 (0,197). Přesná hodnota 1,23/6,25 je 0,1968.
Změna měřítka
[editovat | editovat zdroj]Při výpočtech s pevnou řádovou čárkou je často třeba zkonvertovat hodnotu na jiné měřítko. Tato operace je nezbytná například:
- Pro uložení hodnoty do proměnné, která má jiné implicitní měřítko;
- Pro zkonvertování dvou hodnot na stejné měřítko, aby mohly být sečteny nebo odečteny;
- Pro obnovení původního měřítka hodnoty po násobení nebo dělení;
- Pro zlepšení přesnosti výsledku dělení;
- Pro zajištění, že měřítko součinu nebo podílu je mocninou čísla 10n nebo 2n;
- Pro zajištění, že výsledek operace lze uložit do proměnné bez přetečení;
- Pro omezení ceny hardwaru, který zpracovává data s pevnou řádovou čárkou.
Pro zkonvertování daného čísla s pevnou řádovou čárkou s měřítkem R na jiný typ s měřítkem S je třeba podkladové celé číslo znásobit poměrem R/S. Tedy, například pro zkonvertování hodnota 1,23 = 123/100 z měřítko R=1/100 na jeden s měřítkem S=1/1000, celé číslo 123 musí být znásobeno číslem (1/100)/(1/1000) = 10, což dává reprezentaci 1230/1000.
Pokud měřítko je mocninou základu používaného interně pro reprezentaci celých čísel, změna měřítka vyžaduje pouze zanedbání nejméně významný číslic celého čísla nebo připojení nulových číslic. Tato operace však musí zachovávat znaménko čísla. V reprezentaci ve dvojkovém doplňku, to znamená rozšiřování znaménkového bitu jako při operaci aritmetického posunu.
Pokud S nedělí R (konkrétně pokud nové měřítko S je větší než původní R), bude třeba vniklé celé číslo zaokrouhlit.
Pokud konkrétně r a s jsou proměnné s pevnou řádovou čárkou s implicitní měřítka R a S, operace r ← r×s vyžaduje násobení příslušnou celá čísla a explicitně vydělit výsledek hodnotou S. Výsledek bude muset být zaokrouhlen, a může dojít k přetečení.
Pokud například běžné měřítko je 1/100, při násobení 1,23 a 0,25 se násobí 123 a 25, což je 3075 a střední měřítko je 1/10000. Pro návrat k původnímu měřítku 1/100 musí být celé číslo 3075 znásobeno hodnotou 1/100, tedy po vydělení 100 je výsledek buď 31 (0,31) anebo 30 (0,30), podle použité zaokrouhlovací strategie.
Podobně operace r ← r/s bude vyžadovat provedení celočíselného dělení následovaného explicitním znásobením podílu hodnotou S. Často může dojít k zaokrouhlení nebo přetečení.
Konverze mezi formátem s pohyblivou řádovou čárkou a jiným formátem
[editovat | editovat zdroj]Pro zkonvertování čísla s pohyblivou řádovou čárkou na číslo s pevnou řádovou čárkou je třeba jej znásobit měřítkem S a výsledek zaokrouhlit na nejbližší celé číslo. Je třeba dát pozor, aby se výsledek vešel do cílové proměnné nebo registru. V závislosti na měřítku a velikosti úložného prostoru, a na rozsahu vstupního čísla, nemusí být potřeba provádět zaokrouhlování.
Pro zkonvertování čísla s pevnou řádovou čárkou na číslo s pohyblivou řádovou čárkou stačí zkonvertovat celé číslo do formátu s pohyblivou řádovou čárkou a výsledek vydělit měřítkem S. Tato konverze může mít za následek zaokrouhlení, pokud absolutní hodnota celého čísla je větší než 224 (pro binární IEEE čísla s pohyblivou řádovou čárkou s jednoduchou přesností) nebo 253 (pro čísla s dvojitou přesností). Může dojít k přetečení nebo podtečení, pokud |S| je velmi velká, příp. velmi malá.
Hardwarová podpora
[editovat | editovat zdroj]Zvětšení a renormalizace
[editovat | editovat zdroj]Typické procesory nemají podporu pro aritmetiku s pevnou řádovou čárkou. Většina počítačů s binární aritmetikou má však rychlé instrukce pro bitové operace, které umožňují znásobit nebo vydělit celé číslo jakoukoli mocninou dvojky; konkrétně jde o instrukce aritmetického posunu. Tyto instrukce lze použít pro rychlou změnu měřítka, které je mocninou dvojky, se zachováním znaménka čísla.
Nejstarší počítače jako IBM 1620 a Burroughs B3500 používaly pro celá čísla BCD reprezentaci, jmenovitě základu 10 kde každá desítková číslice byla nezávisle zakódována do čtyř bitů. Některé procesory, např. mikrořadiče, mohou tento formát stále používat. V takových strojích lze konverzi desítkového měřítka provést pomocí bitových posunů nebo změnou adresy.
Některé DSP architektury poskytovat nativní podporu určitých formátů s pevnou řádovou čárkou, například n-bitová čísla se znaménkem s n−1 zlomkovými bity (jejíž hodnoty mohou nabývat rozsah mezi −1 a téměř +1). Podpora může zahrnovat instrukci násobení, která provádí renormalizaci – konverzi měřítka součinu z 2n−2 na n−1 zlomkových bitů.[zdroj?] Pokud CPU tuto funkcionalitu neposkytuje, programátor musí uložit součin do dostatečně velkého registru nebo dočasné proměnné, a použít kód pro explicitní renormalizaci.
Přetečení
[editovat | editovat zdroj]Pokud je se výsledek aritmetické operace nevejde do cílové proměnné, dojde k přetečení. Při sčítání a odčítání může výsledek vyžadovat o jeden bit více než operandy. Při násobení dvou celých čísel bez znaménka s m a n bity může mít výsledek m+n bitů.
Při přetečení dojde ke ztrátě bitů nejvyšších řádů, protože un-scaled celé číslo bude oříznuto modulo 2n, kde n je velikost proměnné. Může tak dojít ke ztrátě znaménkového bitu, což může způsobit změnu znaménka a výrazně změnit řád hodnoty.
Některé procesory mohou nastavit hardwarový příznak přetečení a/nebo generovat výjimku, když dojde k přetečení. Některé procesory mohou místo toho poskytovat saturační aritmetiku: pokud by sčítání nebo odčítání způsobilo přetečení, dosadí maximální hodnotu pro daný cílový typ se správným znaménkem.[zdroj?]
Tyto vlastnosti však v praxi nejsou příliš užitečné; obecně je snazší a bezpečnější vybírat měřítko a velikost slova, aby nemohlo dojít k přetečení a kontrolovat operandy, zda nemají příliš velké hodnoty před provedením operace.
Podpora v programovacích jazycích
[editovat | editovat zdroj]Explicitní podporu čísel s pevnou řádovou čárkou má málo počítačových jazyků, především PL/I, COBOL, Ada, JOVIAL, a Coral 66. Poskytují datové typy s pevnou řádovou čárkou, s binárním nebo desítkovým měřítkem. Překladač automaticky generuje kód, který provádí vhodné konverze měřítka při provádění operací s těmito datovými typy, při čtení nebo ukládání proměnných nebo při konvertování hodnoty na jiné datové typy, např. používající pohyblivou řádovou čárku.
Většina těchto jazyků byla navržena mezi lety 1940 a 1990. Modernější jazyky obvykle datové typy s pevnou řádovou čárkou nebo podporu pro konverze měřítek neposkytují. To je také případ několika starších jazyků, které jsou stále velmi oblíbené, jako Fortran, C a C++. Dobrá dostupnost rychlých procesorů pracujících s čísly s pohyblivou řádovou čárkou se striktně standardizovaným chováním značně omezila poptávka po podpoře dvojkových čísel s pevnou řádovou čárkou.[zdroj?] Podobně podpora pro desítkových čísel s pohyblivou řádovou čárkou v některých programovacích jazycích, jako C# a Python, odstranila většinu potřeb desítkových čísel s podporou pevné řádové čárky. V řídkých situacích, které vyžadují operace s pevnou řádovou čárkou, mohou být tyto operace implementované programátorem, s explicitní konverzí měřítka, v jakémkoli programovacím jazyce.
Na druhou stranu, všechny relační databáze a SQL notace podporují desítkovou aritmetiku a ukládání čísel s pevnou řádovou čárkou. PostgreSQL má speciální numerický typ pro přesné ukládání čísel až s 1000 číslicemi.[2]
V roce 2008 Mezinárodní organizace pro normalizaci (ISO) vydala navíc návrh rozšiřující programovací jazyk C o datové typy s pevnou řádovou čárkou pro použití v programech běžících na vestavěných procesorech.[3] Také GNU Compiler Collection (GCC) má podporu back-endu pro výpočty s pevnou řádovou čárkou.[4][5]
Podrobné příklady
[editovat | editovat zdroj]Násobení desítkových čísel s pevnou řádovou čárkou
[editovat | editovat zdroj]Pokud se násobí dvě čísla s pevnou řádovou čárkou a třemi desítkovými číslicemi za řádovou čárkou:
Kvůli existenci 3 číslic za desetinnou čárkou jsou čísla psána s koncovými nulami. Pro vyjádření operace pomocí celočíselného násobení musíme oba operandy nejdříve znásobit číslem , díky čemuž budou desetinná místa vyjádřena celými čísly, a po provedení násobení výsledek vydělit :
Při použití jiného základu pro reprezentaci čísel (například 2) se postupuje podobně. protože bit posun je totéž jako násobení nebo dělení by řád 2. Tři desítkové číslice je ekvivalentní s asi 10 binárními číslicemi, takže musíme zaokrouhlit 0,05 na 10 bitů za dvojkovou řádovou čárkou. Nejbližší aproximace pak je 0,0000110011.
Tedy naši násobení se stane
Toto číslo zaokrouhlíme na 11,023 se třemi číslicemi po desetinné tečce.
Násobení dvojkových čísel s pevnou řádovou čárkou
[editovat | editovat zdroj]Uvažujme úloha výpočet součinu dvojkových čísel s pevnou řádovou čárkou 1,2 a 5,6 pomocí 16bitových zlomkových hodnot. Reprezentovat dva čísla, jeden násobí jim by 216, získání 78 643,2 a 367 001,6; a okrouhlý tyto hodnoty nejbližší celá čísla, získání 78 643 a 367 002. Tato čísla se pohodlně vejdou do 32bitového slova ve formátu dvojkového doplňku se znaménkem.
Násobení těchto celých čísel současně dává 35bitové celé číslo 28 862 138 286 s 32 zlomkovými bity, bez jakýkoli zaokrouhlování. Všimnout si, že ukládáním toto hodnota přímo do 32bitové celé číslo proměnná by vedou k přetečení a ztrátě nejvýznamnějších bitů. V praxi ono by pravděpodobně být uložený v se znaménkem 64bitové celé číslo proměnná nebo registr.
Pokud má být výsledek uložen ve stejném formát jako operandy, se 16 zlomkovými bity, musí být číslo vyděleno 216, což dává přibližně 440 401,28, a pak zaokrouhleno na nejbližší celé číslo. Toho lze dosáhnout přičtením 215 a pak posunout výsledek by 16 bitů. Výsledek je 440 401, který reprezentuje hodnota 6,719 985 961 914 062 5. Nabývající/beroucí v úvahu přesnost formátu, that hodnota je lepší vyjádřený jako 6,719 986 ± 0,000 008 (nepočítaje chyba that pochází z operand aproximace). Správný výsledek by bylo 1,2 × 5,6 = 6,72.
Pro složitější příklad, předpokládejme, že, že dva čísla 1,2 a 5,6 jsou reprezentována v 32bitové pevný řádovou čárkou formát s 30 příp. 20 zlomkovými bity. Zvětšení by 230 a 220 dává 1|288|490|188,8 a 5 872 025,6, které se zaokrouhlí na 1 288 490 189 resp. 5 872 026. Obě čísla se stále vejdou do 32bitové celočíselné proměnná se znaménkem, a reprezentují zlomky
- 1,200 000 000 186 264 514 923 095 703 125 a
- 5,600 000 381 469 726 562 50
Jejich součin je (přesně) 53bitové celé číslo 7 566 047 890 552 914, které má 30+20 = 50 implicitních zlomkových bitů a proto reprezentuje zlomek
- 6,720 000 458 806 753 229 623 609 513 510 018 587 112 426 757 812 50
Pokud se tato hodnota má reprezentovat pomocí 16bitového čísla s pevnou řádovou čárkou se znaménkem a 8 zlomkovými bity, musíme dělí celé číslo součin by 250-8 = 242 a okrouhlý výsledek; který lze dosáhnout přičtením 241 a posunem o 42 bitů. Výsledek je 1720, reprezentující hodnota 1720/28 = 6,718 75 nebo přibližně 6,719 ± 0,002.
Notace
[editovat | editovat zdroj]Pro přesné zadání formátu čísel s pevnou řádovou čárkou byly používány různé notace. V následujícím seznamu f reprezentuje počet bitů za řádovou čárkou, m počet bitů před řádovou čárkou, s počet znaménkových bitů, a b celkový počet bitů.
- Programovací jazyk COBOL podporuje desítková čísla libovolné délky s pevnou řádovou čárkou, jejichž formát se definuje „graficky“ pomocí direktivy
PIC
. NapříkladPIC S9999V99
specifikuje typ šesticiferných desítkových čísel se znaménkem a dvěma desetinnými místy.[6] - Zápis
REAL FIXED BINARY (
p,
f)
v programovacím jazyce PL/I definuje datový typ binárních čísel s pevnou řádovou čárkou a znaménkem celkem s p bity (bez znaménka) s f bity ve zlomkové části; to je celé číslo s p+1 bity se znaménkem a s měřítkem 1/2f. f může být kladné nebo záporné. MístoREAL
lze použítCOMPLEX
, a místoBINARY
lze použítDECIMAL
pro základ 10. - V programovacím jazyce Ada lze popsat numerický datový typ např. zápisem
type F is delta 0.01 range -100.0 .. 100.0
, který definuje typ binárních čísel se znaménkem s použitím dvojkového doplňku a pevnou řádovou čárkou se 7 implicitními zlomkovými bity (což dává měřítko 1/128) a alespoň 15 bity celkem (které zajišťují skutečný rozsah od -128.00 do téměř +128.00).[7] - Q notaci zavedla firma Texas Instruments.[8] Zápis
Qf
znamená hodnotu dvojkovým číslem s pevnou řádovou čárkou se znaménkem s f zlomkovými bity; napříkladQ15
je celé číslo se znaménkem ve dvojkovém doplňku s měřítkem 1/215. KódQ
m.
f navíc udává, že číslo má m bitů v celočíselné části, nepočítaje znaménkový bit.Q1.30
tedy vyjadřuje formát dvojkového čísla s pevnou řádovou čárkou s 1 celočíselným bitem a 30 zlomkovými bity, který může být uloženo jako 32bitové celé číslo s použitím dvojkového doplňku s měřítkem 1/230.[8][9] Podobná notace se používala u procesorů ARM, kde však byl znaménkový bit započítán v hodnotě m; tzn. že formát uvedený výše by se zapsalQ2.30
.[10][11] - Notace
B
m se používala pro formát binárních čísel s m bity v celočíselné části; zbytek slova je použit pro zlomkové bity. NapříkladB16
umožňuje reprezentovat hodnoty od −32768,0 do ≈32767,9999847. - Společnost VisSim používala zápis
fx
m.
b pro vyjádření hodnoty dvojkového čísla s pevnou řádovou čárkou s celkem b bity a m bity v celočíselné části; to jest, b-bitové celé číslo s měřítkem 1/2b−m. Tedyfx1.16
znamená 16bitové číslo s 1 bitem v celočíselné části a 15 ve zlomkové.[12] - Uživatelská příručka k PlayStation 2 GS ("Graphics Synthesizer") používá notaci s
:
m:
f, kde s udává přítomnost (0 nebo 1) znaménkového bitu.[13] Například0:5:3
reprezentuje bez znaménka 8bitové celé číslo s měřítkem 1/23. - Programovací jazyk LabVIEW používá pro zadání parametrů 'FXP' čísel s pevnou řádovou čárkou notaci
<
s,
b,
m>
. Složka s může být '+' pro čísla bez znaménka nebo '±' pro čísla se znaménkem (reprezentace pomocí dvojkového doplňku). Složka b je celkový počet bitů, m je počet bitů v celočíselné části.
Příklady softwarových aplikací
[editovat | editovat zdroj]- Oblíbený formát fontů TrueType používá 32bitová dvojková čísla s pevnou řádovou čárkou se znaménkem s 26 bity před desítkový pro některé numerický hodnoty v jeho instrukce.[14] Tento formát byl zvolen, protože poskytuje dostatečnou přesnost pro font hinting při rozumných nárocích na výpočetní výkon.[15]
- Všechny 3D grafický enginy na původní PlayStation firmy Sony, Saturn firmy Sega, Game Boy Advance firmy Nintendo (pouze 2D grafika), Nintendo DS (2D i 3D), Nintendo GameCube[16] a GP2X Wiz videoherní systémy, které nemají FPU, používaly aritmetiku s pevnou řádovou čárkou. Konzole PlayStation obsahovaly v transformačním koprocesoru hardwarovou podporu 16bitových čísel s pevnou řádovou čárkou s 12 bity za řádovou čárkou.
- Sázecí software TeX oblíbený mezi vědci a matematiky používá 32bitová dvojková čísla se znaménkem s pevnou řádovou čárkou s 16 zlomkovými bity pro všechny výpočty poloh. Hodnoty jsou interpretovány jako zlomky typografického bodu. Soubory TFM ([TeX font metric) používají 32bitová čísla se znaménkem a s pevnou řádovou čárkou, s 12 bity za řádovou čárkou.
- Softwarové knihovny Tremor, Toast a MPEG Audio Decoder (MAD) pro dekódování formátů Ogg Vorbis, GSM Full Rate a MP3 audio používají aritmetiku s pevnou řádovou čárkou, protože mnoho hardwarových zařízení pro dekódování audia nemá FPU.
- Bezztrátový formát pro kompresi zvuku WavPack používá aritmetiku s pevnou řádovou čárkou, aby použití různých knihoven pro práci s čísly s pohyblivou řádovou čárkou nevedlo k nežádoucím modifikacím akustických dat.[17]
- Knihovna Nest Labs Utilities library[18] poskytuje omezenou sadu maker a funkcí pro čísla pevnou řádovou čárkou vhodných pro práci s těmito čísly při vzorkování a hodnot ze senzorů a jejich ovládací výstupy.
- Specifikace OpenGL ES 1.x obsahuje profil s pevnou řádovou čárkou, protože jde o API zaměřené pro vestavěné systémy, který ne vždy mají FPU.
- Programy dc a bc pro výpočty s libovolnou přesností umí udržovat informaci o (uživatelem zadaném) pevném počtu číslic za řádovou čárkou.
- Program Fractint pracuje s čísly s pevnou řádovou čárkou, která mají dva bity před a 29 bitů za řádovou čárkou (Q2.29),[19] pro zrychlení kreslení na starých počítačích PC s procesory Intel 80386 nebo Intel 80486SX, které neměly aritmetický koprocesor.
- Hra Doom, poslední first-person shooter titul by Id Software používala pro veškeré výpočty s jinými než celými čísly reprezentaci 16.16 s pevnou řádovou čárkou, včetně mapového systému, geometrie, vykreslování, přesunů hráčů atd. Z důvodu kompatibility se tato reprezentace stále používá v moderních portovaných verzích hry Doom.
- čísla s pevnou řádovou čárkou se někdy používají pro ukládáním obrázků a video rámců manipulace s nimi. Procesory s jednotkami SIMD zaměřené na zpracování obrazu mohou obsahovat instrukce vhodné pro zpracovávání pakovaných dat s pevnou řádovou čárkou.
- Programovací jazyk Q# pro kvantové počítače Azure implementující kvantová logická hradla obsahuje standard numerickou knihovnu pro provádění aritmetiky s pevnou řádovou čárkou na registrech qubitů.[20]
Odkazy
[editovat | editovat zdroj]Reference
[editovat | editovat zdroj]V tomto článku byl použit překlad textu z článku Fixed-point arithmetic na anglické Wikipedii.
- ↑ Dokumentace programovacího jazyka Julia FixedPointNumbers balíček.
- ↑ PostgreSQL manual, section 8.1.2. Arbitrary Precision Numbers
- ↑ JTC1/SC22/WG14 (2008), status of TR 18037: Embedded C
- ↑ GCC wiki, Fixed-Point Arithmetic Support
- ↑ Using GCC, section 5.13 Fixed-Point Types
- ↑ IBM Corporation, „Numerical items“. Online dokumentační uzel, datum přístupu 2021-07-05.
- ↑ Dokumentace jazyka Ada 83: „Rationale, 5.3.2: Fixed Point Types“. datum přístupu 2021-07-05.
- ↑ a b TMS320C64x DSP Library Programmer's Reference. [s.l.]: Texas Instruments, October 2003. Dostupné v archivu pořízeném z originálu dne 2022-12-22. SPRU565. Kapitola Appendix A.2.
- ↑ MathWorks Fixed-Point Toolbox Documentation Glossary [online]. mathworks.com [cit. 2023-02-08]. Dostupné v archivu pořízeném dne 2011-03-16.
- ↑ ARM Developer Suite AXD and armsd Debuggers Guide [online]. ARM Holdings, 2001. Dostupné v archivu pořízeném z originálu dne 2017-11-04. ARM DUI 0066D.
- ↑ RealView Development Suite AXD and armsd Debuggers Guide. [s.l.]: ARM Holdings, 2006. Dostupné v archivu pořízeném z originálu dne 2017-11-04. ARM DUI 0066G. Kapitola Chapter 4.7.9. AXD > AXD Facilities > Data formatting > Q-format, s. 4–24.
- ↑ VisSim is now solidThinking Embed [online]. solidThinking Inc.. Dostupné online.
- ↑ PS2 GS User's Guide, Chapter 7.1 "Explanatory Notes
- ↑ The TrueType Instruction Set: Data types [online]. Dostupné online.
- ↑ [Freetype] Why 26.6 ? [online]. Dostupné online.
- ↑ Dolphin Emulator [online]. Dolphin Emulator, 2014-03-15. Dostupné online.
- ↑ WavPack Technical Description [online]. www.wavpack.com [cit. 2015-07-13]. Dostupné online.
- ↑ Nest Labs Utilities library
- ↑ Fractint, A Little Code [online]. [cit. 2005-10-24]. Dostupné v archivu pořízeném z originálu dne 2010-10-27.
- ↑ Introduction to the Quantum Numerics Library [online]. [cit. 2019-11-13]. Dostupné online.
Literatura
[editovat | editovat zdroj]- WARREN, JR., Henry S. Hacker's Delight. 2. vyd. [s.l.]: Addison-Wesley/Pearson Education, Inc., 2013. ISBN 978-0-321-84268-8.
Související články
[editovat | editovat zdroj]- Q (formát čísel)
- Libfixmath – knihovna pro výpočty s pevnou řádovou čárkou pro jazyk C
- Pohyblivá řádová čárka
- Logaritmická číselná soustava
- Minifloat
- Modulo
Externí odkazy
[editovat | editovat zdroj]- Simple Fixed-Point Math Jednoduché výpočty s pevnou řádovou čárkou
- Fixed-Point Arithmetic - An Introduction Úvod do výpočtů s pevnou řádovou čárkou
- Fixed Point Representation and Fractional Math Archivováno 4. 11. 2017 na Wayback Machine. Reprezentace s pevnou řádovou čárkou a zlomková matematika
- A Calculated Look at Fixed-Point Arithmetic, (PDF)