Programavimas

Kintamojo taško aritmetika

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 rodiklis

Slankių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ų:

-5 formos
PasirašykiteMantissa„Radix“ rodiklis
-15010 -1
-1510 0
-10.510 1
-10.0510 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 rodiklis

JVM 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“:

Bitų „Java“ plūdės išdėstymas
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:

Specialios plūduriuojančios vertės
VertėPlūduriuojantys bitai (ženklas „eksponentas mantissa“)
+ Begalybė0 11111111 00000000000000000000000
-Begalybė1 11111111 00000000000000000000000
NaN1 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:

Normalizuotos plūduriuojančios vertės
VertėPlūduriuojantys bitai (ženklas „eksponentas mantissa“)Nešališkas eksponentas
Didžiausia teigiama (baigtinė) plūdė0 11111110 11111111111111111111111128
Didžiausia neigiama (baigtinė) plūdė1 11111110 11111111111111111111111128
Mažiausia normalizuota plūdė1 00000001 00000000000000000000000-125
Pi0 10000000 100100100001111110110112

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ę.

Denormalizuotos plūduriuojančios vertės
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 nulis0 00000000 00000000000000000000000
Neigiamas nulis1 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.