0

IEEE-754 Float Visualizer

Se nøyaktig hvordan et desimaltall lagres som en IEEE-754-float — tegnbit, eksponentbit og mantissebit — og hvorfor tall som 0.1 ikke lagres nøyaktig.

Buy Me a Coffee at ko-fi.com
Behandler... 0%
Normalisering
Dataeksponentskjevhet
Ekspanderende mantissebiter
Ferdig

Resultat

Hvert flyttallnummer en datamaskin lagrer - et JavaScript-tall, en C-float, en Python-float - er kodet på samme måte under IEEE 754: en fortegnsbit, en blokk med eksponentbiter og en blokk med mantisse (brøk)biter. Enkel presisjon (32-bit) bruker 1 tegnbit, 8 eksponentbiter og 23 mantissebiter; dobbel presisjon (64-bit), formatet bak nesten alle språks standard talltype, bruker 1 tegnbit, 11 eksponentbiter og 52 mantissebiter. Dette verktøyet tar et hvilket som helst desimaltall du skriver inn, koder det i begge breddene ved hjelp av nettleserens egen DataView/ArrayBuffer flytekoder – det samme maskineriet som koden din faktisk kjører på – og farger hver bit etter hvilken region den tilhører.

Selve kodingen følger tre trinn, og dette verktøyet går gjennom alle i stedet for bare å vise de siste bitene. Først normalisering: tallet skrives om til 1.mantisse × 2^eksponent, med nøyaktig ett siffer som ikke er null før det binære punktet (tall som er for små til det får den subnormale behandlingen i stedet, uten implisitt innledende 1). For det andre, eksponentskjevhet: siden eksponentfeltet må lagre både positive og negative eksponenter som et tall uten fortegn, legges en fast skjevhet (127 for enkel presisjon, 1023 for dobbel) før feltet skrives ut i binært. For det tredje utvides brøkmantissen bit for bit med den klassiske «multipliser med to, ta heltallsdelen som neste bit, behold resten»-metoden – gjentas til mantissefeltet er fullt, og da bestemmer de resterende bitene om resultatet rundes opp eller ned (rundt halvparten til partall, standard IEEE-754).

Dette er nøyaktig grunnen til at et så vanlig tall som 0,1 ikke lagres nøyaktig. I binær er 0.1 en repeterende brøk (0.0001100110011…, for alltid), så ingen endelig mantisse kan holde den nøyaktig – den må rundes av et sted. Kod 0.1 som en 32-bits float og les bitene tilbake, og du får ikke 0.1 tilbake: du får nøyaktig 0.100000001490116119384765625. Dobbel presisjon har 29 flere mantissebiter å jobbe med, så avrundingsfeilen er langt mindre, men den er heller ikke null - 0,1 som en 64-bits dobbel er nøyaktig 0,100000000000000000555111512312578270211545254101015452541010. Dette verktøyet beregner den nøyaktige lagrede verdien med aritmetikk med stort heltall (ingen flytende kommasnarveier), slik at gapet mellom det du skrev og det maskinvaren faktisk beholder aldri blir skjult eller tilnærmet.

Spesielle verdier får eksakte, reserverte bitmønstre i stedet for en normal koding: null og negativ null har helt null eksponent- og mantissebiter (bare fortegnsbiten er forskjellig), ±Infinity har alt-en-eksponentbiter med en alt-null-mantisse, og NaN har alle-en-eksponentbiter med minst en mantissebit satt. Alt her kjører lokalt i nettleseren din – ingenting du skriver blir lastet opp noe sted – noe som gjør dette til et trygt sted å bygge ekte intuisjon for flytende-punkt-feil: hvorfor `0.1 + 0.2 !== 0.3` i nesten alle programmeringsspråk, hvorfor float32-teksturer i grafikkkode mister presisjon som float64 generelt ikke burde unngå å peke på, og hvorfor binær finansiell kode totalt sett ikke ville.