===== Negatív és lebegőpontos számok ábrázolása ===== Egy mérési eredmény lehet negatív, például −5 °C, és lehet tört érték, például 13,25 mm. A számítógép memóriájában azonban csak bitek, vagyis nullák és egyesek szerepelnek. Hogyan jelöljük ezekkel a mínuszjelet és a törtrészt? Ehhez meg kell állapodnunk a bitek értelmezésében. Először a negatív egész számok tárolását vizsgáljuk meg, majd a törtekből kiindulva eljutunk a lebegőpontos számábrázolásig és az **IEEE 754** szabvány szerinti tárolásig. ==== 1. Kiindulás: mit jelent egy bitsorozat? ==== A kettes számrendszerben a helyi értékek jobbról balra kétszereződnek: 1, 2, 4, 8, 16 és így tovább. Egy bit helyén álló 1 azt jelenti, hogy az adott helyi értéket hozzáadjuk a számhoz; a 0 azt, hogy nem adjuk hozzá. Például a ''00001101'' bitsorozat értéke: ^ Helyi érték ^ 128 ^ 64 ^ 32 ^ 16 ^ 8 ^ 4 ^ 2 ^ 1 ^ | Bit | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | A szám tehát **8 + 4 + 1 = 13**. Nyolc bit együtt egy **bájt**. Nyolc bitből 256 különböző bitsorozat készíthető. Ha mindegyiket nemnegatív egész számként értelmezzük, 0-tól 255-ig tudunk számokat ábrázolni. Ezt nevezzük **előjel nélküli egész számábrázolásnak**. Ha negatív számokat is szeretnénk tárolni, akkor ugyanezt a 256 bitsorozatot kell másképpen felosztanunk. **A bitsorozat önmagában nem mondja meg, hogyan kell értelmezni.** Tudnunk kell, milyen számábrázolási szabály tartozik hozzá. ==== 2. Első ötlet: külön bit jelölje az előjelet ==== Kézenfekvő megoldás, hogy az első bit az előjelet adja meg, a többi pedig a szám abszolút értékét, vagyis az előjel nélküli nagyságát. Állapodjunk meg abban, hogy az első bit 0 esetén pozitív, 1 esetén negatív előjelet jelent. Nyolc bitből így egy az előjelé, hét pedig a nagyságé: ^ Szám ^ Előjelbit ^ A nagyság hét biten ^ Teljes bitsorozat ^ | +5 | 0 | ''0000101'' | ''00000101'' | | −5 | 1 | ''0000101'' | ''10000101'' | Ezt **előjeles abszolútértékes ábrázolásnak** nevezzük. Könnyű megérteni, de az egész számokkal végzett műveleteknél kényelmetlen: * A nullának két alakja van: ''00000000'' és ''10000000'', azaz +0 és −0. * A bitsorozatok közönséges bináris összeadása önmagában nem adja meg helyesen az előjeles összeget. Például +5 és −5 matematikai összege 0. A fenti két bitsorozat szokásos bináris összeadása viszont ''10001010'', ami ebben az ábrázolásban −10 lenne. Az egész számokhoz ezért általában más megoldást használunk: a **kettes komplemens ábrázolást**. ==== 3. Kettes komplemens ==== Olyan bitsorozatot keresünk −5 számára, amelyet +5 bitsorozatához hozzáadva az alsó nyolc biten nullát kapunk. Nyolc biten legfeljebb 255 ábrázolható előjel nélkül. A következő szám, 256, már kilenc bitet igényel: ''100000000''. Ha egy nyolcbites eredményből csak az alsó nyolc bitet tartjuk meg, ebből ''00000000'' marad. Melyik nemnegatív számmal kell az 5-öt kiegészíteni 256-ra? A válasz: **256 − 5 = 251**. Ezért nyolcbites kettes komplemensben a −5 tárolt bitmintája megegyezik az előjel nélkül 251-et jelentő bitmintával: **11111011**. === Hogyan állítjuk elő a negatív szám bitmintáját? === Az eljárás két egyszerű lépésből áll, de **előtte rögzíteni kell a bitszámot**. Most nyolc bittel dolgozunk. - Felírjuk a pozitív számot nyolc biten. - Minden bitet megfordítunk: a 0-ból 1, az 1-ből 0 lesz. - Az eredményhez hozzáadunk 1-et, és nyolc bitet tartunk meg. **Példa: −5 előállítása.** +5 nyolc biten: 00000101 Bitek megfordítása: 11111010 Egy hozzáadása: 11111011 Az eredmény tehát **−5 = 11111011** nyolcbites kettes komplemensben. Miért működik a megfordítás és az egy hozzáadása? A nyolc egyesből álló szám értéke 255. Egy pozitív x szám bitjeinek megfordítása 255 − x-et ad, az ezt követő +1 pedig 256 − x-et. Pontosan ezt kerestük. === Hogyan olvassuk vissza a számot? === Nyolcbites kettes komplemensben az első bit helyi értéke **−128**, a többi bité változatlanul pozitív: ^ Helyi érték ^ −128 ^ 64 ^ 32 ^ 16 ^ 8 ^ 4 ^ 2 ^ 1 ^ | −5 bitmintája | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | Az érték: **−128 + 64 + 32 + 16 + 8 + 2 + 1 = −5**. Ezért az első bit valóban jelzi az előjelet: 0 esetén nemnegatív, 1 esetén negatív a szám. De **nem egyszerűen külön mínuszjel a többi bit elé**. A maradék hét bit itt nem a negatív szám abszolút értékét tárolja. Másik visszaolvasási módszer: az ''11111011'' előjel nélkül 251. Mivel az első bit 1, kivonunk 256-ot: **251 − 256 = −5**. ==== 4. Miért hasznos a kettes komplemens? ==== A pozitív és negatív számok bitmintáit ugyanazzal a bináris összeadással kezelhetjük. Az összeadásban 1 + 1 eredménye 0 az adott helyen, és 1-et továbbviszünk a következő helyi értékre. Ezt **átvitelnek** nevezzük. Vizsgáljuk meg az 5 + (−5) összeget: 00000101 +5 + 11111011 -5 ---------- 1 00000000 A bal oldali kilencedik bit nem fér bele a nyolcbites eredménybe. Az alsó nyolc bit ''00000000'', vagyis **0**, ahogyan vártuk. A kivonás is összeadássá alakítható: **7 − 5 = 7 + (−5)**. 00000111 +7 + 11111011 -5 ---------- 1 00000010 Az alsó nyolc bit értéke **2**. //Fontos:// A helyes előjeles eredményhez az is szükséges, hogy a matematikai eredmény beleférjen az adott bitszám értéktartományába. A kilencedik bit elhagyása önmagában nem oldja meg a túl nagy eredmények problémáját. ==== 5. Mekkora számok férnek el? ==== Nyolcbites kettes komplemensben: * a legnagyobb pozitív érték ''01111111'', vagyis **127**; * a legkisebb érték ''10000000'', vagyis **−128**; * a nulla egyetlen alakja ''00000000''. A tartomány azért nem szimmetrikus, mert az első bit 0-val kezdődő 128 lehetősége közé a nulla is beletartozik: 0–127. Az 1-gyel kezdődő 128 lehetőség a −128 és −1 közötti számoké. ^ Bitszám ^ Előjel nélküli egész ^ Kettes komplemens egész ^ | 8 | 0 … 255 | −128 … 127 | | 16 | 0 … 65 535 | −32 768 … 32 767 | | 32 | 0 … 4 294 967 295 | −2 147 483 648 … 2 147 483 647 | Általánosan n bit esetén a kettes komplemens tartománya **−2n−1 … 2n−1 − 1**. A felső index hatványozást jelent. Ugyanaz a bitsorozat eltérő szabállyal mást jelent: ^ Bitsorozat ^ Előjel nélkül ^ Kettes komplemens szerint ^ | ''01111111'' | 127 | 127 | | ''10000000'' | 128 | −128 | | ''11111111'' | 255 | −1 | A −128 pozitív párja, +128 nem fér el nyolcbites kettes komplemensben. Ezért a legkisebb negatív érték előjelének megfordítása is túlcsordulhat. === Mi történik, ha több bitet használunk? === Ha egy kettes komplemens számot változatlan értékkel több bitre bővítünk, az új bal oldali biteket a régi első bit értékével töltjük ki. Ezt **előjelkiterjesztésnek** nevezzük. ^ Szám ^ Nyolc biten ^ Tizenhat biten ^ | +5 | ''00000101'' | ''00000000 00000101'' | | −5 | ''11111011'' | ''11111111 11111011'' | A szóköz csak az olvashatóságot segíti. Negatív szám elé tehát nem nullákat írunk, mert az megváltoztatná az értékét. ==== 6. Hogyan írunk fel törteket kettes számrendszerben? ==== Tízes számrendszerben a vessző utáni helyi értékek: egy tized, egy század, egy ezred. Kettes számrendszerben ugyanígy folytatódik a helyiérték-rendszer, de minden új helyen kettővel osztunk: ^ Hely ^ A vessző előtt ^ Első törtjegy ^ Második törtjegy ^ Harmadik törtjegy ^ Negyedik törtjegy ^ | Helyi érték | 1 | 1/2 | 1/4 | 1/8 | 1/16 | | Tízes számrendszerben | 1 | 0,5 | 0,25 | 0,125 | 0,0625 | Például a bináris **0,101** értéke: **1 × 1/2 + 0 × 1/4 + 1 × 1/8 = 0,625**. A következőkben a szám mögötti alsó 2 a kettes, az alsó 10 a tízes számrendszert jelöli. Így az előző összefüggés: **0,1012 = 0,62510**. Ez nem azonos a tízes számrendszerbeli 0,101-gyel. A vessző mindkét esetben az egész és a tört részt választja el, de a helyi értékek különböznek. === Példa: 13,25 felírása binárisan === Az egész részt és a tört részt külön vizsgáljuk: * 13 = 8 + 4 + 1, ezért az egész rész ''1101''. * 0,25 = 1/4, ezért a tört rész ''01''. Tehát **13,2510 = 1101,012**. Ellenőrzés: 8 + 4 + 1 + 1/4 = 13,25. === Általános módszer: a törtrész szorzása kettővel === A törtjegyeket ismételt kettővel szorzással is meghatározhatjuk. Minden lépésben felírjuk a szorzat egész részét, majd a következő lépésben csak a megmaradt törtrésszel dolgozunk. Például 0,625 esetén: ^ Lépés ^ Szorzás ^ Következő bináris jegy ^ Továbbvitt törtrész ^ | 1. | 0,625 × 2 = 1,25 | 1 | 0,25 | | 2. | 0,25 × 2 = 0,5 | 0 | 0,5 | | 3. | 0,5 × 2 = 1,0 | 1 | 0 | A jegyeket keletkezésük sorrendjében olvassuk: **0,1012**. A maradék nulla lett, ezért a felírás véget ért. ==== 7. Hol tároljuk a vesszőt? ==== A memóriában nincs a bitek közé rajzolt vessző. A helyét is értelmezési szabállyal kell megadnunk. Az egyik lehetőség, hogy előre rögzítjük, hány bit tartozik a törtrészhez. Ezt **fixpontos számábrázolásnak** nevezzük. Például használjunk nyolc előjel nélküli bitet, és állapodjunk meg abban, hogy az utolsó négy bit a törtrész. A tárolt ''00110100'' bitmintát ilyenkor ''0011,0100'' alakban értelmezzük: **2 + 1 + 1/4 = 3,25**. Ugyanez megfogalmazható úgy is, hogy a tárolt egész szám 52, és annak értékét 16-tal osztjuk: **52/16 = 3,25**. Ebben az egyszerű formátumban két szomszédos szám távolsága mindig 1/16 = 0,0625. A legnagyobb szám 255/16 = 15,9375. Több törtbit finomabb felbontást adna, de ugyanennyi összes bit mellett kisebb egész rész férne el. **A fixpontos ábrázolás állandó lépésközt használ.** Ez hasznos lehet, ha a mérési tartomány és a szükséges felbontás előre ismert. Mi történjen azonban, ha nagyon kicsi és nagyon nagy számokkal is szeretnénk dolgozni? ==== 8. A lebegőpontos ábrázolás alapötlete ==== A mérnöki gyakorlatban gyakran használunk hatványalakot. Például: * 13 250 = 1,325 × 104; * 0,001325 = 1,325 × 10−3. Mindkét számban az 1,325 hordozza az értékes számjegyeket. A tíz hatványa mondja meg, mekkora legyen a szám. A **kitevő** az a szám, amelyet a hatvány alapjának felső indexébe írunk: itt 4, illetve −3. A negatív kitevő osztást jelent: 10−3 = 1/1000. Ugyanígy 2−3 = 1/8. A **lebegőpontos számábrázolás** ezt az ötletet használja: külön tárolja a szám előjelét, értékes jegyeit és a nagyságrendet meghatározó kitevőt. A vessző helye a kitevőtől függ, ezért mondjuk, hogy „lebeg”. A bináris lebegőpontos számoknál a hatvány alapja **2**, nem 10. === A szám rendezése egységes alakba === A 13,25 korábban kapott bináris alakja ''1101,01''. A vesszőt három hellyel balra helyezve ''1,10101''-et kapunk. Ez nyolcadakkora szám, ezért 23-nal, azaz nyolccal kell szoroznunk: **1101,012 = 1,101012 × 23**. A nem nulla szám abszolút értékét úgy rendezzük át, hogy a vessző előtt pontosan egy 1-es maradjon. Ezt az alakot **normalizált alaknak**, az átrendezést **normalizálásnak** nevezzük. Az ''1,10101'' részt **szignifikansnak** nevezzük; sok tananyag a **mantissza** elnevezést használja rá. Ez hordozza a szám értékes bináris jegyeit. Értéke normalizált alakban legalább 1, de kisebb 2-nél. Egy egynél kisebb számnál negatív kitevőt kapunk: **0,001012 = 1,012 × 2−3 = 0,1562510**. Itt a vesszőt jobbra mozdítottuk három hellyel, ezért az érték megtartásához nyolccal osztunk. ==== 9. IEEE 754: pontosan melyik bit mit tároljon? ==== Az alapötlet még nem határozza meg, hány bitet kapjon az előjel, a kitevő és a szignifikáns. Ha különböző számítógépek ugyanúgy szeretnék értelmezni az adatot, közös szabályokra van szükségük. Az **IEEE 754** a lebegőpontos számábrázolás és aritmetika szabványa. Többek között tárolási formátumokat, kerekítési szabályokat és különleges értékeket határoz meg. Itt a **binary32** nevű, 32 bites bináris formátumot vezetjük le részletesen. Ezt egyszeres pontosságú ábrázolásnak is nevezik. A 32 bitet három egymás utáni részre osztjuk. Az ilyen, meghatározott szerepű bitcsoportot **mezőnek** nevezzük. ^ Mező ^ Méret ^ Feladat ^ | Előjel | 1 bit | 0: pozitív, 1: negatív előjel | | Eltolt kitevő | 8 bit | A kettes hatvány kitevőjének tárolása, az alább megadott eltolással | | Törtrész | 23 bit | A normalizált szignifikáns vessző utáni bitjei | Ez összesen **1 + 8 + 23 = 32 bit**, vagyis négy bájt. A következő levezetések a normál, véges, nem nulla számokra vonatkoznak. A nulla és más különleges esetek szabályait később külön tárgyaljuk. === Miért csak a vessző utáni biteket tároljuk? === A normalizált bináris alak mindig ''1,''-gyel kezdődik. Ezt az első 1-est ezért nem szükséges külön eltárolni: visszaolvasáskor automatikusan eléírjuk a tárolt törtbiteknek. Például az ''1,10101'' szignifikansból csak az ''10101'' rész kerül a törtrészmezőbe. A hiányzó helyeket jobbról nullákkal töltjük ki. Az elhagyott első 1-est **rejtett vezető bitnek** nevezik. Emiatt a 23 tárolt törtbit a normál számoknál **24 értékes bináris jegyet** biztosít. A szignifikans és a tárolt törtrészmező tehát nem pontosan ugyanaz. === Hogyan tárolunk negatív kitevőt? === A kitevő lehet pozitív és negatív is. A binary32 kitevőmezőjét azonban **nem kettes komplemens szerint** értelmezzük. Ehelyett a valódi kitevőhöz hozzáadunk **127-et**, és ezt a nemnegatív értéket tároljuk. Ezt az állandó hozzáadást **eltolásnak** nevezzük; angol neve bias. * **Tárolás:** tárolt kitevő = valódi kitevő + 127. * **Visszaolvasás:** valódi kitevő = tárolt kitevő − 127. ^ Valódi kitevő ^ Tárolt érték ^ A tárolt érték nyolc biten ^ | −3 | 124 | ''01111100'' | | 0 | 127 | ''01111111'' | | +3 | 130 | ''10000010'' | A normál számok tárolt kitevője 1 és 254 közötti lehet, ami −126 és +127 közötti valódi kitevőt jelent. A 0 és a 255 mezőérték különleges esetek számára van fenntartva. ==== 10. Teljes példa: −13,25 tárolása binary32 formátumban ==== === 1. lépés: az előjel === A szám negatív, ezért az **előjelbit 1**. A továbbiakban a 13,25 abszolút értékével dolgozunk. === 2. lépés: bináris alak és normalizálás === A korábbi levezetés szerint: **13,2510 = 1101,012 = 1,101012 × 23**. A valódi kitevő tehát **3**, a szignifikáns **1,10101**. === 3. lépés: a kitevőmező === A 3-hoz hozzáadjuk az eltolást: **3 + 127 = 130**. Mivel 130 = 128 + 2, a kitevőmező nyolc bitje **10000010**. === 4. lépés: a törtrészmező === Az ''1,10101'' elejéről elhagyjuk a rejtett 1-est. A maradó ''10101'' öt bit hosszú; jobbról 18 nullával egészítjük ki 23 bitre: **10101000000000000000000**. Itt nincs szükség kerekítésre, mert az összes értékes jegy elfér. === 5. lépés: a mezők összeillesztése === ^ Előjel: 1 bit ^ Kitevő: 8 bit ^ Törtrész: 23 bit ^ | ''1'' | ''10000010'' | ''10101000000000000000000'' | A teljes 32 bites minta: 1 10000010 10101000000000000000000 A szóközök csak a mezőhatárokat mutatják, nem tárolt jelek. A bitmintát a legfelső előjelbittől a legalsó törtbit felé írtuk fel; a memóriabeli bájtsorrend külön kérdés. **Fontos különbség:** itt a negatív előjelet egy külön bit tárolja. A −13,25 előállításához nem fordítjuk meg a +13,25 teljes bitmintáját, és nem adunk hozzá 1-et. A kettes komplemens az egész számoknál tanult másik ábrázolás. === Visszaellenőrzés: mit jelent ez a 32 bit? === - Az előjelbit 1, ezért az eredmény negatív. - A kitevőmező ''10000010'', vagyis 130. A valódi kitevő 130 − 127 = 3. - A törtmező elé visszaírjuk a rejtett 1-est: ''1,10101''. - A szignifikáns értéke 1 + 1/2 + 1/8 + 1/32 = 1,65625. - Megszorozzuk 23-nal: 1,65625 × 8 = 13,25. - Alkalmazzuk a negatív előjelet: **−13,25**. === A szabály tömör képlettel === Jelöljük az előjelbitet s-sel, a kitevőmező előjel nélküli egész értékét E-vel, a 23 bites törtrészmező előjel nélküli egész értékét pedig F-fel. Normál binary32 számnál: **érték = (−1)s × (1 + F / 223) × 2E−127**. A képlet ugyanazokat a lépéseket foglalja össze, amelyeket az előbb külön elvégeztünk. Csak akkor alkalmazható ebben az alakban, ha **1 ≤ E ≤ 254**. ==== 11. Második példa: egy kicsi pozitív szám ==== Ábrázoljuk a **0,15625** számot! Mivel 0,15625 = 1/8 + 1/32, bináris alakja ''0,00101''. Normalizálva: **1,012 × 2−3**. * Az előjelbit **0**, mert a szám pozitív. * A valódi kitevő **−3**, így a tárolt kitevő −3 + 127 = **124**, azaz ''01111100''. * A rejtett 1-es utáni törtbitek ''01'', amelyeket 23 bitre egészítünk ki. ^ Előjel ^ Kitevő ^ Törtrész ^ | ''0'' | ''01111100'' | ''01000000000000000000000'' | Visszaolvasva a szignifikáns 1,25, a kettes hatvány 1/8, ezért az eredmény **1,25 / 8 = 0,15625**. ==== 12. Miért nem minden szám tárolható pontosan? ==== A tízes számrendszerben az 1/3 felírása végtelen: 0,3333… Kettes számrendszerben is vannak végtelen felírású törtek, de nem pontosan ugyanazok. Például a **0,110 bináris alakja 0,0001100110011…2**. A ''0011'' rész az első törtjegy után ismétlődik. Az ismételt kettővel szorzásnál is látszik az ismétlődés: ^ Lépés ^ Szorzás ^ Kiírt bit ^ Maradó törtrész ^ | 1. | 0,1 × 2 = 0,2 | 0 | 0,2 | | 2. | 0,2 × 2 = 0,4 | 0 | 0,4 | | 3. | 0,4 × 2 = 0,8 | 0 | 0,8 | | 4. | 0,8 × 2 = 1,6 | 1 | 0,6 | | 5. | 0,6 × 2 = 1,2 | 1 | 0,2 | Az ötödik lépésben újra 0,2 maradt, ezért innentől ugyanaz a folyamat ismétlődik. A szám felírása nem ér véget. Véges számú biten csak véges számú jegyet tárolhatunk, ezért **közelítő értéket** választunk. A binary32 formátumban a 0,1 legközelebbi tárolható értéke körülbelül **0,10000000149**. Ez nem meghibásodás. Hasonló ahhoz, amikor az 1/3 helyett csak 0,333-at írunk le. === A kerekítés alapelve === Az IEEE 754 alapértelmezett bináris kerekítése a **legközelebbi ábrázolható értéket** választja. Pontos félútnál azt az értéket részesíti előnyben, amelynek utolsó megtartott bináris jegye 0. Ezt „legközelebbire, döntetlennél párosra” kerekítésnek nevezik. Ezért a tárolás nem minden esetben puszta levágás: a megtartott utolsó jegyek a kerekítés hatására megváltozhatnak. === A pontosság nem a tizedesjegyek állandó számát jelenti === A binary32 normál számoknak 24 értékes bináris jegyük van. Amikor a kitevő nő, ugyanezek a jegyek nagyobb helyi értékeket jelölnek. Ezért a nagyobb számok között általában nagyobb a távolság. Például binary32 esetén: * 1 és 2 között a szomszédos számok távolsága 2−23, körülbelül 0,0000001192. * 224 = 16 777 216 és 225 között a lépésköz már **2**. A **16 777 217** egész szám ezért nem tárolható pontosan binary32-ben, pedig nem közelíti meg a formátum legnagyobb értékét. A szomszédai 16 777 216 és 16 777 218. Az alapértelmezett kerekítés itt a 16 777 216-ot választja. **Az ábrázolható tartomány és az ábrázolás pontossága külön tulajdonság.** Attól, hogy egy érték a tartományon belül van, még nem feltétlenül tárolható pontosan. ==== 13. Nulla, nagyon kicsi számok és különleges értékek ==== A normál alak mindig rejtett 1-essel kezdődik, ezért ezzel a szabállyal a nullát nem tudnánk leírni. A szabvány ezért bizonyos kitevőmintákhoz külön értelmezést rendel. A következő táblázatban E a kitevőmező egész értéke, F pedig a törtrészmezőé: ^ Tárolt kitevő, E ^ Törtrész, F ^ Jelentés ^ | 1–254 | Tetszőleges | Normál, véges, nem nulla szám; rejtett vezető bitje 1. | | 0 | 0 | Nulla; az előjelbittől függően +0 vagy −0. | | 0 | Nem nulla | Szubnormális, azaz a normál tartománynál kisebb abszolút értékű, nem nulla szám. | | 255 | 0 | Pozitív vagy negatív végtelen az előjelbit szerint. | | 255 | Nem nulla | NaN: különleges „nem szám” érték. | A **szubnormális számoknál** a vezető bit 0, a kettes hatvány kitevője pedig rögzítetten −126. Így a normál tartomány alatt is tárolhatók nullától különböző értékek, de kevesebb értékes jeggyel. A legkisebb pozitív binary32 érték 2−149, körülbelül 1,4 × 10−45. A szubnormális érték képlete: **(−1)s × (F / 223) × 2−126**. Itt nem írunk vissza rejtett 1-est. A **végtelen** jelölés például túl nagy eredménynél jelenhet meg. Nem egy rendkívül nagy véges számot jelent, hanem különleges érték. A **NaN** az angol Not a Number rövidítése. Olyan eredményt jelölhet, amelyhez nem rendelhető szokásos számérték, például a 0/0 műveletnél. A program konkrét szabályai szerint ilyen helyzetben különleges érték vagy hibajelzés is keletkezhet. A +0 és −0 a szokásos numerikus egyenlőségvizsgálatban egyenlő, de bitmintájuk eltér, és egyes műveletek különbséget tesznek közöttük. Ez az egész számok kettes komplemens ábrázolásának egyetlen nullájától eltérő szabály. ==== 14. Mi változik 64 bites lebegőpontos ábrázolásnál? ==== Az IEEE 754 másik gyakori formátuma a **binary64**, más néven kétszeres pontosságú ábrázolás. Ugyanarra az elvre épül, de több bitet használ a kitevőhöz és a törtrészhez is. ^ Tulajdonság ^ binary32 ^ binary64 ^ | Teljes méret | 32 bit, 4 bájt | 64 bit, 8 bájt | | Előjel | 1 bit | 1 bit | | Kitevőmező | 8 bit | 11 bit | | Tárolt törtbitek | 23 bit | 52 bit | | Értékes bináris jegyek normál számnál | 24 | 53 | | Kitevő eltolása | 127 | 1023 | | Tájékoztató pontosság tízes számrendszerben | Körülbelül 7 értékes jegy | Körülbelül 16 értékes jegy | | Legnagyobb pozitív véges érték, közelítőleg | 3,4 × 1038 | 1,8 × 10308 | Az „értékes jegy” nem ugyanaz, mint a „vessző utáni jegy”. Például az 1,234567 és az 1 234 567 egyaránt hét értékes decimális jegyet tartalmaz. A táblázat kerekített tájékoztatást ad, nem minden decimális számra érvényes pontos tárolási garanciát. A binary64 lényegesen pontosabb, de **a 0,1-et ez sem tárolja pontosan**, mert annak bináris felírása végtelen. ==== 15. Mire figyeljünk mérnöki számításoknál? ==== * **Egész számoknál ellenőrizzük a tartományt.** Például egy számláló tárolásakor fontos, elfér-e benne a legnagyobb várható érték. * **A lebegőpontos eredményben lehet kerekítési eltérés.** Ez nem azonos a műszer mérési hibájával, bár a számítás során mindkettő jelentős lehet. * **Nagy érték mellett egy kis változás elveszhet.** Ha a változás kisebb a helyi lépésköznél, kerekítés után ugyanaz a szám maradhat. * **A számítás sorrendje is számíthat.** A részeredmények kerekítése miatt az összeadások átcsoportosítása eltérő eredményt adhat. * **Számított vagy mért értékek egyezését gyakran tűréssel vizsgáljuk.** A tűrést a mértékegységhez, a nagyságrendhez és a feladat pontossági követelményéhez kell választani. Például ha két hosszúságeredmény eltérését legfeljebb 0,001 mm-ig tekintjük elfogadhatónak, azt vizsgáljuk, hogy különbségük abszolút értéke legfeljebb 0,001 mm-e. Más nagyságrendű feladatnál relatív, az érték nagyságához viszonyított tűrésre is szükség lehet. A több megjelenített tizedesjegy nem teszi pontosabbá sem az eredeti mérést, sem a már elvégzett számítást. ==== Ellenőrző kérdések és feladatok ==== - Írja fel a −6 értéket nyolcbites kettes komplemens ábrázolással! - Mit jelent az ''11110110'' nyolcbites kettes komplemens szerint? - Miért okoz problémát a 100 + 40 művelet nyolcbites kettes komplemensben? - Írja fel a 0,375 számot bináris tört alakban! - Írja fel a 6,5 számot normalizált bináris alakban! - Adja meg a +6,5 három mezőjét IEEE 754 binary32 formátumban! - Az előző bitmintában mely bitek változnak meg, ha +6,5 helyett −6,5-et tárolunk? - Miért nem tárolható pontosan a 0,1 sem binary32, sem binary64 formátumban? - Hogyan lehetséges, hogy egy tartományon belüli egész szám sem tárolható pontosan lebegőpontos formában? === Megoldások === - +6: ''00000110''; megfordítva: ''11111001''; egyet hozzáadva: **11111010**. - Előjel nélkül 246, ezért kettes komplemens szerint 246 − 256 = **−10**. - A matematikai eredmény 140, de a legnagyobb ábrázolható érték 127. Túlcsordulás történik. - 0,375 = 1/4 + 1/8, ezért **0,0112**. - 6,5 = 110,12 = **1,1012 × 22**. - Előjel: ''0''; kitevő: 2 + 127 = 129, azaz ''10000001''; törtrész: ''10100000000000000000000''. - Csak az előjelbit változik 0-ról 1-re. - A 0,1 bináris alakja végtelen szakaszos tört, a tárolható bitek száma pedig véges. - A tartomány a nagyságrendet korlátozza, a szignifikáns hossza pedig a pontosságot. Nagy értékeknél a szomszédos tárolható számok között egynél nagyobb távolság is lehet. ==== Források és további olvasnivaló ==== * [[https://docs.oracle.com/cd/E77782_01/html/E77791/z4000ac019878.html|Oracle Numerical Computation Guide: IEEE-formátumok és különleges értékek]] * [[https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html|David Goldberg: What Every Computer Scientist Should Know About Floating-Point Arithmetic]]

Nyolc bit – kétféle értelmezés

Kattints a bitekre! Ugyanazt a bitsorozatot előjel nélküli egészként és kettes komplemens szerint is értelmezzük.

Előjel nélkül:
Kettes komplemens szerint:

Próbáld ki: állíts be 127-et, majd adj hozzá 1-et! A demonstráció nyolc bitet tart meg.