0

IEEE-754 Float-visualizer

Ontdek precies hoe een decimaal getal wordt opgeslagen als een IEEE-754 float (tekenbit, exponentbit en mantissebit) en waarom getallen als 0,1 niet precies worden opgeslagen.

Buy Me a Coffee at ko-fi.com
Verwerken... 0%
Normaliseren
Computing exponent bias
Uitbreidende mantisse-bits
Klaar

Resultaat

Elk drijvende-kommagetal dat een computer opslaat – een JavaScript-nummer, een C-float, een Python-float – wordt op dezelfde manier gecodeerd onder IEEE 754: één tekenbit, een blok exponentbits en een blok mantissebits (fractiebits). Enkele precisie (32-bits) gebruikt 1 tekenbit, 8 exponentbits en 23 mantissebits; dubbele precisie (64-bit), het formaat achter het standaard getaltype van bijna elke taal, gebruikt 1 tekenbit, 11 exponentbits en 52 mantissebits. Deze tool neemt elk decimaal getal dat je typt, codeert het in elke breedte met behulp van de DataView/ArrayBuffer float-encoder van de browser (dezelfde machine waarop je code feitelijk draait) en kleurt elk bit op basis van de regio waartoe het behoort.

De codering zelf volgt drie stappen, en deze tool doorloopt ze allemaal in plaats van alleen de laatste stukjes weer te geven. Ten eerste normalisatie: het getal wordt herschreven als 1.mantisse × 2^exponent, met precies één cijfer dat niet nul is vóór het binaire punt (getallen die daarvoor te klein zijn, krijgen in plaats daarvan de subnormale behandeling, zonder impliciete leidende 1). Ten tweede, exponent bias: aangezien het exponentveld zowel positieve als negatieve exponenten moet opslaan als een getal zonder teken, wordt een vaste bias (127 voor enkele precisie, 1023 voor dubbele) toegevoegd voordat het veld in binair getal wordt uitgeschreven. Ten derde wordt de fractionele mantisse beetje bij beetje uitgebreid met de klassieke methode ‘vermenigvuldig met twee, neem het gehele deel als het volgende bit, behoud de rest’ – herhaald totdat het mantisseveld vol is, waarna de overgebleven bits beslissen of het resultaat naar boven of naar beneden wordt afgerond (rond-half-naar-even, de standaard van IEEE-754).

Dit is precies de reden waarom een gewoon getal als 0,1 niet precies wordt opgeslagen. In binair getal is 0,1 een zich herhalende breuk (0,0001100110011…, voor altijd), dus geen enkele eindige mantisse kan deze breuk precies vasthouden – hij moet ergens afgerond worden. Codeer 0,1 als een 32-bit float en lees de bits terug, en je krijgt niet 0,1 terug: je krijgt precies 0,100000001490116119384765625. Dubbele precisie heeft nog 29 mantissebits om mee te werken, dus de afrondingsfout is veel kleiner, maar ook niet nul: 0,1 aangezien een 64-bits dubbel precies 0,100000000000000055511151231257827021181583404541015625 is. Deze tool berekent de exacte opgeslagen waarde met rekenkundige berekeningen met grote gehele getallen (geen snelkoppelingen met drijvende komma), zodat de kloof tussen wat u hebt getypt en wat de hardware daadwerkelijk bijhoudt nooit verborgen of bij benadering wordt weergegeven.

Speciale waarden krijgen exacte, gereserveerde bitpatronen in plaats van een normale codering: nul en negatieve nul hebben exponent- en mantisse-bits die allemaal nul zijn (alleen het tekenbit verschilt), ± Infinity heeft allemaal-één exponent-bits met een mantisse die helemaal nul is, en NaN heeft allemaal-één exponent-bits met ten minste één mantisse-bit ingesteld. Alles hier draait lokaal in je browser - niets wat je typt wordt ergens geüpload - wat dit een veilige plek maakt om echte intuïtie voor drijvende-komma-bugs op te bouwen: waarom `0.1 + 0.2 !== 0.3` in bijna elke programmeertaal, waarom float32-texturen in grafische code precisie verliezen die float64 niet zou doen, en waarom financiële code over het algemeen binaire drijvende komma helemaal zou moeten vermijden.