Tervetuloa toiseen erään Konepellin alle. Tämän sarakkeen tarkoituksena on antaa Java-kehittäjille oivallus piilotetusta kauneudesta heidän käynnissä olevien Java-ohjelmiensa alla. Tämän kuukauden sarake jatkaa viime kuussa aloitettua keskustelua Java-virtuaalikoneen (JVM) tavukoodikäskyjoukosta. Tässä artikkelissa tarkastellaan liukulukujen aritmeettisuutta JVM: ssä ja käsitellään tavukoodeja, jotka suorittavat liukulukuaritmeettisia operaatioita. Myöhemmissä artikkeleissa keskustellaan muista tavukoodiperheen jäsenistä.
Tärkeimmät kelluvat pisteet
JVM: n liukulukutuki noudattaa IEEE-754 1985 -liukulukustandardia. Tämä standardi määrittelee 32- ja 64-bittisten liukulukujen muodon ja määrittelee operaatiot näillä numeroilla. JVM: ssä liukulukulaskenta suoritetaan 32-bittisillä kelluilla ja 64-bittisillä tuplailla. Jokaiselle tavukoodille, joka suorittaa aritmeettisen uimurilla, on vastaava tavukoodi, joka suorittaa saman toiminnon kaksoiskappaleilla.
Liukuluvun numerossa on neljä osaa - merkki, mantissa, radix ja eksponentti. Merkki on joko 1 tai -1. Mantissa, aina positiivinen luku, sisältää liukuluvun merkittävät numerot. Eksponentti osoittaa radiksin positiivisen tai negatiivisen voiman, jolla mantissa ja merkki tulisi kertoa. Neljä komponenttia yhdistetään seuraavasti liukulukuarvon saamiseksi:
merkki * mantissa * radix-eksponenttiLiukulukuilla on useita esityksiä, koska aina voidaan kertoa minkä tahansa liukuluvun mantissa jokin radiksin teho ja muuttaa eksponentti alkuperäisen luvun saamiseksi. Esimerkiksi lukua -5 voidaan edustaa tasaisesti millä tahansa seuraavista radiksin 10 muodoista:
Merkki | Mantissa | Radix-eksponentti |
---|---|---|
-1 | 50 | 10 -1 |
-1 | 5 | 10 0 |
-1 | 0.5 | 10 1 |
-1 | 0.05 | 10 2 |
Jokaiselle liukuluvun numerolle on yksi esitys, jonka sanotaan olevan normalisoitu. Liukuluku normalisoidaan, jos sen mantissa on seuraavan suhteen määrittelemällä alueella:
1 / radix <= mantissa <Normisoidun radix 10 -liukuluvun desimaalipiste on vain mantissan ensimmäisen nollasta poikkeavan numeron vasemmalla puolella. -5: n normalisoitu liukuluvun esitys on -1 * 0,5 * 10 1. Toisin sanoen normalisoidun liukuluvun mantissassa ei ole nollasta poikkeavia numeroita desimaalipisteen vasemmalla puolella ja ei-nollanumero vain desimaalipilkun oikealla puolella. Kaikkien liukulukujen, jotka eivät sovi tähän luokkaan, sanotaan olevan denormalisoitu. Huomaa, että luvulla nolla ei ole normalisoitua esitystä, koska sillä ei ole nollan ulkopuolista numeroa, jonka laittaa vain desimaalipilkun oikealle puolelle. "Miksi normalisoida?" on yleinen huutomerkki nollien joukossa.
JVM: n liukulukuluvuissa käytetään kahden radiksia. JVM: n liukulukuluvuilla on siis seuraava muoto:
merkki * mantissa * 2 eksponenttiLiukulukuluvun mantissa JVM: ssä ilmaistaan binäärilukuna. Normalisoidun mantissan binääripiste (kahden peruspisteen ekvivalentti) on merkittävimmän nollan ulkopuolisen numeron vasemmalla puolella. Koska binääriluvujärjestelmässä on vain kaksi numeroa - nolla ja yksi -, normalisoidun mantissan merkittävin numero on aina yksi.
Merkittävin kelluva tai kaksinkertainen bitti on sen merkkibitti. Mantissa vie kellukan 23 vähiten merkitsevää bittiä ja kaksoisosan 52 vähiten merkitsevää bittiä. Eksponentti, 8 bittiä kellukkeessa ja 11 bittiä kaksoiskappaleessa, istuu merkin ja mantissan välissä. Uimurin muoto on esitetty alla. Merkkibitti näytetään "s": nä, eksponenttibitit näytetään "e": nä ja mantissa-bitit "m":
s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm |
Nollan merkkibitti osoittaa positiivista lukua ja yhden merkkibitti negatiivista. Mantissa tulkitaan aina positiivisena kahden perusnumerona. Se ei ole kaksikommenttinen numero. Jos merkkibitti on yksi, liukuluku on negatiivinen, mutta mantissa tulkitaan silti positiivisena lukuna, joka on kerrottava -1: llä.
Eksponenttikenttä tulkitaan yhdellä kolmesta tavasta. Kaikkien eksponentti osoittaa, että liukuluvun numerolla on yksi erikoisarvoista plus tai miinus ääretön tai "ei luku" (NaN). NaN on seurausta tietyistä toiminnoista, kuten nollan jakamisesta nollalla. Kaikkien nollien eksponentti ilmaisee denormalisoidun liukuluvun. Mikä tahansa muu eksponentti ilmoittaa normalisoidun liukuluvun.
Mantissa sisältää yhden ylimääräisen tarkkuuden pidemmälle kuin ne, jotka näkyvät mantissa-paloissa. Uimurin mantissalla, joka vie vain 23 bittiä, on 24 bitin tarkkuus. Tuplan mantissalla, joka vie 52 bittiä, on 53 bitin tarkkuus. Merkittävin mantissabitti on ennustettavissa, eikä sitä siksi sisällytetä, koska liukulukujen eksponentti JVM: ssä osoittaa, onko luku normalisoitu vai ei. Jos eksponentti on kaikki nollat, kelluva luku denormalisoidaan ja mantissan merkittävimmän bitin tiedetään olevan nolla. Muussa tapauksessa liukuluku normalisoidaan ja mantissan merkittävimmän bitin tiedetään olevan yksi.
JVM ei aiheuta poikkeuksia minkään liukulukuoperaation seurauksena. Erityisarvot, kuten positiivinen ja negatiivinen ääretön tai NaN, palautetaan epäilyttävien toimintojen, kuten nollalla jakamisen, seurauksena. Kaikkien eksponentti osoittaa erityisen liukulukuarvon. Kaikkien eksponentti, jolla on mantissa, jonka bitit ovat kaikki nollia, osoittaa ääretöntä. Äärettömyyden merkki ilmaistaan merkkibitillä. Kaikkien muiden kanssa esiintyvän eksponentin tulkitaan tarkoittavan "ei lukua" (NaN). JVM tuottaa aina saman mantissan NaN: lle, joka on kaikki nollat lukuun ottamatta merkittävintä mantissabittiä. Nämä arvot näytetään alla olevalle uimurille:
Arvo | Kelluvat bitit (merkki eksponentti Mantissa) |
---|---|
+ Ääretön | 0 11111111 00000000000000000000000 |
- Äärettömyys | 1 11111111 00000000000000000000000 |
NaN | 1 11111111 10000000000000000000000 |
Eksponentit, jotka eivät ole kaikki ykkösiä tai kaikkia nollia, osoittavat kahden voiman, jolla normalisoitu mantissa voidaan kertoa. Kahden teho voidaan määrittää tulkitsemalla eksponenttibitit positiivisena lukuna ja vähentämällä sitten esijännitys positiivisesta luvusta. Kellukkeella esijännitys on 126. Kaksinkertaisen kohdalla esijännitys on 1023. Esimerkiksi kelluvan kentän 00000001 eksponenttikenttä tuottaa kahden tehon vähentämällä ennakkoarvon (126) positiivisena kokonaislukuna tulkittavasta eksponenttikentästä. (1). Siksi kahden teho on 1 - 126, mikä on -125. Tämä on kahden pienin mahdollinen voima kellukkeelle. Toisessa ääripäässä eksponenttikenttä 11111110 tuottaa kahden (254 - 126) tai 128 tehon. Luku 128 on suurin kelluvan käytettävissä oleva teho kahdesta. Seuraavassa taulukossa on useita esimerkkejä normalisoiduista uimureista:
Arvo | Kelluvat bitit (merkki eksponentti Mantissa) | Puolueeton eksponentti |
---|---|---|
Suurin positiivinen (äärellinen) kelluva | 0 11111110 11111111111111111111111 | 128 |
Suurin negatiivinen (äärellinen) kelluva | 1 11111110 11111111111111111111111 | 128 |
Pienin normalisoitu uimuri | 1 00000001 00000000000000000000000 | -125 |
Pi | 0 10000000 10010010000111111011011 | 2 |
Kaikkien nollien eksponentti osoittaa, että mantissa on denormalisoitu, mikä tarkoittaa, että ilmoittamaton alkubitti on nolla yhden sijasta. Kahden teho on tässä tapauksessa sama kuin normalisoidulle mantissalle käytettävissä oleva kahden alin teho. Kellukkeelle tämä on -125. Tämä tarkoittaa, että normalisoiduilla mantissoilla kerrottuna kahdella, joka on korotettu arvoon -125, eksponenttikenttä on 00000001, kun taas denormalisoiduilla mantissoilla, jotka on kerrottu kahdella, jotka on korotettu arvoon -125, on eksponenttikenttä 00000000. Denormalisoitujen numeroiden alaraja on alareunassa. eksponenttialueen loppu tukee asteittaista alivuotoa. Jos alimman eksponentin sijasta käytettäisiin normalisoitua lukua, suurempien lukujen kohdalla tapahtuisi alivirta nollaan. Toisin sanoen pienimmän eksponentin jättäminen denormalisoiduille numeroille antaa mahdollisuuden edustaa pienempiä lukuja. Pienemmillä denormalisoiduilla numeroilla on vähemmän tarkkuusbittejä kuin normalisoiduilla numeroilla, mutta tämä on parempi kuin alivirta nollaan heti, kun eksponentti saavuttaa vähimmäis normalisoidun arvon.
Arvo | Kelluvat bitit (merkki eksponentti Mantissa) |
---|---|
Pienin positiivinen (ei nolla) kelluva | 0 00000000 00000000000000000000001 |
Pienin negatiivinen (ei nolla) kelluva | 1 00000000 00000000000000000000001 |
Suurin denormalisoitu uimuri | 1 00000000 11111111111111111111111 |
Positiivinen nolla | 0 00000000 00000000000000000000000 |
Negatiivinen nolla | 1 00000000 00000000000000000000000 |
Paljasta kellua
Java-uimuri paljastaa sen sisäisen luonteen. Alla olevan sovelman avulla voit leikkiä liukulukuformaatilla. Uimurin arvo näytetään useissa muodoissa. Radix kaksi tieteellistä merkintämuotoa näyttää mantissan ja eksponentin peruskymmenessä. Ennen näyttämistä todellinen mantissa kerrotaan 2 24: llä, mikä antaa kokonaisluvun, ja puolueeton eksponentti vähennetään 24. Sekä integraali mantissa että eksponentti muunnetaan sitten helposti kymmeneksi ja näytetään.