0

IEEE-754 ujuv visualiseerija

Vaadake täpselt, kuidas kümnendarvu salvestatakse IEEE-754 ujukina – märgibitid, eksponendibitid ja mantissibitid – ja miks selliseid numbreid nagu 0,1 täpselt ei salvestata.

Buy Me a Coffee at ko-fi.com
Töötlemine... 0%
Normaliseerimine
Eksponentnihke arvutamine
Laienevad mantissitükid
Valmis

Tulemus

Iga arvuti salvestatud ujukomaarv – JavaScripti number, C-ujuk, Pythoni ujuk – kodeeritakse IEEE 754-s samamoodi: üks märgibitt, eksponendibittide plokk ja mantissa (murru)bittide plokk. Üksiktäpsus (32-bitine) kasutab 1 märgibitti, 8 eksponendibitti ja 23 mantissibitti; topelttäpsus (64-bitine), peaaegu iga keele vaikenumbritüübi taga olev vorming, kasutab 1 märgibitti, 11 eksponendibitti ja 52 mantissibitti. See tööriist võtab suvalise kümnendarvu, mille sisestate, kodeerib selle kummagi laiusega, kasutades brauseri enda DataView/ArrayBuffer-ujukkodeerijat (sama masinat, millel teie kood tegelikult töötab) ja värvib iga biti selle piirkonna järgi, kuhu see kuulub.

Kodeerimine ise järgib kolme sammu ja see tööriist käib need kõik läbi, selle asemel et näidata ainult viimaseid bitte. Esiteks, normaliseerimine: arv kirjutatakse ümber kujul 1.mantissa × 2^ astendaja, kusjuures kahendpunkti ees on täpselt üks nullist erinev number (selleks liiga väikesed arvud saavad selle asemel alanormaalse käsitluse, ilma kaudse eesotsa 1ta). Teiseks, eksponendi kallutatus: kuna eksponendiväli peab salvestama nii positiivsed kui ka negatiivsed eksponendid märgita arvuna, lisatakse enne välja kahendarvuna väljakirjutamist fikseeritud nihe (127 ühekordse täpsuse korral, 1023 kahekordse täpsuse korral). Kolmandaks laiendatakse murdosa mantissi klassikalise meetodiga „korruta kahega, võta järgmiseks bitiks täisarv, jäta allesjäänu alles” – seda korratakse, kuni mantissi väli on täis, misjärel otsustavad allesjäänud bitid, kas tulemus ümardub üles või alla (poolist paarisväärtuseni, IEEE-754 vaikimisi).

See on täpselt põhjus, miks nii tavalist arvu nagu 0,1 täpselt ei salvestata. Kahendkoodis on 0,1 korduv murd (0,0001100110011…, igavesti), nii et ükski lõplik mantiss ei suuda seda täpselt hoida – see tuleb kuskil ümardada. Kodeerige 0.1 32-bitise ujukina ja lugege bitid tagasi ja te ei saa 0.1 tagasi: saate täpselt 0,100000001490116119384765625. Topelttäpsusel on töötamiseks veel 29 mantissibitti, seega on selle ümardamisviga palju väiksem, kuid see pole ka null – 0,1, kui 64-bitine topelt on täpselt 0,100000000000000005551115123125782702118154134156. See tööriist arvutab selle täpse salvestatud väärtuse suurte täisarvude aritmeetika abil (ilma ujukoma otseteedeta), nii et lünka sisestatu ja riistvara tegelikult säilitatava vahel ei peideta ega lähendata.

Eriväärtused saavad tavalise kodeeringu asemel täpsed reserveeritud bitimustrid: nullil ja negatiivsel nullil on täisnull-eksponent ja mantissibitid (erineb ainult märgibitt), ±Lõpmatuses on kõik üks eksponendibitid, mille mantiss on null, ja NaN-il on kõik üks eksponendibitid, millel on vähemalt üks mantissibiti komplekt. Kõik siin töötab teie brauseris lokaalselt – mitte midagi, mida te sisestate, ei laadita kuhugi üles –, mis teeb sellest turvalise koha ujukomavigade jaoks tõelise intuitsiooni loomiseks: miks 0,1 + 0,2 !== 0,3 peaaegu igas programmeerimiskeeles, miks float32 tekstuurid graafikakoodis kaotavad täpsuse, mida float64 ei sooviks, ja miks peaks ujukoma binaarne kood üldiselt vältima.