Sveiki atvykę į kitą Po gaubtu. Šiuo stulpeliu siekiama „Java“ kūrėjams pažvelgti į paslėptą grožį po jų vykdomomis „Java“ programomis. Šio mėnesio stulpelyje tęsiama praėjusį mėnesį pradėta „Java“ virtualiosios mašinos (JVM) baitų kodo instrukcijų rinkinio diskusija. Šiame straipsnyje apžvelgiama slankiojo kablelio aritmetika JVM ir aptariami bytecodes, atliekantys slankiojo kablelio aritmetines operacijas. Vėlesniuose straipsniuose bus aptariami kiti baitų kodų šeimos nariai.
Pagrindiniai slankieji taškai
JVM slankiojo kablelio atrama atitinka IEEE-754 1985 slankiojo kablelio standartą. Šis standartas apibrėžia 32 ir 64 bitų slankiojo kablelio skaičių formatą ir apibrėžia šių skaičių operacijas. JVM slankiojo kablelio aritmetika atliekama 32 bitų plūdėms ir 64 bitų dviguboms. Kiekvienam baitiniam kodui, kuris atlieka aritmetiką plūdėms, yra atitinkamas baitas, kuris tą pačią operaciją atlieka dvigubai.
Slankiojo kablelio skaičius turi keturias dalis - ženklą, mantisą, radiksą ir rodiklį. Ženklas yra 1 arba -1. Mantissa, visada teigiamas skaičius, turi reikšmingus slankiojo kablelio skaičiaus skaitmenis. Eksponentas rodo teigiamą arba neigiamą radikso galią, kuria mantissa ir ženklas turėtų būti padauginti. Keturi komponentai sujungiami taip, kad gautų slankiojo kablelio vertę:
ženklas * mantissa * radix rodiklisSlankiųjų kablelių skaičiai gali būti keleriopai pavaizduoti, nes bet kurio slankiojo kablelio skaičiaus mantisą visada galima padauginti iš tam tikros radikso galios ir pakeisti rodiklį, kad gautumėte pradinį skaičių. Pvz., Skaičius -5 gali būti vienodai parodytas bet kuria iš šių radix 10 formų:
Pasirašykite | Mantissa | „Radix“ rodiklis |
---|---|---|
-1 | 50 | 10 -1 |
-1 | 5 | 10 0 |
-1 | 0.5 | 10 1 |
-1 | 0.05 | 10 2 |
Kiekvienam slankiojo kablelio skaičiui nurodoma viena reprezentacija normalizuotas. Slankiojo kablelio skaičius yra normalizuojamas, jei jo mantissa yra diapazone, apibrėžtame tokiu ryšiu:
1 / radiksas <= mantissa <Normalizuoto 10 radikso slankiojo kablelio skaičiaus dešimtainis taškas yra tiesiai į kairę nuo pirmo nulio skaičiaus, esančio mantisoje. Normalizuotas slankiojo kablelio atvaizdas -5 yra -1 * 0,5 * 10 1. Kitaip tariant, normalizuoto slankiojo kablelio skaičiaus mantisoje nėra dešimtainio kablelio kairėje nei nulis skaitmenų, o nulio nėra tik nulis. dešimtainio kablelio dešinė. Teigiama, kad bet koks slankiojo kablelio skaičius, kuris netinka šiai kategorijai denormalizuota. Atkreipkite dėmesį, kad skaičius nulis neturi normalizuoto atvaizdavimo, nes jis neturi skaičiaus, kuris nėra nulis, tik dešimtainio kablelio dešinėje. - Kodėl reikia normalizuoti? yra įprastas šauktukas tarp nulių.
JVM slankiųjų taškų skaičiai naudoja dviejų radiksą. Todėl JVM slankiųjų kablelių skaičiai yra tokios formos:
ženklas * mantissa * 2 rodiklisJVM slankiojo kablelio skaičiaus mantissa išreiškiama dvejetainiu skaičiumi. Normalizuotos mantisos dvejetainis taškas (dviejų bazinių dešimtainio taško ekvivalentas) yra kairėje nuo reikšmingiausio ne nulio skaičiaus. Kadangi dvejetainių skaičių sistema turi tik du skaitmenis - nulį ir vieną - svarbiausias normalizuotos mantisos skaitmuo visada yra vienas.
Reikšmingiausias plūdės ar dvigubo elemento dydis yra jo ženklas. Mantissa užima 23 mažiausiai reikšmingus plūdės ir 52 mažiausiai reikšmingus dvigubos bitus. Eksponentas, 8 bitai plūdėje ir 11 bitų dviguboje, sėdi tarp ženklo ir mantisos. Plūdės formatas rodomas žemiau. Ženklo bitai rodomi kaip „s“, eksponentų bitai rodomi kaip „e“, o mantisos bitai - „m“:
s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm |
Nulio ženklo bitai rodo teigiamą skaičių, o vieno ženklo bitai - neigiamą skaičių. Mantissa visada aiškinama kaip teigiamas dviejų skaičių skaičius. Tai nėra dviejų papildų skaičius. Jei ženklo bitas yra vienas, slankiojo kablelio reikšmė yra neigiama, tačiau mantissa vis tiek aiškinama kaip teigiamas skaičius, kurį reikia padauginti iš -1.
Eksponento laukas aiškinamas vienu iš trijų būdų. Visų skaičių rodiklis rodo, kad slankiojo kablelio skaičius turi vieną iš specialiųjų pliuso arba minuso begalybės verčių arba „ne skaičių“ (NaN). NaN yra tam tikrų operacijų rezultatas, pavyzdžiui, nulio padalijimas iš nulio. Visų nulių rodiklis rodo denormalizuotą slankiojo kablelio skaičių. Bet kuris kitas rodiklis nurodo normalizuotą slankiojo kablelio skaičių.
Mantisoje yra vienas papildomas tikslumas, viršijantis tuos, kurie atsiranda mantisos gabaliukuose. Tik 23 bitų užimančios plūdės mantisos tikslumas yra 24 bitai. 52 bitų užimančios dvigubos mantisos tikslumas yra 53 bitai. Svarbiausias mantisos bitas yra nuspėjamas, todėl nėra įtrauktas, nes slankiųjų kablelių skaičių rodiklis JVM rodo, ar skaičius yra normalizuotas, ar ne. Jei rodiklis yra visas nulis, slankiojo kablelio skaičius denormalizuojamas ir žinoma, kad reikšmingiausias mantisos bitas yra nulis. Priešingu atveju slankiojo kablelio skaičius yra normalizuojamas ir žinoma, kad reikšmingiausias mantisos bitas yra vienas.
Dėl bet kokių slankiojo kablelio operacijų JVM nemeta jokių išimčių. Specialios vertės, tokios kaip teigiama ir neigiama begalybė arba NaN, grąžinamos dėl įtartinų operacijų, tokių kaip padalijimas į nulį. Visų jų rodiklis rodo specialią slankiojo kablelio vertę. Visų, turinčių mantisą, kurios bitai visi lygūs nuliui, rodiklis rodo begalybę. Begalybės ženklą rodo ženklo bitai. Visų, turinčių bet kurią kitą mantisą, eksponentas aiškinamas reiškia „ne skaičių“ (NaN). JVM visada gamina tą pačią mantisą NaN, kuri yra visi nuliai, išskyrus svarbiausią mantisos bitą, kuris rodomas skaičiuje. Toliau pateikiamos šios plūdės vertės:
Vertė | Plūduriuojantys bitai (ženklas „eksponentas mantissa“) |
---|---|
+ Begalybė | 0 11111111 00000000000000000000000 |
-Begalybė | 1 11111111 00000000000000000000000 |
NaN | 1 11111111 10000000000000000000000 |
Eksponentai, kurie nėra nei visi, nei visi nuliai, rodo dviejų galią, padauginantį normalizuotą mantisą. Dviejų galią galima nustatyti aiškinant eksponentų bitus kaip teigiamą skaičių, o tada iš teigiamo skaičiaus atimant šališkumą. Plūdės nuokrypis yra 126. Dvigubai šališkumas yra 1023. Pvz., 00000001 plūdės eksponento laukas duoda galią, atimdamas šališkumą (126) iš rodiklio lauko, interpretuojamo kaip teigiamas sveikasis skaičius. (1). Todėl dviejų galia yra 1 - 126, tai yra -125. Tai yra mažiausia įmanoma plūdės galia iš dviejų. Kitu kraštutinumu, 11111110 eksponento laukas duoda dviejų galių (254 - 126) arba 128 galią. Skaičius 128 yra didžiausia dviejų plūdės galia. Keli normalizuotų plūdžių pavyzdžiai pateikti šioje lentelėje:
Vertė | Plūduriuojantys bitai (ženklas „eksponentas mantissa“) | Nešališkas eksponentas |
---|---|---|
Didžiausia teigiama (baigtinė) plūdė | 0 11111110 11111111111111111111111 | 128 |
Didžiausia neigiama (baigtinė) plūdė | 1 11111110 11111111111111111111111 | 128 |
Mažiausia normalizuota plūdė | 1 00000001 00000000000000000000000 | -125 |
Pi | 0 10000000 10010010000111111011011 | 2 |
Visų nulių rodiklis rodo, kad mantissa yra denormalizuota, o tai reiškia, kad nenurodytas priekinis bitas yra nulis, o ne vienas. Dviejų galia šiuo atveju yra tokia pati kaip mažiausia dviejų galia, kurią turi normalizuota mantissa. Plūdei tai yra -125. Tai reiškia, kad normalizuotų mantisų, padaugintų iš dviejų, pakeltų iki -125 galios, eksponento laukas yra 00000001, o denormalizuotų mantisų, padaugintų iš dviejų, pakeltų iki -125 galios, eksponento laukas yra 00000000. Leidimas denormalizuotiems skaičiams apačioje rodiklių diapazono pabaiga palaiko laipsnišką nepakankamumą. Jei normalizuotam skaičiui atspindėti būtų naudojamas žemiausias rodiklis, didesniems skaičiams būtų nutekėjimas iki nulio. Kitaip tariant, paliekant mažiausią rodiklį denormalizuotiems skaičiams, galima pateikti mažesnius skaičius. Mažesni denormalizuoti skaičiai turi mažiau tikslumo bitų nei normalizuoti skaičiai, tačiau tai yra geriau nei potvynis iki nulio, kai tik rodiklis pasiekia mažiausią normalizuotą vertę.
Vertė | Plūduriuojantys bitai (ženklas „eksponentas mantissa“) |
---|---|
Mažiausia teigiama (ne nulinė) plūdė | 0 00000000 00000000000000000000001 |
Mažiausia neigiama (ne nulio) plūdė | 1 00000000 00000000000000000000001 |
Didžiausia denormalizuota plūdė | 1 00000000 11111111111111111111111 |
Teigiamas nulis | 0 00000000 00000000000000000000000 |
Neigiamas nulis | 1 00000000 00000000000000000000000 |
Atidengta plūdė
„Java“ plūdė atskleidžia savo vidinę prigimtį Žemiau esanti programėlė leidžia žaisti su slankiojo kablelio formatu. Plūdės vertė rodoma keliais formatais. Dviejų radiksų mokslinio užrašymo formatas rodo mantisą ir eksponentą dešimties bazėje. Prieš rodant faktinę mantisą padauginama iš 2 24, gaunant vientisą skaičių, o nešališkas rodiklis sumažinamas 24. Po to tiek vientisa mantisa, tiek eksponentas lengvai konvertuojami į dešimtį ir rodomi.