Programování

Aritmetika s plovoucí desetinnou čárkou

Vítejte v další splátce Under The Hood. Tento sloupec si klade za cíl poskytnout vývojářům jazyka Java letmý pohled na skrytou krásu pod jejich spuštěnými programy Java. Sloupec z tohoto měsíce pokračuje v diskusi, zahájené minulý měsíc, o instrukční sadě bajtkódů virtuálního stroje Java (JVM). Tento článek pojednává o aritmetice s plovoucí desetinnou čárkou v JVM a popisuje bajtové kódy, které provádějí aritmetické operace s plovoucí desetinnou čárkou. Následující články pojednávají o dalších členech rodiny bytových kódů.

Hlavní plovoucí body

Podpora JVM s plovoucí desetinnou čárkou dodržuje standard IEEE-754 1985 s plovoucí desetinnou čárkou. Tato norma definuje formát 32bitových a 64bitových čísel s plovoucí desetinnou čárkou a definuje operace s těmito čísly. V JVM se aritmetika s plovoucí desetinnou čárkou provádí na 32bitových plovácích a 64bitových dvojcích. Pro každý bytecode, který provádí aritmetiku na plovácích, existuje odpovídající bytecode, který provádí stejnou operaci na čtyřhře.

Číslo s plovoucí desetinnou čárkou má čtyři části - znaménko, mantisu, radix a exponent. Znaménko je buď 1 nebo -1. Mantisa, vždy kladné číslo, obsahuje významné číslice čísla s plovoucí desetinnou čárkou. Exponent vyjadřuje kladnou nebo zápornou sílu radixu, kterou by mantisa a znaménko měly být vynásobeny. K získání hodnoty s plovoucí desetinnou čárkou jsou čtyři komponenty kombinovány následujícím způsobem:

znaménko * mantisa * exponent radixu

Čísla s plovoucí desetinnou čárkou mají více reprezentací, protože lze vždy vynásobit mantisu jakéhokoli čísla s plovoucí desetinnou čárkou nějakou mocninou radixu a změnit exponenta, aby získal původní číslo. Například číslo -5 může být zastoupeno stejně jakoukoli z následujících forem v radix 10:

Formy -5
PodepsatMantissaExponent Radix
-15010 -1
-1510 0
-10.510 1
-10.0510 2

Pro každé číslo s plovoucí desetinnou čárkou existuje jedna reprezentace, o které se říká, že je normalizováno. Číslo s plovoucí desetinnou čárkou je normalizováno, pokud je jeho mantisa v rozsahu definovaném následujícím vztahem:

1 / radix <= mantisa <

Normalizované číslo s plovoucí desetinnou čárkou Radix 10 má desetinnou čárku hned nalevo od první nenulové číslice v mantisě. Normalizovaná reprezentace s plovoucí desetinnou čárkou -5 je -1 * 0,5 * 10 1. Jinými slovy, mantisa normalizovaného čísla s plovoucí desetinnou čárkou nemá nenulové číslice nalevo od desetinné čárky a nenulovou číslici jen k vpravo od desetinné čárky. Říká se, že každé číslo s plovoucí desetinnou čárkou, které se do této kategorie nehodí denormalizováno. Všimněte si, že číslo nula nemá normalizovanou reprezentaci, protože nemá nenulovou číslici, která by se dala napravo od desetinné čárky. „Proč se normalizovat?“ je běžný výkřik mezi nulami.

Čísla s plovoucí desetinnou čárkou v JVM používají radix dvou. Čísla s plovoucí desetinnou čárkou v JVM mají tedy následující podobu:

znaménko * mantisa * 2 exponent

Mantisa čísla s plovoucí desetinnou čárkou v JVM je vyjádřena jako binární číslo. Normalizovaná mantisa má svůj binární bod (ekvivalent dvou desetinných teček základny) hned nalevo od nejvýznamnější nenulové číslice. Protože binární číselný systém má jen dvě číslice - nulu a jednu - nejvýznamnější číslice normalizované mantisy je vždy jedna.

Nejvýznamnějším bitem float nebo double je bit znaménka. Mantisa zabírá 23 nejméně významných bitů floatu a 52 nejméně významných bitů double. Exponent, 8 bitů v plováku a 11 bitů v double, sedí mezi znaménkem a mantisou. Formát plováku je uveden níže. Znakový bit je zobrazen jako „s“, bity exponentů jsou zobrazeny jako „e“ a bity mantisy jsou zobrazeny jako „m“:

Bitové rozložení Java float
s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmmmm

Znakový bit nula označuje kladné číslo a bit znaménka jedna označuje záporné číslo. Mantisa je vždy interpretována jako kladné číslo dvě základny. Není to číslo s dvojitým doplňkem. Pokud je bit znaménka jedna, je hodnota s plovoucí desetinnou čárkou záporná, ale mantisa je stále interpretována jako kladné číslo, které musí být vynásobeno -1.

Pole exponentu je interpretováno jedním ze tří způsobů. Exponent všech označuje, že číslo s plovoucí desetinnou čárkou má jednu ze speciálních hodnot plus nebo minus nekonečna, nebo „není číslo“ (NaN). NaN je výsledkem určitých operací, například dělení nuly na nulu. Exponent všech nul označuje denormalizované číslo s plovoucí desetinnou čárkou. Jakýkoli jiný exponent označuje normalizované číslo s plovoucí desetinnou čárkou.

