0

IEEE-754 vizualizator floatova

Vidite točno kako se decimalni broj pohranjuje kao IEEE-754 float — bit predznaka, bitovi eksponenta i bitovi mantise — i zašto brojevi poput 0.1 nisu pohranjeni točno.

🔒 U potpunosti se obrađuje u vašem pregledniku — ništa što ovdje unesete nikada se ne učitava.

Obrada... 0%
Normalizacija
Izračun pristranosti eksponenta
Proširivanje bitova 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 bitova eksponenta i 23 bita mantise; dvostruka preciznost (64-bitna), format koji stoji iza gotovo svakog podrazumijevanog tipa broja u programskim jezicima, koristi 1 bit predznaka, 11 bitova eksponenta i 52 bita mantise. Ovaj alat uzima bilo koji decimalni broj koji upišete, kodira ga u bilo kojoj širini koristeći enkoder float vrijednosti ugrađen u preglednik putem DataView/ArrayBuffer — ista mašinerija na kojoj se vaš kod stvarno izvodi — i boji svaki bit prema području kojem pripada.

Samo kodiranje slijedi tri koraka, a ovaj alat prolazi kroz sve njih umjesto da samo prikazuje konačne bitove. Prvo, normalizacija: broj se zapisuje kao 1.mantisa × 2^eksponent, s točno jednom znamenkom različitom od nule prije binarne točke (brojevi koji su za to premali umjesto toga dobivaju tretman subnormalnih, bez implicitne vodeće jedinice). Drugo, pristranost eksponenta: budući da polje eksponenta mora pohraniti i pozitivne i negativne eksponente kao nepredznačeni broj, dodaje se fiksna pristranost (127 za jednostruku preciznost, 1023 za dvostruku) prije nego što se polje zapiše u binarnom obliku. Treće, razlomljena mantisa se proširuje bit po bit klasičnom metodom “pomnoži s dva, uzmi cijeli dio kao sljedeći bit, zadrži ostatak” — ponavlja se dok se polje mantise ne popuni, a u tom trenutku preostali bitovi određuju zaokružuje li se rezultat prema gore ili prema dolje (zaokruživanje na parni, IEEE-754 zadani način).

Upravo to je razlog zašto broj tako običan kao 0.1 nije pohranjen točno. U binarnom sustavu, 0.1 je periodični razlomak (0.0001100110011…, zauvijek), tako da ga nijedna konačna mantisa ne može držati precizno — mora se negdje zaokružiti. Kodirajte 0.1 kao 32-bitni float i pročitajte bitove natrag, i nećete dobiti natrag 0.1: dobit ćete točno 0.100000001490116119384765625. Dvostruka preciznost ima 29 bitova mantise više za raditi, tako da je njena pogreška zaokruživanja daleko manja, ali nije ni nula — 0.1 kao 64-bitni double je točno 0.1000000000000000055511151231257827021181583404541015625. Ovaj alat izračunava tu točnu pohranjenu vrijednost aritmetikom 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 bitne obrasce umjesto normalnog kodiranja: nula i negativna nula imaju sve bitove eksponenta i mantise postavljene na nulu (razlikuje se samo bit predznaka), ±Beskonačno ima sve bitove eksponenta jedan s mantisom svih nula, a NaN ima sve bitove eksponenta jedan s barem jednim bitom mantise postavljenim. Sve se ovdje izvodi lokalno u vašem pregledniku — ništa što upišete ne prenosi se nikamo — što ovo čini sigurnim mjestom za izgradnju stvarne intuicije o bugovima s pomičnim zarezom: zašto je `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 u potpunosti izbjegavati binarni pomični zarez.