IEEE-754 Float Visualizer
Pozrite sa, ako presne sa ukladá desatinné číslo ako IEEE-754 float – znamienkový bit, exponentné bity a bity mantisy – a prečo sa čísla ako 0,1 neukladajú presne.
Výsledok
Každé číslo s pohyblivou rádovou čiarkou, ktoré počítač ukladá – číslo JavaScriptu, C float, Python float – je zakódované rovnakým spôsobom podľa IEEE 754: jeden znamienkový bit, blok exponentných bitov a blok mantisových (zlomkových) bitov. Jednoduchá presnosť (32-bitová) používa 1 znamienkový bit, 8 exponentných bitov a 23 mantisových bitov; dvojitá presnosť (64-bit), formát za predvoleným typom čísel takmer každého jazyka, používa 1 znakový bit, 11 exponentných bitov a 52 mantisových bitov. Tento nástroj prevezme akékoľvek desatinné číslo, ktoré napíšete, zakóduje ho v ľubovoľnej šírke pomocou vlastného plávacieho kódovača DataView/ArrayBuffer prehliadača – rovnakého stroja, na ktorom skutočne beží váš kód – a zafarbí každý bit podľa oblasti, do ktorej patrí.
Samotné kódovanie prebieha v troch krokoch a tento nástroj prechádza všetkými z nich namiesto toho, aby len zobrazoval posledné bity. Po prvé, normalizácia: číslo sa prepíše ako 1.mantisa × 2^exponent s presne jednou nenulovou číslicou pred binárnym bodom (čísla, ktoré sú na to príliš malé, dostanú subnormálne spracovanie, bez implicitného úvodu 1). Po druhé, odchýlka exponentov: keďže pole exponentov musí uchovávať kladné aj záporné exponenty ako číslo bez znamienka, pred zapísaním poľa v binárnom formáte sa pridá pevná odchýlka (127 pre jednoduchú presnosť, 1023 pre dvojitú presnosť). Po tretie, zlomková mantisa sa rozširuje bit po bite pomocou klasickej metódy „vynásobte dvoma, vezmite celú časť ako ďalší bit, ponechajte si zvyšok“ – opakuje sa, kým sa pole mantisy nezaplní, v tomto bode zostávajúce bity rozhodnú, či sa výsledok zaokrúhli nahor alebo nadol (zaokrúhlenie na polovicu na párne, štandardné nastavenie IEEE-754).
To je presne dôvod, prečo obyčajné číslo ako 0,1 nie je uložené presne. V dvojkovej sústave je 0,1 opakujúci sa zlomok (0,0001100110011…, navždy), takže žiadna konečná mantisa to nedokáže presne udržať – niekde sa musí zaokrúhliť. Kódujte 0.1 ako 32-bitový float a čítajte bity späť a 0.1 nedostanete späť: dostanete presne 0,100000001490116119384765625. Dvojitá presnosť má o 29 viac bitov mantisy na prácu, takže jej chyba zaokrúhľovania je oveľa menšia, ale nie je ani nulová — 0,1 ako 64-bitová dvojitá je presne 0,100000000000000005511151231257827021181510140445510256. Tento nástroj vypočíta túto presnú uloženú hodnotu pomocou aritmetiky veľkého celého čísla (žiadne skratky s pohyblivou rádovou čiarkou), takže rozdiel medzi tým, čo ste napísali, a tým, čo hardvér skutočne uchováva, nie je nikdy skrytý ani aproximovaný.
Špeciálne hodnoty získajú presné, vyhradené bitové vzory namiesto normálneho kódovania: nula a záporná nula majú nulový exponent a mantisový bit (líši sa len znamienkový bit), ±Infinity má celý jeden exponentný bit s mantisou nula a NaN má celý jeden exponentný bit s nastaveným aspoň jedným bitom mantisy. Všetko tu beží lokálne vo vašom prehliadači – nič, čo napíšete, sa nikam neodovzdáva – vďaka čomu je toto bezpečné miesto na budovanie skutočnej intuície pre chyby s pohyblivou rádovou čiarkou: prečo `0,1 + 0,2 !== 0,3` v takmer každom programovacom jazyku, prečo textúry float32 v grafickom kóde strácajú presnosť, ktorú by float64 nemal, a prečo by sa finančný kód mal vo všeobecnosti vyhýbať binárnemu spojeniu.