0

IEEE-754 plutajući vizualizator

Pogledajte točno kako se decimalni broj pohranjuje kao IEEE-754 float — bit predznaka, bit eksponenta i bit mantise — i zašto se brojevi poput 0,1 ne pohranjuju točno.

Buy Me a Coffee at ko-fi.com
Obrada... 0%
Normaliziranje
Računanje pristranosti eksponenata
Proširujući bitovi mantise
Gotovo

Rezultat

Svaki broj s pomičnim zarezom koji računalo pohranjuje — JavaScript broj, C float, Python float — kodiran je na isti način prema IEEE 754: jedan bit predznaka, blok bitova eksponenta i blok bitova mantise (razlomka). Jednostruka preciznost (32-bitna) koristi 1 bit predznaka, 8 bita eksponenta i 23 bita mantise; dvostruka preciznost (64-bitni), format koji stoji iza zadanog tipa broja gotovo svakog jezika, koristi 1 bit znaka, 11 bita eksponenta i 52 bita mantise. Ovaj alat uzima bilo koji decimalni broj koji upisujete, kodira ga u bilo koju širinu pomoću vlastitog DataView/ArrayBuffer float kodera preglednika — iste mašinerije na kojoj vaš kod zapravo radi — i boji svaki bit prema regiji kojoj pripada.

Samo kodiranje slijedi tri koraka, a ovaj alat prolazi kroz sve njih umjesto da samo prikazuje posljednje dijelove. Prvo, normalizacija: broj se prepisuje kao 1.mantisa × 2^eksponent, s točno jednom znamenkom različitom od nule ispred binarne točke (brojevi premali za to dobivaju subnormalni tretman umjesto toga, bez implicitnog vodećeg 1). Drugo, pristranost eksponenta: budući da polje eksponenta mora pohraniti i pozitivne i negativne eksponente kao broj bez predznaka, dodaje se fiksna pristranost (127 za jednostruku preciznost, 1023 za dvostruku) prije nego što se polje ispiše u binarnom obliku. Treće, frakcijska mantisa se proširuje malo po malo klasičnom metodom "pomnoži s dva, uzmi cjelobrojni dio kao sljedeći bit, zadrži ostatak" — ponavlja se dok se polje mantise ne popuni, u kojoj točki preostali bitovi odlučuju hoće li rezultat zaokružiti gore ili dolje (zaokružiti od pola do čak, IEEE-754 zadana vrijednost).

To je upravo razlog zašto tako običan broj kao što je 0,1 nije točno pohranjen. U binarnom obliku, 0,1 je razlomak koji se ponavlja (0,0001100110011…, zauvijek), tako da ga nikakva konačna mantisa ne može precizno držati — mora se negdje zaokružiti. Kodirajte 0.1 kao 32-bitni float i pročitajte bitove natrag, i nećete dobiti 0.1 natrag: dobit ćete točno 0.100000001490116119384765625. Dvostruka preciznost ima još 29 bitova mantise za rad, tako da je njena pogreška zaokruživanja daleko manja, ali nije ni nula — 0,1 kao 64-bitni dvostruki je točno 0,100000000000000055511151231257827021181583404541015625. Ovaj alat izračunava tu točnu pohranjenu vrijednost pomoću aritmetike velikih cijelih brojeva (bez prečaca s pomičnim zarezom) tako da razlika između onoga što ste upisali i onoga što hardver zapravo čuva nikada nije skrivena ili aproksimirana.

Posebne vrijednosti dobivaju točne, rezervirane uzorke bitova umjesto normalnog kodiranja: nula i negativna nula imaju sve nulte eksponente i bitove mantise (razlikuje se samo bit predznaka), ±Infinity ima sve jedan bitove eksponenta s potpuno nultom mantisom, a NaN ima sve jedan bitove eksponenta s postavljenim barem jednim bitom mantise. Sve se ovdje izvodi lokalno u vašem pregledniku — ništa što upišete nigdje se ne učitava — što ovo čini sigurnim mjestom za stvaranje stvarne intuicije za pogreške s pomičnim zarezom: zašto `0.1 + 0.2 !== 0.3` u gotovo svakom programskom jeziku, zašto float32 teksture u grafičkom kodu gube preciznost koju float64 ne bi i zašto bi financijski kod općenito trebao izbjegavati binarne pomične zareze ukupno.