Mantisa obsahuje jeden kousek přesnosti nad rámec těch, které se objevují v mantisových bitech. Mantisa plováku, který zabírá pouze 23 bitů, má přesnost 24 bitů. Mantisa dvojníka, který zabírá 52 bitů, má přesnost 53 bitů. Nejvýznamnější bit mantisy je předvídatelný, a proto není zahrnut, protože exponent čísel s plovoucí desetinnou čárkou v JVM indikuje, zda je číslo normalizováno či nikoli. Pokud jsou exponenty všechny nuly, je číslo s plovoucí desetinnou čárkou denormalizováno a je známo, že nejvýznamnější bit mantisy je nula. Jinak je číslo s plovoucí desetinnou čárkou normalizováno a je známo, že nejvýznamnější bit mantisy je jeden.

JVM nevyvolává žádné výjimky v důsledku jakýchkoli operací s plovoucí desetinnou čárkou. Speciální hodnoty, jako je kladné a záporné nekonečno nebo NaN, jsou vráceny jako výsledek podezřelých operací, jako je dělení nulou. Exponent všech označuje speciální hodnotu s plovoucí desetinnou čárkou. Exponent všech s mantisou, jejíž bity jsou nulové, označuje nekonečno. Znamení nekonečna je označeno znaménkovým bitem. Exponent všech s jakoukoli jinou mantisou je interpretován tak, že znamená „ne číslo“ (NaN). JVM vždy vytváří stejnou mantisu pro NaN, což jsou všechny nuly kromě nejvýznamnějšího bitu mantisy, který se v čísle objeví. Tyto hodnoty jsou zobrazeny pro float níže:

Speciální hodnoty float
HodnotaPlovoucí bity (znaménko exponent mantisa)
+ Nekonečno0 11111111 00000000000000000000000
-Nekonečno1 11111111 00000000000000000000000
NaN1 11111111 10000000000000000000000

Exponenti, kteří nejsou ani jeden, ani všechny nuly, označují sílu dvou, kterými se násobí normalizovaná mantisa. Síla dvou může být určena interpretací bitů exponentu jako kladného čísla a poté odečtením zkreslení od kladného čísla. Pro plovák je předpětí 126. U dvojitého je předpětí 1023. Například pole exponentu v plováku 00000001 poskytuje sílu dvou odečtením předpětí (126) od pole exponentu interpretovaného jako kladné celé číslo. (1). Síla dvou je tedy 1 - 126, což je -125. Toto je nejmenší možná síla dvou pro plovák. Na druhém konci pole exponentu 11111110 poskytuje sílu dvou (254 - 126) nebo 128. Číslo 128 je největší síla ze dvou, která je k dispozici pro plovák. Několik příkladů normalizovaných plováků je uvedeno v následující tabulce:

Normalizované plovoucí hodnoty
HodnotaPlovoucí bity (znaménko exponent mantisa)Nestranný exponent
Největší kladný (konečný) float0 11111110 11111111111111111111111128
Největší záporný (konečný) float1 11111110 11111111111111111111111128
Nejmenší normalizovaný plovák1 00000001 00000000000000000000000-125
Pi0 10000000 100100100001111110110112

Exponent všech nul označuje, že mantisa je denormalizována, což znamená, že neuváděný úvodní bit je nula místo jedné. Síla dvou je v tomto případě stejná jako nejnižší síla dvou dostupná pro normalizovanou mantisu. Pro float je to -125. To znamená, že normalizované mantisy vynásobené dvěma zvýšenými na sílu -125 mají pole exponentu 00000001, zatímco denormalizované mantisy vynásobené dvěma zvýšenými na sílu -125 mají pole exponentu 00000000. Příspěvek pro denormalizovaná čísla dole konec rozsahu exponentů podporuje postupné podtečení. Pokud by místo toho byl k reprezentaci normalizovaného čísla použit nejnižší exponent, u větších čísel by došlo k podtečení na nulu. Jinými slovy, ponechání nejnižšího exponenta pro denormalizovaná čísla umožňuje reprezentaci menších čísel. Menší denormalizovaná čísla mají méně bitů přesnosti než normalizovaná čísla, ale je lepší než podtečení na nulu, jakmile exponent dosáhne své minimální normalizované hodnoty.

Denormalizované plovoucí hodnoty
HodnotaPlovoucí bity (znaménko exponent mantisa)
Nejmenší kladný (nenulový) float0 00000000 00000000000000000000001
Nejmenší záporný (nenulový) float1 00000000 00000000000000000000001
Největší denormalizovaný plovák1 00000000 11111111111111111111111
Kladná nula0 00000000 00000000000000000000000
Záporná nula1 00000000 00000000000000000000000

Odkrytý plovák

Plovák Java odhaluje jeho vnitřní povahu Níže uvedený applet vám umožňuje hrát si s formátem s plovoucí desetinnou čárkou. Hodnota floatu se zobrazuje v několika formátech. Formát vědecké notace radix two ukazuje mantisu a exponent v základní desítce. Před zobrazením se skutečná mantisa vynásobí 2 24, čímž se získá celé číslo, a nezaujatý exponent se sníží o 24. Integrální mantisa i exponent se potom snadno převedou na základní desítku a zobrazí se.

$config[zx-auto] not found$config[zx-overlay] not found