De eerste keer a 0.1 + 0.2 === 0.3 bug beet me in productie, ik deed wat de meeste ontwikkelaars doen: ik zocht, vond & quot; zwevend punt is raar, & quot; en ging verder Het was jaren voordat ik daadwerkelijk naar de bits keek en begreep waarom Toen ik dat eenmaal deed, was een hele categorie numerieke bugs niet meer mysterieus. Deze gids loopt door wat een IEEE 754-converter je laat zien, met behulp van de IEEE 754-converter op Toolz.dev, en waarom staren naar het bord, de exponent en de mantisse de snelste manier is om echte intuïtie op te bouwen over hoe computers decimalen opslaan.
tl;dr: Computers slaan getallen met drijvende komma op als teken, een macht van twee en een fractionele significantie, volgens de IEEE 754-standaard Een IEEE 754-converter codeert een decimaal zoals 3.14159 in die exacte bits en decodeert bits terug naar een waarde De IEEE 754-converter doet beide, voor enkele en dubbele precisie, volledig in uw browser, met het teken, de exponent en de mantisse uitgebroken.
Wat is IEEE 754?
IEEE 754 is de standaard, voor het eerst gepubliceerd in 1985 en herzien als IEEE 754-2019, dat definieert hoe computers drijvende-kommagetallen in binair vertegenwoordigen Bijna elke CPU, GPU en programmeertaal volgt het, en daarom is a double gedraagt zich hetzelfde in C, Java, Python en JavaScript. Wanneer mensen zeggen "floating point, & quot; bedoelen ze bijna altijd IEEE 754 binaire drijvende komma.
Kernidee is dat een getal in drie delen opgeslagen wordt Er is een tekenbit dat positief of negatief zegt Er is een exponent die de waarde schaalt met een macht van twee En er is een mantisse, ook wel de breuk of significantie genoemd, die de precieze cijfers bij elkaar houdt, een normaal getal is teken maal 1.mantissa maal 2 tot de exponent Het is wetenschappelijke notatie, in grondtal twee, verpakt in een vast aantal bits.
De twee formaten die je dagelijks ontmoet zijn enkele precisie, genaamd binary32, en dubbele precisie, genaamd binary64 Single gebruikt 1 tekenbit, 8 exponentbits en 23 mantissebits, voor in totaal 32 bits Dubbel gebruikt 1 tekenbit, 11 exponentbits en 52 mantissebits, voor in totaal 64 bits. Dubbel is het standaard drijvende-kommatype in de meeste talen; enkelvoudig is gebruikelijk op GPU's en in geheugengevoelige code.
Wat doet een IEEE 754 converter eigenlijk?
Een IEEE 754 converter neemt een getal en toont je zijn exacte bitpatroon, opgesplitst in die drie velden, samen met de hexadecimale vorm en de waarde die wordt teruggelezen uit de bits Het werkt twee kanten op: voer een decimaal in om het te coderen, of plak een binair of hex bitpatroon om het terug te decoderen in het getal dat het vertegenwoordigt.
Op Toolz.dev is de workflow kort Kies enkelvoudige of dubbele precisie Kies of uw invoer een decimaal getal, een hex bit patroon, of een binair bit patroon is Voer de waarde in Het gereedschap toont de tekenbit, het exponent veld, de mantisse, de volledige bits, de hex, zowel de vooringenomen als onbevooroordeelde exponent, en de exact opgeslagen waarde Elk veld heeft een kopieerknop.
De reden om dit alles te bekijken, in plaats van te vertrouwen op het nummer dat je taal afdrukt, is dat het afgedrukte nummer ligt door weglating Wanneer je console wordt weergegeven 0.1, het toont je een afgeronde, vriendelijke weergave De bits vertellen je wat er echt is opgeslagen, en het verschil tussen die twee is waar drijvende-komma bugs leven.
Waarom is 0,1 plus 0,2 niet gelijk aan 0,3?
Dit is het canonieke voorbeeld, en de converter maakt het concreet De waarde 0,1 kan niet exact in binair drijvende komma worden weergegeven, om dezelfde reden kan 1/3 niet exact in decimaal worden geschreven In grondtal tien is 1/3 voor altijd 0,3333... In grondtal twee is 0,1 een zich herhalende breuk die nooit eindigt, dus moet deze worden afgerond om in 52 mantissebits te passen.
Decodeer het dubbele voor 0,1 en de waarde die de bits daadwerkelijk bevatten is 0,10000000000005551151231257827021181583404541015625 Het dubbele voor 0,2 is op dezelfde manier een haar te groot Voeg de twee afgeronde waarden toe en het resultaat is een klein beetje meer dan 0,3, maar het dubbele voor 0,3 is een klein beetje minder, dus de twee zijn niet gelijk. Er is niets gebroken. Elke stap doet precies wat IEEE 754 vereist, en de converter laat je zien dat het gebeurt.
Als je dit hebt gezien, volgt de fix natuurlijk: vergelijk nooit floats voor exacte gelijkheid Vergelijk binnen een kleine tolerantie, of gebruik gehele centen voor geld, of een decimale bibliotheek wanneer je exacte decimale rekenkunde nodig hebt De bug zat nooit in de toevoeging Het was in de verwachting dat een binair formaat decimale breuken precies zou opslaan.
Wat zijn het teken, de exponent en de mantisse?
Elk veld heeft een specifieke taak en de converter labelt ze alle drie.
Het tekenbit is het eenvoudigst: 0 betekent positief, 1 betekent negatief Omdat het teken een apart bit is heeft IEEE 754 zowel een positieve als een negatieve nul, die zich in vergelijkingen gelijk gedragen maar verschillende bits dragen.
Het exponentveld slaat een macht van twee op, maar met een bias toegevoegd zodat het negatieve exponenten kan weergeven zonder een apart teken De bias is 127 voor enkele precisie en 1023 voor dubbel Dus een opgeslagen exponentveld van 127 in enkele precisie betekent een werkelijke exponent van nul De Toolz.dev converter toont beide getallen: de biased waarde die in de bits leeft, en de unbiased power van twee is eigenlijk van toepassing Dat onderscheid struikelt een heleboel mensen, daarom spelt de tool het uit in plaats van je af te trekken in je hoofd.
De mantisse houdt het fractionele deel van de significantie vast Voor een normaal getal is er een impliciete voorloop 1 die niet wordt opgeslagen, omdat een genormaliseerde binaire significantie altijd begint met 1, dus het formaat krijgt een vrij stukje precisie door het weg te laten. Daarom geeft een enkele precisie ongeveer 7 decimale cijfers en het dubbele ongeveer 15 tot 16, ook al zijn de mantissevelden 23 en 52 bits.
Hier ziet u hoe de twee formaten veld voor veld op één lijn liggen:
| Property | Enkelvoudig (binary32) | Dubbel (binary64) |
|---|---|---|
| Totaal bits | 32 | 64 |
| Bits ondertekenen | 1 | 1 |
| Exponentbits | 8 | 11 |
| Mantissa bits | 23 | 52 |
| Exponent bias | 127 | 1023 |
| Ongeveer. decimale cijfers | 7 | 15 tot 16 |
| Algemene naam | float | double |
Hoe converteer ik bits terug naar een decimaal getal?
Decoderen is net zo handig als coderen, en het is hoe je een waarde uit een geheugendump, een binair bestandsformaat of een netwerkprotocol leest dat onbewerkte floats opslaat Stel het invoertype in op Hex of Binary en plak het exacte bitpatroon dat de precisie verwacht: 8 hex-cijfers of 32 bits voor enkel, 16 hex-cijfers of 64 bits voor dubbel.
Bijvoorbeeld de single-precision hex 40490FDB decodeert naar 3.1415927, de dichtstbijzijnde vlotter bij pi. De converter accepteert ook een optionele 0x spaties en onderstrepingstekens voor - en negeren, zodat je gegroepeerde bytes kunt plakken terwijl je ze vindt Als je het het verkeerde aantal cijfers geeft, vertelt het je precies hoeveel die precisie nodig heeft in plaats van stil af te korten, wat het soort foutmelding is waarvan ik wens dat meer tools de moeite nemen om te schrijven.
Deze decoderichting koppelt op natuurlijke wijze aan een generaal Nummer Basisomvormer wanneer u een waarde tussen decimaal, hex, binair en octaal moet verplaatsen zonder de drijvende-komma-interpretatie, en met de binaire vertaler als je met tekst werkt in plaats van met cijfers, reik ik vaak genoeg naar alle drie dat ze in dezelfde hoek van mijn bladwijzers leven.
Hoe worden oneindigheid, NaN en nul weergegeven?
De speciale waarden zijn waar IEEE 754 slim wordt, en de converter identificeert elk geval voor u, zodat u de patronen niet hoeft te onthouden.
Het exponentveld fungeert als schakelaar Wanneer elk exponentbit 1 is, zit je in het speciale bereik: een mantisse die geheel nul is, betekent oneindig, en elke mantisse die niet nul is, betekent NaN, niet een getal. Positieve en negatieve oneindigheid verschillen alleen door het tekenbit. NaN is wat je krijgt van bewerkingen als nul gedeeld door nul of de vierkantswortel van een negatief, en het heeft de beroemde eigenschap dat het zichzelf niet evenaart.
Wanneer elk exponentbit 0 is, bevindt u zich in het andere speciale bereik: een mantisse die geheel nul is, is nul, positief of negatief, afhankelijk van het tekenbit, en een mantisse die niet nul is, is een subnormaal getal. Subnormalen vullen het gat tussen nul en het kleinste normale getal, waarbij ze precisie inruilen voor de mogelijkheid om zeer kleine magnitudes weer te geven. Ze gebruiken een effectieve exponent van één minus de bias, en ze laten de impliciete voorloop 1 vallen, die de converter in rekening brengt wanneer deze de onbevooroordeelde exponent laat zien.
Al het andere, waarbij het exponentveld noch alle nullen, noch alle enen is, is een normaal getal, In staat zijn om een blik te werpen op een bitpatroon en direct te weten naar welke van deze vijf gevallen je kijkt, is een echte debugging superpower wanneer een berekening een waarde oplevert die je niet had verwacht.
Wanneer heb ik dit eigenlijk nodig?
Je hebt het vaker nodig dan je zou raden als je eenmaal weet te kijken. Ik reik ernaar als een numeriek resultaat door een afrondingsfout wordt uitgeschakeld en ik wil bevestigen of de waarde precies representeerbaar is. Ik gebruik het bij het schrijven of debuggen van een binaire serialisator, een bestandsformaat of een draadprotocol dat floats opslaat, zodat ik kan verifiëren dat de bytes overeenkomen met wat ik bedoelde. Het is onmisbaar bij het vergelijken van enkele en dubbele precisie, bijvoorbeeld bij het beslissen of een GPU-shader kan gebruiken float zonder al te veel nauwkeurigheid te verliezen En het is een van de duidelijkste leermiddelen die ik ken voor computerarchitectuur, omdat het zien van de velden de abstracte standaard tastbaar maakt.
Als je over de stapel bouwt zoals ik dat doe, verschijnt floating point op verrassende plekken: een prijsberekening in een Laravel API, een canvasanimatie in React, een CSV-export die een coördinaat verminkt Het begrijpen van het opslagformaat is een kleine investering die voor al deze dingen loont Ik schreef over hoe dit soort tools in een bredere kit in de Webontwikkelaar Toolkit, en de gids voor nummerbasisconverters en gids voor binaire vertalers bedek de aangrenzende conversies op laag niveau dieper.
Wat zijn de grenzen van de drijvende-kommaprecisie?
Zodra je de bits kunt zien, stoppen de limieten van het formaat als abstract Een dubbel heeft 52 opgeslagen mantisse bits plus de impliciete voorloop 1, wat neerkomt op grofweg 15 tot 16 significante decimale cijfers Duw daar voorbij en precisie verdampt stilletjes Het grootste gehele getal dat een dubbel kan vertegenwoordigen met elke waarde ertussen nog steeds exact is 2 tot de 53e macht, dat is 9007199254740992 Voeg daar één aan toe en het resultaat wordt weer naar beneden afgerond, omdat de volgende representeerbare waarde twee weg is, niet één. Dit is de reden waarom talen die dubbel gebruiken voor alle getallen, JavaScript ertussen, een blootleggen Number.MAX_SAFE_INTEGER constant op precies die waarde, en waarom grote database-ID's die als JSON-nummers worden verzonden, stilletjes kunnen corrumperen.
De kloof tussen de ene representeerbare waarde en de volgende wordt op de laatste plaats een eenheid genoemd, of ULP, en groeit naarmate de magnitude groeit. Bijna 1,0 is de kloof klein; bijna een miljard is het een paar honderd; bijna het maximale dubbele, ongeveer 1,8 keer 10 tot de 308e, is de kloof tussen buren astronomisch groot. De converter maakt dit zichtbaar: codeer twee grote getallen in de buurt en je zult vaak merken dat ze dezelfde bits delen, omdat er eenvoudigweg geen representatie tussen hen is. Door ULP te begrijpen, kun je niet meer resolutie verwachten dan het formaat kan geven.
Een gerelateerde val is catastrofale annulering Wanneer je twee bijna gelijke drijvende-kommagetallen aftrekt, annuleren de leidende cijfers en houd je de lage-orde bits over, die in het begin het minst nauwkeurige deel waren Het resultaat kan worden gedomineerd door afrondingsfouten, ook al zag elke invoer er nauwkeurig uit. Dit is de reden waarom numeriek zorgvuldige code-herschikkingen bewerkingen om te voorkomen dat kleine hoeveelheden worden afgetrokken, en waarom het optellen van een lange lijst met floats in een naïeve lus fouten accumuleert die betere algoritmen zoals Kahan-sommatie vermijden.
De praktische afhaalmogelijkheden zijn consistent Geld niet opslaan als een float; gebruik gehele centen of een decimaal type, omdat een waarde als 0,10 niet precies representeerbaar is en fouten over duizenden transacties worden samengesteld Vergelijk floats niet met exacte gelijkheid; vergelijk binnen een tolerantiegrootte met uw probleem En wanneer een zeer groot geheel getal een retour moet overleven, bewaar het dan als een string of gebruik een geheel getal met willekeurige precisie in plaats van erop te vertrouwen dat een dubbelganger het vasthoudt Elk van deze regels is gemakkelijker te onthouden zodra de converter u heeft laten zien waarom het formaat zich gedraagt zoals het doet.
Veelgestelde vragen
Hoe converteer ik een decimaal getal naar IEEE 754?
Kies enkele of dubbele precisie, houd het invoertype op Decimal, typ uw nummer en converteer Het gereedschap codeert de waarde in zijn IEEE 754 bit patroon en toont het teken bit, exponent veld, mantisse, volledige binaire, en hexadecimale Alles draait in uw browser.
Wat is het verschil tussen enkele en dubbele precisie?
Enkelvoudige precisie (binary32) gebruikt 32 bits: 1 teken, 8 exponent en 23 mantisse, wat ongeveer 7 decimale cijfers van precisie oplevert Dubbele precisie (binary64) gebruikt 64 bits: 1 teken, 11 exponent en 52 mantisse, wat ongeveer 15 tot 16 cijfers oplevert Dubbel is het standaard float-type in de meeste talen; enkelvoudig is gebruikelijk op GPU's en in geheugenbeperkte code.
Waarom converteert 0,1 niet naar een exacte waarde?
0,1 heeft geen eindige representatie in binair drijvende komma, net zoals 1/3 geen eindige decimaal heeft. Het dichtstbijzijnde representatieve dubbele is 0,10000000000000551151231257827021181583404541015625. De converter toont de opgeslagen waarde die wordt teruggelezen uit de bits, zodat je het kleine verschil kunt zien dat afrondingsverrassingen veroorzaakt zoals 0,1 + 0,2, wat niet gelijk is aan 0,3.
Wat zijn het teken, de exponent en de mantisse?
Het tekenbit is 0 voor positief en 1 voor negatief Het exponentveld slaat een macht van twee op met een bias toegevoegd (127 voor enkel, 1023 voor dubbel), daarom toont het gereedschap zowel de biased waarde in de bits als de unbiased power die het toepast De mantisse houdt het fractionele deel van de significantie vast, met een impliciete leading 1 voor normale getallen.
Kan ik IEEE 754 bits terug converteren naar een decimaal getal?
Ja. stel het invoertype in op Hex of Binary en plak het exacte bitpatroon: 8 hex-cijfers of 32 bits voor enkele precisie, 16 hex-cijfers of 64 bits voor dubbel. Het gereedschap decodeert het en toont de decimale waarde die het vertegenwoordigt, samen met de volledige velduitsplitsing.
Hoe worden oneindigheid, NaN en nul weergegeven?
Wanneer elke exponentbit 1 is, betekent een mantisse die geheel nul is oneindig en een mantisse die niet nul is NaN. Wanneer elke exponentbit 0 is, is een mantisse die geheel nul is nul (positief of negatief afhankelijk van de tekenbit) en een mantisse die niet nul is, is een subnormaal getal. De converter labelt elk van deze gevallen voor u.
Is het veilig om deze tool te gebruiken voor gevoelige getallen?
Ja. de conversie draait volledig in JavaScript in uw browser Geen netwerkverzoek draagt uw invoer, niets wordt opgeslagen, en de tool werkt offline zodra de pagina is geladen, dus elke waarde die u invoert blijft op uw apparaat.
Welk hex-formaat verwacht de converter?
Gewone hexadecimale cijfers, met een optioneel voorvoegsel van 0x en spaties of onderstrepingstekens voor groepering, die worden genegeerd Enkelvoudige precisie verwacht 8 hexadecimale cijfers en dubbele precisie verwacht 16. 40490FDB is bijvoorbeeld single-precision pi (3.1415927).
Verken de stukjes zelf met de gratis IEEE 754-converter. Het codeert en decodeert enkele en dubbele precisiewagens volledig in uw browser, zonder dat er iets is geüpload.



