IEEE-754 ujukoma visualiseerija
Vaata täpselt, kuidas kümnendarv salvestatakse IEEE-754 ujukomaarvuna – märgibitt, eksponendi bitid ja mantissi bitid – ja miks sellised arvud nagu 0,1 ei ole salvestatud täpselt.
🔒 Töödeldud täielikult teie brauseris – midagi, mida siia sisestate, ei laadita kunagi üles.
Tulemus
Iga ujukomaarv, mida arvuti salvestab – JavaScripti number, C float, Pythoni float – kodeeritakse IEEE 754 järgi ühtemoodi: üks märgibitt, eksponendibittide plokk ja mantissi (murru) bittide plokk. Ühekordne täpsus (32-bitine) kasutab 1 märgibitti, 8 eksponendibitti ja 23 mantissibitti; kahekordne täpsus (64-bitine), formaat peaaegu iga keele vaikimisi arvutüübi taga, kasutab 1 märgibitti, 11 eksponendibitti ja 52 mantissibitti. See tööriist võtab suvalise kümnendarvu, mille sisestad, kodeerib selle mõlemas laiuses, kasutades brauseri enda DataView/ArrayBuffer ujukoma kodeerijat – sedasama mehhanismi, millel su kood tegelikult jookseb – ja värvib iga biti vastavalt sellele, millisesse piirkonda see kuulub.
Kodeering ise järgib kolme sammu ja see tööriist käib nad kõik läbi, selle asemel et näidata ainult lõplikke bitte. Esiteks normaliseerimine: arv kirjutatakse kujule 1.mantiss × 2^eksponent, kus binaarpunkti ees on täpselt üks nullist erinev number (liiga väikesed arvud saavad selle asemel alanormaalse kohtlemise, ilma varjatud juhtiva 1-ta). Teiseks eksponendi nihe: kuna eksponendiväli peab salvestama nii positiivseid kui ka negatiivseid eksponente märgita arvuna, liidetakse enne välja binaarselt väljakirjutamist fikseeritud nihe (127 ühekordse täpsuse korral, 1023 kahekordse korral). Kolmandaks laiendatakse murruline mantiss bitt-biti haaval klassikalise „korruta kahega, võta täisosa järgmiseks bitiks, jäta jääk” meetodiga – korratakse, kuni mantissiväli on täis, mille järel ülejäänud bitid otsustavad, kas tulemus ümardatakse üles või alla (round-half-to-even, IEEE-754 vaikimisi).
Just seetõttu ei salvestata nii tavalist arvu nagu 0,1 täpselt. Binaarselt on 0,1 perioodiline murd (0,0001100110011…, igavesti), nii et ükski lõplik mantiss ei suuda seda täpselt hoida – see tuleb kusagil ümardada. Kodeeri 0,1 32-bitise ujukomaarvuna ja loe bitid tagasi, ning sa ei saa tagasi 0,1: saad täpselt 0,100000001490116119384765625. Kahekordsel täpsusel on 29 mantissibitti rohkem, nii et selle ümardusviga on palju väiksem, kuid see ei ole samuti null – 0,1 64-bitise kahekordse täpsusega on täpselt 0,1000000000000000055511151231257827021181583404541015625. See tööriist arvutab selle täpse salvestatud väärtuse suurtäisarvulise aritmeetikaga (ei mingeid ujukoma otseteid), nii et vahe selle vahel, mida sisestasid, ja selle vahel, mida riistvara tegelikult hoiab, ei ole kunagi peidetud ega lähendatud.
Eriväärtused saavad tavalise kodeeringu asemel täpsed reserveeritud bitimustrid: nullil ja negatiivsel nullil on kõik eksponendi ja mantissi bitid nullid (ainult märgibitt erineb), ±Lõpmatusel on kõik eksponendi bitid ühed ja mantiss null, ning NaN-il on kõik eksponendi bitid ühed ja vähemalt üks mantissibitt seatud. Kõik siin töötab kohapeal su brauseris – midagi, mida sisestad, ei laadita üles kuhugi –, mis teeb sellest turvalise koha tõelise intuitsiooni arendamiseks ujukomavigade suhtes: miks `0,1 + 0,2 !== 0,3` peaaegu igas programmeerimiskeeles, miks float32 tekstuurid graafikakoodis kaotavad täpsust, mida float64 ei kaotaks, ja miks finantskood peaks üldiselt binaarset ujukomat täielikult vältima.