0

IEEE-754 Float Visualizer

Se præcis, hvordan et decimaltal er gemt som en IEEE-754 float — fortegnsbit, eksponentbit og mantissebit — og hvorfor tal som 0.1 ikke gemmes nøjagtigt.

Buy Me a Coffee at ko-fi.com
Behandler... 0%
Normalisering
Beregningseksponentbias
Udvidende mantissebits
Færdig

Resultat

Hvert flydende kommatal, som en computer gemmer - et JavaScript-tal, et C-float, en Python-float - er kodet på samme måde under IEEE 754: en fortegnsbit, en blok af eksponentbits og en blok af mantisse (brøk)bit. Enkelt præcision (32-bit) bruger 1 tegnbit, 8 eksponentbit og 23 mantissebit; dobbelt præcision (64-bit), formatet bag næsten alle sprogs standardnummertype, bruger 1 tegnbit, 11 eksponentbit og 52 mantissebit. Dette værktøj tager ethvert decimaltal, du indtaster, koder det i begge bredder ved hjælp af browserens egen DataView/ArrayBuffer float-encoder - det samme maskineri, som din kode faktisk kører på - og farver hver bit efter hvilken region den tilhører.

Selve kodningen følger tre trin, og dette værktøj gennemgår dem alle i stedet for blot at vise de sidste bits. Først normalisering: tallet omskrives som 1.mantisse × 2^eksponent, med nøjagtig et ciffer, der ikke er nul, før det binære punkt (tal, der er for små til det, får den subnormale behandling i stedet, uden implicit foranstående 1). For det andet eksponentbias: da eksponentfeltet skal lagre både positive og negative eksponenter som et tal uden fortegn, tilføjes en fast bias (127 for enkelt præcision, 1023 for dobbelt), før feltet skrives ud i binært. For det tredje udvides brøkmantissen bit for bit med den klassiske "multiplikér med to, tag heltalsdelen som den næste bit, behold resten"-metoden - gentaget, indtil mantissefeltet er fuldt, hvorefter de resterende bits afgør, om resultatet rundes op eller ned (runder halvt til lige, IEEE-754-standarden).

Det er præcis grunden til, at et tal så almindeligt som 0,1 ikke gemmes nøjagtigt. I binær er 0,1 en gentagende brøk (0,0001100110011…, for evigt), så ingen endelig mantisse kan holde den præcist - den skal rundes af et sted. Indkode 0.1 som en 32-bit float og læs bitsene tilbage, og du får ikke 0.1 tilbage: du får præcis 0.100000001490116119384765625. Dobbelt præcision har 29 flere mantissebits at arbejde med, så dens afrundingsfejl er langt mindre, men den er heller ikke nul - 0,1, da en 64-bit double er nøjagtigt 0,1000000000000000005551115123125782702115452541010. Dette værktøj beregner den nøjagtige lagrede værdi med aritmetik med stort heltal (ingen genveje med flydende komma), så afstanden mellem det, du har skrevet, og det, som hardwaren faktisk gemmer, bliver aldrig skjult eller tilnærmet.

Specielle værdier får nøjagtige, reserverede bitmønstre i stedet for en normal kodning: nul og negativ nul har eksponent- og mantissebit helt nul (kun fortegnsbitten er forskellig), ±Infinity har alle-en-eksponentbits med en mantisse med alt-nul, og NaN har alle-en-eksponentbits med mindst én mantissebit. Alt her kører lokalt i din browser - intet du skriver uploades nogen steder - hvilket gør dette til et sikkert sted at opbygge ægte intuition for floating-point-fejl: hvorfor `0.1 + 0.2 !== 0.3` i næsten alle programmeringssprog, hvorfor float32-teksturer i grafikkode mister præcision, som float64 generelt ikke burde undgå, og hvorfor binær finansiel kode generelt ikke burde undgå.