IEEE-754 pludiņa vizualizētājs
Uzziniet, kā tieši decimālskaitlis tiek saglabāts kā IEEE-754 pludiņš — zīmes biti, eksponenta biti un mantisas biti — un kāpēc tādi skaitļi kā 0,1 netiek saglabāti precīzi.
Rezultāts
Katrs datorā saglabātais peldošā komata skaitlis — JavaScript skaitlis, C pludiņš, Python float — saskaņā ar IEEE 754 tiek kodēts vienādi: viens zīmes bits, eksponenta bitu bloks un mantisas (daļdaļas) bitu bloks. Viena precizitāte (32 biti) izmanto 1 zīmes bitu, 8 eksponenta bitus un 23 mantisas bitus; dubultā precizitāte (64 biti), gandrīz katras valodas noklusējuma skaitļu veida formāts, izmanto 1 zīmes bitu, 11 eksponenta bitus un 52 mantisas bitus. Šis rīks ņem jebkuru jūsu ievadīto decimālskaitli, kodē to jebkurā platumā, izmantojot paša pārlūkprogrammas DataView/ArrayBuffer pludiņa kodētāju — to pašu iekārtu, kurā faktiski darbojas jūsu kods, un krāso katru bitu atkarībā no reģiona, kuram tas pieder.
Pati kodēšana notiek trīs soļos, un šis rīks veic visas tās, nevis tikai parāda pēdējos bitus. Pirmkārt, normalizācija: skaitlis tiek pārrakstīts kā 1.mantisa × 2^ eksponents, ar tieši vienu ciparu, kas nav nulles ciparu pirms binārā punkta (skaitļi, kas ir pārāk mazi, tā vietā saņem subnormālu apstrādi, bez netieša sākuma 1). Otrkārt, eksponenta novirze: tā kā eksponenta laukā ir jāsaglabā gan pozitīvie, gan negatīvie eksponenti kā neparakstīts skaitlis, pirms lauka izrakstīšanas binārā veidā tiek pievienota fiksēta novirze (127 vienai precizitātei, 1023 dubultai). Treškārt, daļēja mantisa tiek paplašināta pa bitam, izmantojot klasisko metodi “reizināt ar divi, ņemt veselo skaitļu daļu kā nākamo bitu, paturēt atlikušo daļu” — atkārto, līdz mantisas lauks ir pilns, un tad atlikušie biti izlemj, vai rezultāts tiek noapaļots uz augšu vai uz leju (noapaļots uz pusi līdz pat, IEEE-754 noklusējums).
Tieši tāpēc tāds parasts skaitlis kā 0,1 netiek precīzi saglabāts. Binārajā valodā 0,1 ir atkārtojoša daļa (0,0001100110011…, uz visiem laikiem), tāpēc neviena galīga mantisa to nevar precīzi noturēt — tā kaut kur ir jānoapaļo. Kodējiet 0.1 kā 32 bitu pludiņu un nolasiet bitus atpakaļ, un jūs nesaņemat atpakaļ 0.1: jūs saņemat tieši 0.100000001490116119384765625. Divkāršajai precizitātei ir vēl 29 mantisas biti, tāpēc tā noapaļošanas kļūda ir daudz mazāka, taču tā arī nav nulle — 0,1, jo 64 bitu dubultā vērtība ir tieši 0,10000000000000000555111512312578270211815410456. Šis rīks aprēķina precīzu saglabāto vērtību ar lielu veselu skaitļu aritmētiku (bez peldošā komata īsceļiem), tāpēc atstarpe starp ievadīto un to, ko aparatūra faktiski saglabā, nekad netiek paslēpta vai tuvināta.
Īpašās vērtības iegūst precīzus, rezervētus bitu modeļus, nevis parastu kodējumu: nullei un negatīvajai nullei ir nulles eksponenta biti un mantisas biti (atšķiras tikai zīmes bits), ± Infinity ir viss viens eksponenta bits ar nulles mantisu, un NaN ir viss viens eksponenta biti ar vismaz vienu mantisas bitu kopu. Viss šeit darbojas lokāli jūsu pārlūkprogrammā — nekas, ko ievadāt, nekur netiek augšupielādēts — tas padara šo vietu par drošu vietu, kur veidot reālu intuīciju peldošā komata kļūdām: kāpēc `0,1 + 0,2 !== 0,3` gandrīz visās programmēšanas valodās, kāpēc float32 tekstūras grafikas kodā zaudē precizitāti, ko float64 nevarētu izvairīties, un kāpēc parasti vajadzētu izvairīties no peldošā punkta binārajiem kodiem.