tanszek:oktatas:infrendalapjai_architekturak:logika_alapjai:szamabrazolas
Differences
This shows you the differences between two versions of the page.
| tanszek:oktatas:infrendalapjai_architekturak:logika_alapjai:szamabrazolas [2026/09/18 19:19] – created knehez | tanszek:oktatas:infrendalapjai_architekturak:logika_alapjai:szamabrazolas [2026/10/03 18:17] (current) – knehez | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ===== Negatív és lebegőpontos számok ábrázolása | + | ===== Negatív és lebegőpontos számok ábrázolása ===== |
| - | A számítógép | + | 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 |
| - | Fontos, hogy ugyanaz | + | Ehhez meg kell állapodnunk |
| - | * előjel nélküli egész számként 255-öt; | + | ==== 1. Kiindulás: mit jelent egy bitsorozat? ==== |
| - | * 8 bites kettes komplemens előjeles számként −1-et; | + | |
| - | * egy hosszabb adat, karakter vagy utasítás részét. | + | |
| - | Az értelmezéshez tehát ismernünk kell az adattípust | + | A kettes számrendszerben a helyi értékek jobbról balra kétszereződnek: |
| - | ==== 1. Előjel nélküli egész számok ==== | + | Például a '' |
| - | Előjel nélküli ábrázolásnál minden bit a szám nagyságát adja meg. Egy 8 bites szám helyiértékei: | + | ^ Helyi érték ^ 128 ^ 64 ^ 32 ^ 16 ^ 8 ^ 4 ^ 2 ^ 1 ^ |
| + | | Bit | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | | ||
| - | ^ Helyiérték ^ 2⁷ ^ 2⁶ ^ 2⁵ ^ 2⁴ ^ 2³ ^ 2² ^ 2¹ ^ 2⁰ ^ | + | A szám tehát **8 + 4 + 1 = 13**. |
| - | | Érték | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 | | + | |
| - | Például: | + | 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, |
| - | < | + | Ha negatív számokat is szeretnénk tárolni, akkor ugyanezt a 256 bitsorozatot kell másképpen felosztanunk. |
| - | 00101101₂ = 32 + 8 + 4 + 1 = 45₁₀ | + | |
| - | </ | + | |
| - | '' | + | **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 ==== |
| - | 0 ... 2ⁿ − 1 | + | |
| - | </ | + | |
| - | 8 bit esetén ez: | + | 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é: |
| - | 0 ... 255 | + | |
| - | </ | + | |
| - | ==== 2. Negatív egész számok ábrázolása ==== | + | ^ Szám ^ Előjelbit ^ A nagyság hét biten ^ Teljes bitsorozat ^ |
| + | | +5 | 0 | '' | ||
| + | | −5 | 1 | '' | ||
| - | A negatív számok tárolására többféle módszert dolgoztak ki. A legismertebbek: | + | 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: |
| - | * előjel–nagyságos ábrázolás; | + | * A nullának két alakja van: '' |
| - | * egyes komplemens ábrázolás; | + | * A bitsorozatok közönséges bináris összeadása önmagában nem adja meg helyesen az előjeles összeget. |
| - | * kettes komplemens ábrázolás. | + | |
| - | A modern számítógépek szinte mindig a //kettes komplemens// | + | Például +5 és −5 matematikai összege 0. A fenti két bitsorozat szokásos bináris összeadása viszont '' |
| - | ==== 2.1. Előjel–nagyságos ábrázolás ==== | + | Az egész számokhoz ezért általában más megoldást használunk: |
| - | Ebben a módszerben a legmagasabb helyiértékű, | + | ==== 3. Kettes komplemens ==== |
| - | * '' | + | Olyan bitsorozatot keresünk −5 számára, amelyet +5 bitsorozatához hozzáadva az alsó nyolc biten nullát kapunk. |
| - | * '' | + | |
| - | A többi bit a szám abszolút értékét tartalmazza. | + | Nyolc biten legfeljebb 255 ábrázolható előjel nélkül. |
| - | 8 biten például: | + | 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: |
| - | +5 = 00000101 | + | |
| - | −5 = 10000101 | + | |
| - | </ | + | |
| - | A módszer könnyen értelmezhető, de kétféle nulla tartozik hozzá: | + | === 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.** | ||
| < | < | ||
| - | +0 = 00000000 | + | +5 nyolc biten: |
| - | −0 = 10000000 | + | Bitek megfordítása: |
| + | Egy hozzáadása: | ||
| </ | </ | ||
| - | Az összeadás | + | Az eredmény tehát **−5 = 11111011** nyolcbites kettes komplemensben. |
| + | |||
| + | Miért működik a megfordítás | ||
| + | |||
| + | === 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, | ||
| + | |||
| + | Másik visszaolvasási módszer: az '' | ||
| + | |||
| + | ==== 4. Miért hasznos a kettes komplemens? ==== | ||
| - | ==== 2.2. Egyes komplemens ábrázolás ==== | + | 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. |
| - | Egy negatív szám egyes komplemensét úgy kapjuk | + | Vizsgáljuk |
| < | < | ||
| - | +5 = 00000101 | + | 00000101 |
| - | −5 = 11111010 | + | + 11111011 |
| + | ---------- | ||
| + | 1 00000000 | ||
| </ | </ | ||
| - | A bitenkénti megfordítás során minden 0-ból 1, minden 1-ből | + | A bal oldali kilencedik bit nem fér bele a nyolcbites eredménybe. Az alsó nyolc bit '' |
| - | Ennél a módszernél | + | A kivonás |
| < | < | ||
| - | +0 = 00000000 | + | 00000111 |
| - | −0 = 11111111 | + | + 11111011 |
| + | ---------- | ||
| + | 1 00000010 | ||
| </ | </ | ||
| - | Ez a tulajdonság, | + | Az alsó nyolc bit értéke **2**. |
| - | ==== 2.3. Kettes komplemens ábrázolás ==== | + | //Fontos:// A helyes előjeles eredményhez az is szükséges, |
| - | A kettes komplemens ábrázolás előnye, hogy csak egyetlen nullaérték létezik, és ugyanaz az összeadó áramkör használható pozitív és negatív számok összeadására. | + | ==== 5. Mekkora számok férnek el? ==== |
| - | Egy negatív szám kettes | + | Nyolcbites |
| - | | + | |
| - | | + | |
| - | | + | |
| - | Például a −5 előállítása 8 biten: | + | A tartomány azért nem szimmetrikus, |
| - | < | + | ^ 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 | |
| - | + 1 | + | | 32 | 0 … 4 294 967 295 | −2 147 483 648 … 2 147 483 647 | |
| - | ---------- | + | |
| - | 11111011 | + | |
| - | </ | + | |
| - | Tehát: | + | Általánosan n bit esetén a kettes komplemens tartománya **−2< |
| - | < | + | Ugyanaz a bitsorozat eltérő szabállyal mást jelent: |
| - | +5 = 00000101 | + | |
| - | −5 = 11111011 | + | |
| - | </ | + | |
| - | === Negatív kettes | + | ^ Bitsorozat ^ Előjel nélkül ^ Kettes |
| + | | '' | ||
| + | | '' | ||
| + | | '' | ||
| - | Ha egy kettes | + | A −128 pozitív párja, +128 nem fér el nyolcbites |
| - | - fordítsuk meg az összes | + | === Mi történik, ha több bitet használunk? |
| - | - adjunk hozzá 1-et; | + | |
| - | - az eredményt lássuk el negatív előjellel. | + | |
| - | Például: | + | Ha egy kettes komplemens számot változatlan értékkel több bitre bővítünk, |
| - | < | + | ^ Szám ^ Nyolc biten ^ Tizenhat biten ^ |
| - | 11110110 | + | | +5 | '' |
| - | 00001001 | + | | −5 | '' |
| - | + 1 | + | |
| - | ---------- | + | |
| - | 00001010 | + | |
| - | </ | + | |
| - | Ezért: | + | 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? |
| - | 11110110₂ | + | |
| - | </ | + | |
| - | Egy másik gyors módszer szerint | + | Tízes számrendszerben |
| - | < | + | ^ Hely ^ A vessző |
| - | 11110110₂ = 246 előjel nélküli számként | + | | Helyi érték | 1 | 1/2 | 1/4 | 1/8 | 1/16 | |
| - | 246 − 256 = −10 | + | | Tízes számrendszerben | 1 | 0,5 | 0,25 | 0,125 | 0,0625 | |
| - | </code> | + | |
| - | === A kettes komplemens értéktartománya === | + | 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: |
| - | −2ⁿ⁻¹ | + | |
| - | </ | + | |
| - | Néhány gyakori eset: | + | **0, |
| - | ^ Bitszám ^ Legkisebb érték ^ Legnagyobb érték ^ | + | 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. |
| - | | 8 bit | −128 | 127 | | + | |
| - | | 16 bit | −32 768 | 32 767 | | + | |
| - | | 32 bit | −2 147 483 648 | 2 147 483 647 | | + | |
| - | | 64 bit | −2⁶³ | 2⁶³ − 1 | | + | |
| - | A tartomány azért nem szimmetrikus, | + | === 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: |
| - | 01111111 = 127 | + | |
| - | 00000000 = 0 | + | |
| - | 11111111 = | + | |
| - | 10000000 = −128 | + | |
| - | </ | + | |
| - | ==== 2.4. Összeadás kettes komplemens számokkal ==== | + | * 13 = 8 + 4 + 1, ezért az egész rész '' |
| + | * 0,25 = 1/4, ezért a tört rész '' | ||
| - | Kettes komplemens ábrázolásnál a pozitív és negatív számok a szokásos bináris összeadással összeadhatók. | + | Tehát **13, |
| - | Számítsuk ki 8 biten az '' | + | Ellenőrzés: |
| - | < | + | === Általános módszer: a törtrész szorzása kettővel === |
| - | 00000101 | + | |
| - | + 11111101 | + | |
| - | ---------- | + | |
| - | 1 00000010 | + | |
| - | </ | + | |
| - | A kilencedik bitre kerülő átvitelt elhagyjuk, mert a számábrázolás | + | 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 |
| - | < | + | Például 0,625 esetén: |
| - | 00000010 = 2 | + | |
| - | </ | + | |
| - | Valóban: | + | ^ 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 | | ||
| - | <code> | + | A jegyeket keletkezésük sorrendjében olvassuk: **0,101<sub>2</sub>**. A maradék nulla lett, ezért a felírás véget ért. |
| - | 5 + (−3) = 2 | + | |
| - | </code> | + | |
| - | === Kivonás összeadással | + | ==== 7. Hol tároljuk a vesszőt? ==== |
| - | Az '' | + | 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, |
| - | A − B = A + (−B) | + | |
| - | </ | + | |
| - | Például '' | + | Például |
| - | < | + | **2 + 1 + 1/4 = 3,25**. |
| - | 00000111 | + | |
| - | + 11111011 | + | |
| - | ---------- | + | |
| - | 1 00000010 | + | |
| - | </code> | + | |
| - | ==== 2.5. Túlcsordulás ==== | + | Ugyanez megfogalmazható úgy is, hogy a tárolt egész szám 52, és annak értékét 16-tal osztjuk: **52/ |
| - | Túlcsordulás akkor történik, ha a matematikai eredmény nem fér el a rendelkezésre álló bitszámon. | + | 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 |
| - | 8 bites előjeles szám esetén a legnagyobb tárolható érték 127. Ha ehhez 1-et adunk: | + | **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 |
| - | < | + | ==== 8. A lebegőpontos ábrázolás alapötlete ==== |
| - | 01111111 | + | |
| - | + 00000001 | + | |
| - | ---------- | + | |
| - | 10000000 | + | |
| - | </ | + | |
| - | A matematikai eredmény 128 lenne, de ez 8 bites előjeles számban nem ábrázolható. | + | A mérnöki gyakorlatban gyakran használunk hatványalakot. Például: |
| - | Előjeles összeadásnál túlcsordulás történt, ha: | + | * 13 250 = 1,325 × 10< |
| + | * 0,001325 = 1,325 × 10< | ||
| - | * két pozitív | + | 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. |
| - | | + | |
| - | Különböző előjelű számok összeadásakor nem keletkezhet előjeles túlcsordulás. Az utolsó bitről kilépő átvitel önmagában nem azonos az előjeles túlcsordulással. | + | A negatív kitevő osztást jelent: 10< |
| - | ==== 2.6. Előjelkiterjesztés ==== | + | 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”. |
| - | Ha egy előjeles számot több biten szeretnénk tárolni, a bal szélső előjelbitet kell megismételni. | + | A bináris lebegőpontos számoknál a hatvány alapja **2**, nem 10. |
| - | Például a −5 átalakítása 8 bitesről 16 bitesre: | + | === A szám rendezése egységes alakba === |
| - | <code> | + | A 13,25 korábban kapott bináris alakja '' |
| - | 8 biten: | + | |
| - | 16 biten: 11111111 11111011 | + | |
| - | </code> | + | |
| - | Pozitív szám esetén balról 0-kat írunk hozzá: | + | **1101, |
| - | < | + | 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. |
| - | 8 biten: | + | |
| - | 16 biten: 00000000 00000101 | + | |
| - | </ | + | |
| - | Ez az // | + | Az '' |
| - | ==== 3. Törtszámok kettes számrendszerben ==== | + | Egy egynél kisebb számnál negatív kitevőt kapunk: |
| - | A bináris törtek a tízes számrendszer törtrészeihez hasonlóan helyiértékeket használnak, de a tizedesvesszőtől jobbra | + | **0,00101< |
| - | ^ Bináris helyiérték ^ 2⁻¹ ^ 2⁻² ^ 2⁻³ ^ 2⁻⁴ ^ | + | Itt a vesszőt jobbra mozdítottuk három hellyel, ezért az érték megtartásához nyolccal osztunk. |
| - | | Tízes számrendszerben | 1/2 | 1/4 | 1/8 | 1/16 | | + | |
| - | | Érték | 0,5 | 0,25 | 0,125 | 0,0625 | | + | |
| - | Például: | + | ==== 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. |
| - | 0,101₂ = 1 · 2⁻¹ + 0 · 2⁻² + 1 · 2⁻³ | + | |
| - | = 0,5 + 0 + 0,125 | + | |
| - | = 0, | + | |
| - | </ | + | |
| - | Egy egész- | + | Az **IEEE 754** a lebegőpontos számábrázolás |
| - | < | + | A 32 bitet három egymás utáni részre osztjuk. Az ilyen, meghatározott szerepű bitcsoportot **mezőnek** nevezzük. |
| - | 1101,01₂ = 8 + 4 + 1 + 0,25 = 13, | + | |
| - | </ | + | |
| - | === Tízes tört átalakítása binárissá === | + | ^ 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 | | ||
| - | A törtrészt ismételten megszorozzuk 2-vel. Minden lépésben az eredmény egész része adja a következő | + | Ez összesen **1 + 8 + 23 = 32 bit**, vagyis négy bájt. A következő |
| - | Alakítsuk át a 0,625 értéket: | + | === Miért csak a vessző utáni biteket tároljuk? === |
| - | ^ Művelet ^ Egész rész ^ Megmaradó törtrész ^ | + | A normalizált bináris alak mindig '' |
| - | | 0,625 · 2 = 1,25 | 1 | 0,25 | | + | |
| - | | 0,25 · 2 = 0,5 | 0 | 0,5 | | + | |
| - | | 0,5 · 2 = 1,0 | 1 | 0 | | + | |
| - | Az egész részeket felülről lefelé összeolvasva: | + | Például az '' |
| - | < | + | 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. |
| - | 0,625₁₀ = 0,101₂ | + | |
| - | </ | + | |
| - | Nem minden tízes számrendszerbeli tört írható fel véges bináris törtként. A 0,1 például végtelen, ismétlődő bináris tört: | + | === 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. |
| - | 0,1₁₀ = 0, | + | |
| - | </ | + | |
| - | Emiatt a számítógép a 0,1 értéknek csak egy közeli közelítését tudja eltárolni. | + | Ezt az állandó hozzáadást **eltolásnak** nevezzük; angol neve bias. |
| - | ==== 4. Fixpontos és lebegőpontos ábrázolás ==== | + | * **Tárolás: |
| + | * **Visszaolvasás: | ||
| - | Törtszámok tárolására többféle megoldás használható. | + | ^ Valódi kitevő ^ Tárolt érték ^ A tárolt érték nyolc biten ^ |
| + | | −3 | 124 | '' | ||
| + | | 0 | 127 | '' | ||
| + | | +3 | 130 | '' | ||
| - | //Fixpontos ábrázolásnál// | + | 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 |
| - | < | + | ==== 10. Teljes példa: −13,25 tárolása binary32 formátumban ==== |
| - | 0011, | + | |
| - | </ | + | |
| - | A fixpontos számok egyszerűek és kiszámítható pontosságúak, | + | === 1. lépés: az előjel === |
| - | //Lebegőpontos ábrázolásnál// | + | A szám negatív, ezért az **előjelbit 1**. A továbbiakban |
| - | < | + | === 2. lépés: bináris alak és normalizálás === |
| - | előjel · mantissza · 2kitevő | + | |
| - | </ | + | |
| - | Például: | + | A korábbi levezetés szerint: |
| - | <code> | + | **13,25<sub>10</ |
| - | 1101,01₂ = 1,10101₂ · 2³ | + | |
| - | </code> | + | |
| - | A bináris pontot három hellyel mozgattuk balra, ezért a kitevő | + | A valódi |
| - | ==== 5. Az IEEE 754 lebegőpontos szabvány ==== | + | === 3. lépés: a kitevőmező === |
| - | A legtöbb mai számítógép | + | A 3-hoz hozzáadjuk |
| - | * '' | + | Mivel 130 = 128 + 2, a kitevőmező nyolc bitje **10000010**. |
| - | * '' | + | |
| - | * '' | + | |
| - | A két leggyakoribb formátum: | + | === 4. lépés: a törtrészmező === |
| - | ^ Formátum ^ Teljes méret ^ Előjel ^ Kitevő ^ Törtrész ^ Kitevő eltolása ^ Közelítő decimális pontosság ^ | + | Az '' |
| - | | Egyszeres pontosság (float) | 32 bit | 1 bit | 8 bit | 23 bit | 127 | kb. 7 számjegy | | + | |
| - | | Kétszeres pontosság (double) | 64 bit | 1 bit | 11 bit | 52 bit | 1023 | kb. 15–16 számjegy | | + | |
| - | Egy normál, 32 bites lebegőpontos szám értéke: | + | **10101000000000000000000**. |
| - | < | + | Itt nincs szükség kerekítésre, mert az összes értékes jegy elfér. |
| - | (−1)^S · 1,F₂ · 2^(E − 127) | + | |
| - | </ | + | |
| - | ahol: | + | === 5. lépés: a mezők összeillesztése === |
| - | * '' | + | ^ Előjel: 1 bit ^ Kitevő: 8 bit ^ Törtrész: 23 bit ^ |
| - | * '' | + | | '' |
| - | * '' | + | |
| - | * 127 a kitevő eltolási értéke, más néven //bias//. | + | |
| - | Az előjelbit értelmezése: | + | A teljes 32 bites minta: |
| < | < | ||
| - | S = 0: pozitív szám | + | 1 10000010 10101000000000000000000 |
| - | S = 1: negatív szám | + | |
| </ | </ | ||
| - | A kitevőt eltolva tároljuk, ezért negatív kitevőhöz sincs szükség külön | + | 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: |
| - | 3 + 127 = 130 = 10000010₂ | + | |
| - | </ | + | |
| - | Normál számok esetében a mantissza mindig '' | + | === Visszaellenőrzés: mit jelent ez a 32 bit? === |
| - | ==== 5.1. A 13,25 ábrázolása | + | - Az előjelbit 1, ezért az eredmény negatív. |
| + | - A kitevőmező '' | ||
| + | - A törtmező elé visszaírjuk a rejtett | ||
| + | - A szignifikáns értéke 1 + 1/2 + 1/8 + 1/32 = 1,65625. | ||
| + | - Megszorozzuk 2< | ||
| + | - Alkalmazzuk a negatív előjelet: **−13, | ||
| - | === 1. Átalakítás kettes számrendszerbe | + | === 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: |
| - | 13,25₁₀ = 1101,01₂ | + | |
| - | </ | + | |
| - | === 2. Normalizálás === | + | **érték |
| - | < | + | 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**. |
| - | 1101,01₂ = 1,10101₂ · 2³ | + | |
| - | </ | + | |
| - | === 3. Az előjelbit meghatározása | + | ==== 11. Második példa: egy kicsi pozitív szám ==== |
| - | A szám pozitív: | + | Ábrázoljuk a **0,15625** számot! Mivel 0,15625 = 1/8 + 1/32, bináris alakja '' |
| - | <code> | + | Normalizálva: |
| - | S = 0 | + | |
| - | </code> | + | |
| - | === 4. A kitevő | + | * Az előjelbit **0**, mert a szám pozitív. |
| + | * A valódi | ||
| + | * A rejtett 1-es utáni törtbitek '' | ||
| - | < | + | ^ Előjel ^ Kitevő ^ Törtrész ^ |
| - | kitevő = 3 | + | | '' |
| - | eltolt kitevő = 3 + 127 = 130 = 10000010₂ | + | |
| - | </ | + | |
| - | === 5. A törtrész tárolása === | + | Visszaolvasva a szignifikáns 1,25, a kettes hatvány 1/8, ezért az eredmény **1,25 / 8 = 0,15625**. |
| - | A normalizált alak kezdő 1-esét nem tároljuk. Az utána következő bitek: | + | ==== 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. |
| - | 10101000000000000000000 | + | |
| - | </code> | + | |
| - | === 6. A mezők összeállítása === | + | Például a **0, |
| - | < | + | Az ismételt kettővel szorzásnál is látszik az ismétlődés: |
| - | S | E | + | |
| - | 0 | 10000010 | 10101000000000000000000 | + | |
| - | </ | + | |
| - | Egybefüggően: | + | ^ 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. |
| - | 01000001010101000000000000000000 | + | |
| - | </ | + | |
| - | Hexadecimális alakban: | + | Véges számú biten csak véges számú jegyet tárolhatunk, |
| - | < | + | Ez nem meghibásodás. Hasonló ahhoz, amikor az 1/3 helyett csak 0,333-at írunk le. |
| - | 0x41540000 | + | |
| - | </code> | + | |
| - | A −13,25 ábrázolásánál csak az előjelbit változik 1-re: | + | === 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, |
| - | 11000001010101000000000000000000 = 0xC1540000 | + | |
| - | </ | + | |
| - | ==== 5.2. IEEE 754 bitsorozat visszaalakítása ==== | + | 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. |
| - | Határozzuk meg a következő 32 bites lebegőpontos szám értékét: | + | === 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. |
| - | 1 | 10000001 | 01100000000000000000000 | + | |
| - | </ | + | |
| - | Az előjelbit: | + | Például binary32 esetén: |
| - | <code> | + | * 1 és 2 között a szomszédos számok távolsága 2<sup> |
| - | S = 1, ezért a szám negatív. | + | * 2< |
| - | </code> | + | |
| - | A kitevőmező: | + | A **16 777 217** egész szám ezért nem tárolható pontosan binary32-ben, |
| - | < | + | **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. |
| - | 10000001₂ = 129 | + | |
| - | valódi kitevő = 129 − 127 = 2 | + | |
| - | </ | + | |
| - | A rejtett 1-essel kiegészített mantissza: | + | ==== 13. Nulla, nagyon kicsi számok és különleges értékek ==== |
| - | < | + | A normál alak mindig rejtett |
| - | 1,011₂ = 1 + 1/4 + 1/8 = 1,375 | + | |
| - | </ | + | |
| - | A szám értéke: | + | A következő táblázatban E a kitevőmező egész |
| - | < | + | ^ Tárolt kitevő, E ^ Törtrész, F ^ Jelentés ^ |
| - | (−1) · 1,375 · 2² = −1,375 · 4 = −5,5 | + | | 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. | | ||
| - | ==== 5.3. Különleges | + | 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ő |
| - | Az IEEE 754 szabvány bizonyos kitevőmintákat különleges értékek jelölésére tart fenn. | + | A szubnormális érték képlete: **(−1)< |
| - | ^ Kitevőmező ^ Törtrészmező ^ Jelentés ^ | + | 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. |
| - | | minden bit 0 | minden bit 0 | +0 vagy −0 | | + | |
| - | | minden bit 0 | nem minden bit 0 | szubnormális szám | | + | |
| - | | 1 és 254 között | tetszőleges | normál szám | | + | |
| - | | minden bit 1 | minden bit 0 | +végtelen | + | |
| - | | minden bit 1 | nem minden bit 0 | NaN | | + | |
| - | === Pozitív és negatív nulla === | + | 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, |
| - | Az IEEE 754 formátumban | + | 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? |
| - | +0: S = 0 | + | |
| - | −0: S = 1 | + | |
| - | </ | + | |
| - | A legtöbb műveletben egyenlőnek számítanak, de bizonyos műveleteknél az előjelüknek lehet jelentősége. | + | Az IEEE 754 másik gyakori formátuma a **binary64**, |
| - | === Szubnormális számok === | + | ^ 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 × 10< | ||
| - | A szubnormális számok segítségével | + | 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. |
| - | (−1)^S · 0,F₂ · 2^(1 − bias) | + | |
| - | </ | + | |
| - | Pontosságuk kisebb, mint a normál számoké, de fokozatos átmenetet biztosítanak a legkisebb normál szám és a nulla között. | + | ==== 15. Mire figyeljünk mérnöki számításoknál? |
| - | === Végtelen === | + | * **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, | ||
| + | * **Nagy érték mellett egy kis változás elveszhet.** Ha a változás kisebb a helyi lépésköznél, | ||
| + | * **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, | ||
| - | Pozitív vagy negatív végtelen keletkezhet például túl nagy eredmény vagy nem nulla érték | + | Például ha két hosszúságeredmény eltérését legfeljebb 0,001 mm-ig tekintjük elfogadhatónak, |
| - | < | + | 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. |
| - | 1,0 / 0,0 = +végtelen | + | |
| - | −1,0 / 0,0 = −végtelen | + | |
| - | </ | + | |
| - | === NaN === | + | ==== Ellenőrző kérdések és feladatok ==== |
| - | A '' | + | - Írja fel a −6 értéket nyolcbites kettes komplemens ábrázolással! |
| + | - Mit jelent az '' | ||
| + | - Miért okoz problémát | ||
| + | - Í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 | ||
| + | - Hogyan lehetséges, | ||
| - | < | + | === Megoldások === |
| - | 0,0 / 0,0 | + | |
| - | négyzetgyök(−1, | + | |
| - | végtelen − végtelen | + | |
| - | </ | + | |
| - | A NaN különleges tulajdonsága, hogy még önmagával sem tekinthető egyenlőnek: | + | - +6: '' |
| + | - 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, | ||
| + | - 6,5 = 110, | ||
| + | - Előjel: '' | ||
| + | - 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, | ||
| - | <code c> | + | ==== Források és további olvasnivaló ==== |
| - | if (x != x) | + | |
| - | { | + | |
| - | /* x értéke NaN */ | + | |
| - | } | + | |
| - | </ | + | |
| - | A gyakorlatban azonban erre a célra a programozási nyelvek beépített '' | + | * [[https:// |
| + | * [[https:// | ||
| - | ==== 6. A lebegőpontos ábrázolás pontatlansága ==== | ||
| - | A lebegőpontos számok véges számú bitből állnak, ezért a valós számoknak csak egy véges részhalmazát tudják pontosan tárolni. A többi értéket a legközelebbi ábrázolható számra kell kerekíteni. | + | < |
| + | <div id=" | ||
| + | < | ||
| + | #szam-demo { | ||
| + | max-width: 1000px; | ||
| + | margin: 20px auto; | ||
| + | padding: 22px; | ||
| + | box-sizing: border-box; | ||
| + | border: 1px solid #cbd5e1; | ||
| + | border-radius: | ||
| + | background: #f8fafc; | ||
| + | color: #172033; | ||
| + | font: 16px/1.6 Arial, sans-serif; | ||
| + | } | ||
| + | #szam-demo * { box-sizing: border-box; } | ||
| + | #szam-demo h3 { margin: 0 0 12px; color: #172033; } | ||
| + | #szam-demo p { margin: 10px 0; } | ||
| + | #szam-demo button, | ||
| + | #szam-demo input { | ||
| + | font: inherit; | ||
| + | } | ||
| + | #szam-demo button { | ||
| + | padding: 8px 13px; | ||
| + | border: 1px solid #94a3b8; | ||
| + | border-radius: | ||
| + | background: white; | ||
| + | color: #172033; | ||
| + | cursor: pointer; | ||
| + | } | ||
| + | #szam-demo button: | ||
| + | #szam-demo button: | ||
| + | #szam-demo input: | ||
| + | outline: 3px solid #2563eb; | ||
| + | outline-offset: | ||
| + | } | ||
| + | #szam-demo .navigation, | ||
| + | #szam-demo .controls, | ||
| + | #szam-demo .presets { | ||
| + | display: flex; | ||
| + | flex-wrap: wrap; | ||
| + | gap: 8px; | ||
| + | align-items: | ||
| + | margin-bottom: | ||
| + | } | ||
| + | #szam-demo .navigation button[aria-pressed=" | ||
| + | background: #1e40af; | ||
| + | border-color: | ||
| + | color: white; | ||
| + | } | ||
| + | #szam-demo input[type=" | ||
| + | #szam-demo input[type=" | ||
| + | width: 180px; | ||
| + | max-width: 100%; | ||
| + | padding: 8px; | ||
| + | border: 1px solid #94a3b8; | ||
| + | border-radius: | ||
| + | background: white; | ||
| + | color: #172033; | ||
| + | } | ||
| + | #szam-demo input[type=" | ||
| + | display: block; | ||
| + | width: 100%; | ||
| + | margin: 18px 0; | ||
| + | accent-color: | ||
| + | } | ||
| + | #szam-demo .bits { | ||
| + | display: flex; | ||
| + | flex-wrap: wrap; | ||
| + | gap: 5px; | ||
| + | margin: 10px 0; | ||
| + | } | ||
| + | #szam-demo .bit { | ||
| + | width: 44px; | ||
| + | min-height: 48px; | ||
| + | padding: 5px; | ||
| + | font: bold 20px monospace; | ||
| + | } | ||
| + | #szam-demo .bit[aria-pressed=" | ||
| + | background: #1e40af; | ||
| + | color: white; | ||
| + | border-color: | ||
| + | } | ||
| + | #szam-demo .bit small { | ||
| + | display: block; | ||
| + | font: 11px Arial, sans-serif; | ||
| + | } | ||
| + | #szam-demo .result { | ||
| + | margin: 14px 0; | ||
| + | padding: 14px; | ||
| + | border-left: | ||
| + | border-radius: | ||
| + | background: #eaf1ff; | ||
| + | overflow-wrap: | ||
| + | } | ||
| + | #szam-demo .mono { | ||
| + | font-family: | ||
| + | overflow-wrap: | ||
| + | } | ||
| + | #szam-demo .error { | ||
| + | color: #a61b1b; | ||
| + | font-weight: | ||
| + | } | ||
| + | #szam-demo .hint { | ||
| + | color: #475569; | ||
| + | font-size: 14px; | ||
| + | } | ||
| + | #szam-demo .field { | ||
| + | margin-top: 16px; | ||
| + | padding: 12px; | ||
| + | border-radius: | ||
| + | background: white; | ||
| + | border: 1px solid #dbe3ed; | ||
| + | } | ||
| + | # | ||
| + | #szam-demo [hidden] { display: none !important; } | ||
| + | @media (max-width: 500px) { | ||
| + | #szam-demo { padding: 12px; } | ||
| + | # | ||
| + | } | ||
| + | </ | ||
| - | Mivel a 0,1 és a 0,2 nem írható fel véges bináris törtként, a következő összehasonlítás egyes programozási nyelvekben meglepő eredményt adhat: | + | <div class=" |
| + | <button type=" | ||
| + | Negatív egész számok | ||
| + | </ | ||
| + | <button type=" | ||
| + | IEEE 754 lebegőpontos számok | ||
| + | </ | ||
| + | </ | ||
| - | <code c> | + | |
| - | double | + | < |
| - | double b = 0.2; | + | <p> |
| + | Kattints | ||
| + | | ||
| + | </p> | ||
| - | if (a + b == 0.3) | + | <div class=" |
| - | { | + | <label for=" |
| - | | + | < |
| - | } | + | min="-128" |
| - | else | + | < |
| - | { | + | </div> |
| - | printf("Nem egyenlo"); | + | |
| - | } | + | |
| - | </code> | + | |
| - | Az eredmény rendszerint '' | + | <input data-role=" |
| + | | ||
| + | | ||
| - | Lebegőpontos értékeket ezért általában egy kis hibahatár, úgynevezett | + | <div class=" |
| + | <button type=" | ||
| + | <button type=" | ||
| + | <button type=" | ||
| + | <button type=" | ||
| + | <button type=" | ||
| + | <button type=" | ||
| + | </ | ||
| - | <code c> | + | |
| - | # | + | aria-label=" |
| - | double epsilon | + | <div class=" |
| + | < | ||
| + | < | ||
| + | <strong data-role=" | ||
| + | </ | ||
| + | <div data-role=" | ||
| + | </ | ||
| - | if (fabs((a + b) - 0.3) < epsilon) | + | |
| - | { | + | |
| - | printf("A ket ertek a megadott pontossagon belul egyenlo"); | + | |
| - | } | + | |
| - | </code> | + | |
| - | Az epsilon megfelelő értéke a számok nagyságrendjétől | + | <div class=" |
| + | <button type=" | ||
| + | Adjunk hozzá 1-et! | ||
| + | </ | ||
| + | <button type=" | ||
| + | Bitek megfordítása | ||
| + | </ | ||
| + | </ | ||
| - | ==== 6.1. Pontosság és nagyságrend ==== | + | <p data-role=" |
| - | A lebegőpontos számábrázolás relatív pontosságú. Minél nagyobb számokat tárolunk, annál nagyobb távolság lehet két egymást követő ábrázolható érték között. | + | <p class=" |
| + | Próbáld ki: állíts be 127-et, majd adj hozzá 1-et! | ||
| + | | ||
| + | </ | ||
| + | </ | ||
| - | A 32 bites '' | + | <section data-section=" |
| + | < | ||
| + | <p> | ||
| + | Írj be egy számot, vagy válassz példát! | ||
| + | A program IEEE 754 binary32 formátumra alakítja. | ||
| + | A kapott biteket külön is átkapcsolhatod. | ||
| + | </p> | ||
| - | Például 32 bites float esetén: | + | <div class=" |
| + | <label for=" | ||
| + | <input id=" | ||
| + | | ||
| + | <button type=" | ||
| + | </ | ||
| - | <code> | + | |
| - | 16 777 216 még pontosan ábrázolható. | + | < |
| - | 16 777 217 már nem ábrázolható pontosan. | + | < |
| - | </code> | + | <button type=" |
| + | <button type=" | ||
| + | <button type=" | ||
| + | <button type=" | ||
| + | <button type=" | ||
| + | <button type=" | ||
| + | </ | ||
| + | |||
| + | <p data-role=" | ||
| + | |||
| + | <div class=" | ||
| + | <div class=" | ||
| + | <div data-role=" | ||
| + | <div data-role=" | ||
| + | </ | ||
| + | |||
| + | <div class=" | ||
| + | <div class=" | ||
| + | <div data-role=" | ||
| + | <div data-role=" | ||
| + | </ | ||
| + | |||
| + | <div class=" | ||
| + | <div class=" | ||
| + | <div data-role=" | ||
| + | <div data-role=" | ||
| + | </ | ||
| + | |||
| + | <div class=" | ||
| + | < | ||
| + | <div data-role=" | ||
| + | < | ||
| + | Tárolt érték: | ||
| + | <strong data-role=" | ||
| + | </ | ||
| + | <div class=" | ||
| + | A véges, | ||
| + | </div> | ||
| + | </ | ||
| + | |||
| + | <p class=" | ||
| + | A 0,1 példán figyeld meg a kerekítést! | ||
| + | Normál számnál a tárolt törtbitek elé egy rejtett 1-es kerül. | ||
| + | Nulla és szubnormális szám esetén a vezető bit 0. | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | < | ||
| + | |||
| + | < | ||
| + | (function () { | ||
| + | "use strict"; | ||
| + | |||
| + | const root = document.getElementById(" | ||
| + | if (!root || root.dataset.initialized) return; | ||
| + | root.dataset.initialized = " | ||
| + | |||
| + | const el = name => root.querySelector(' | ||
| + | const intInput = root.querySelector("# | ||
| + | const floatInput = root.querySelector("# | ||
| + | |||
| + | let byte = 251; | ||
| + | let word = 0; | ||
| + | |||
| + | const buffer = new ArrayBuffer(4); | ||
| + | const view = new DataView(buffer); | ||
| + | |||
| + | function signedValue() { | ||
| + | return byte < 128 ? byte : byte - 256; | ||
| + | } | ||
| + | |||
| + | function numberText(value) { | ||
| + | if (Number.isNaN(value)) return " | ||
| + | if (value === Infinity) return " | ||
| + | if (value === -Infinity) return " | ||
| + | if (Object.is(value, | ||
| + | return String(value).replace(" | ||
| + | } | ||
| + | |||
| + | function preciseText(value) { | ||
| + | if (!Number.isFinite(value) || value === 0) { | ||
| + | return numberText(value); | ||
| + | } | ||
| + | return value.toPrecision(17).replace(" | ||
| + | } | ||
| + | |||
| + | function makeBit(container, | ||
| + | const button = document.createElement(" | ||
| + | button.type = " | ||
| + | button.className = " | ||
| - | Ezért lebegőpontos típust nem célszerű például nagy azonosítók vagy pénzösszegek pontos tárolására használni. | + | const digit = document.createElement(" |
| + | button.appendChild(digit); | ||
| - | ==== 6.2. Túlcsordulás és alulcsordulás ==== | + | if (weight !== undefined) { |
| + | const label = document.createElement(" | ||
| + | label.textContent | ||
| + | button.appendChild(label); | ||
| + | } | ||
| - | // | + | button.addEventListener(" |
| + | container.appendChild(button); | ||
| - | // | + | return {button, digit, position}; |
| + | } | ||
| - | ==== 6.3. Kerekítési hibák felhalmozódása | + | const intBits |
| + | for (let p = 7; p >= 0; p--) { | ||
| + | intBits.push(makeBit( | ||
| + | el(" | ||
| + | p, | ||
| + | function () { | ||
| + | byte ^= 1 << p; | ||
| + | clearIntegerMessage(); | ||
| + | renderInteger(); | ||
| + | }, | ||
| + | p === 7 ? " | ||
| + | )); | ||
| + | } | ||
| - | Egyetlen lebegőpontos művelet hibája rendszerint nagyon kicsi, de sok egymás utáni művelet során a hibák felhalmozódhatnak. A műveletek sorrendje is befolyásolhatja az eredményt. | + | function clearIntegerMessage() { |
| + | el(" | ||
| + | el(" | ||
| + | } | ||
| - | Például nagyon nagy és nagyon kicsi szám összeadásakor a kis szám hatása elveszhet: | + | function renderInteger() { |
| + | const value = signedValue(); | ||
| - | <code> | + | intInput.value = value; |
| - | nagy_szam | + | el(" |
| - | </code> | + | |
| + | intBits.forEach(item => { | ||
| + | const bit = (byte >>> | ||
| + | item.digit.textContent = bit; | ||
| + | item.button.setAttribute(" | ||
| + | item.button.setAttribute( | ||
| + | " | ||
| + | item.position + ". bit: " + bit + ", átkapcsolás" | ||
| + | ); | ||
| + | }); | ||
| + | |||
| + | el(" | ||
| + | el(" | ||
| + | |||
| + | const terms = []; | ||
| + | for (let p = 7; p >= 0; p--) { | ||
| + | if ((byte >>> | ||
| + | terms.push(p === 7 ? " | ||
| + | } | ||
| + | } | ||
| + | el(" | ||
| + | (terms.length ? terms.join(" | ||
| + | |||
| + | el(" | ||
| + | ? "Az első bit 1. Előjel nélküli értékéből 256-ot kivonva: " + | ||
| + | byte + " − 256 = " + value + | ||
| + | ". Az első bit itt −128 súlyú, nem külön mínuszjel." | ||
| + | : "Az első bit 0. A két értelmezés ugyanazt a nemnegatív számot adja."; | ||
| + | } | ||
| + | |||
| + | function setInteger(value) { | ||
| + | if (!Number.isInteger(value) || value < -128 || value > 127) { | ||
| + | | ||
| + | " | ||
| + | el(" | ||
| + | return; | ||
| + | } | ||
| + | byte = value & 255; | ||
| + | clearIntegerMessage(); | ||
| + | renderInteger(); | ||
| + | } | ||
| + | |||
| + | root.querySelector(' | ||
| + | .addEventListener(" | ||
| + | |||
| + | intInput.addEventListener(" | ||
| + | if (event.key === " | ||
| + | }); | ||
| + | |||
| + | el(" | ||
| + | setInteger(Number(event.target.value)); | ||
| + | }); | ||
| + | |||
| + | root.querySelectorAll(" | ||
| + | button.addEventListener(" | ||
| + | setInteger(Number(button.dataset.int)); | ||
| + | }); | ||
| + | }); | ||
| + | |||
| + | root.querySelector(' | ||
| + | .addEventListener(" | ||
| + | const before = signedValue(); | ||
| + | byte = (byte + 1) & 255; | ||
| + | renderInteger(); | ||
| + | |||
| + | el(" | ||
| + | | ||
| + | ? " | ||
| + | "A megtartott 10000000 bitminta előjelesen −128." | ||
| + | : before + " + 1 = " + signedValue() + | ||
| + | ". Az eredmény belefér a nyolcbites előjeles tartományba."; | ||
| + | }); | ||
| + | |||
| + | root.querySelector(' | ||
| + | .addEventListener(" | ||
| + | const before = signedValue(); | ||
| + | const original = byte.toString(2).padStart(8, | ||
| + | const inverted = ((~byte) & 255).toString(2).padStart(8, | ||
| + | |||
| + | byte = ((~byte) + 1) & 255; | ||
| + | renderInteger(); | ||
| + | |||
| + | el(" | ||
| + | el(" | ||
| + | original + " → megfordítva: | ||
| + | " → +1: " + byte.toString(2).padStart(8, | ||
| + | (before === -128 | ||
| + | ? ". Túlcsordulás: | ||
| + | : ". Az új előjeles érték: " + signedValue() + " | ||
| + | }); | ||
| + | |||
| + | const floatBits = []; | ||
| + | |||
| + | function addFloatBits(container, | ||
| + | for (let p = high; p >= low; p--) { | ||
| + | floatBits.push(makeBit(container, | ||
| + | word = (word ^ (1 << p)) >>> 0; | ||
| + | el(" | ||
| + | " | ||
| + | el(" | ||
| + | renderFloat(true); | ||
| + | })); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | addFloatBits(el(" | ||
| + | addFloatBits(el(" | ||
| + | addFloatBits(el(" | ||
| + | |||
| + | function renderFloat(updateInput) { | ||
| + | view.setUint32(0, | ||
| + | const value = view.getFloat32(0, | ||
| + | |||
| + | const sign = word >>> | ||
| + | const exponent = (word >>> | ||
| + | const fraction = word & 0x7fffff; | ||
| + | const fractionBits = fraction.toString(2).padStart(23, | ||
| + | |||
| + | floatBits.forEach(item => { | ||
| + | const bit = (word >>> | ||
| + | item.digit.textContent = bit; | ||
| + | item.button.setAttribute(" | ||
| + | item.button.setAttribute( | ||
| + | " | ||
| + | item.position + ". bit: " + bit + ", átkapcsolás" | ||
| + | ); | ||
| + | }); | ||
| + | |||
| + | el(" | ||
| + | ? "s = 1: negatív előjel. NaN esetén ez nem számszerű előjel." | ||
| + | : "s = 0: pozitív előjel. NaN esetén ez nem számszerű előjel."; | ||
| + | |||
| + | el(" | ||
| + | "A 23 bit előjel nélküli egész értéke: F = " + fraction + " | ||
| + | |||
| + | let classification; | ||
| + | let formula; | ||
| + | |||
| + | if (exponent === 255) { | ||
| + | el(" | ||
| + | "E = 255: különleges érték; nem alkalmazzuk az E − 127 szabályt."; | ||
| + | |||
| + | classification = fraction === 0 ? " | ||
| + | formula = fraction === 0 | ||
| + | ? "Csupa 1-es kitevő és nulla törtrész: " + numberText(value) | ||
| + | : "Csupa 1-es kitevő és nem nulla törtrész: NaN."; | ||
| + | } else if (exponent === 0) { | ||
| + | el(" | ||
| + | "E = 0: nulla vagy szubnormális szám. A skálázás 2⁻¹²⁶, | ||
| + | "a vezető bit 0."; | ||
| + | |||
| + | classification = fraction === 0 ? " | ||
| + | formula = fraction === 0 | ||
| + | ? "Nulla kitevő és nulla törtrész: " + numberText(value) | ||
| + | : (sign ? " | ||
| + | "₂ × 2^(−126)"; | ||
| + | } else { | ||
| + | const actualExponent = exponent - 127; | ||
| + | classification = " | ||
| + | |||
| + | el(" | ||
| + | "E = " + exponent + "; valódi kitevő: " + | ||
| + | exponent + " − 127 = " + actualExponent + " | ||
| + | |||
| + | formula = (sign ? " | ||
| + | "₂ × 2^(" + actualExponent + " | ||
| + | |||
| + | el(" | ||
| + | " A rejtett 1-essel a szignifikáns: | ||
| + | numberText(1 + fraction / 8388608) + " | ||
| + | } | ||
| + | |||
| + | el(" | ||
| + | el(" | ||
| + | el(" | ||
| + | |||
| + | if (updateInput) { | ||
| + | floatInput.value = Number.isNaN(value) | ||
| + | ? " | ||
| + | : Object.is(value, | ||
| + | } | ||
| + | } | ||
| + | |||
| + | function convertFloat() { | ||
| + | const text = floatInput.value.trim().replace(" | ||
| + | let value; | ||
| - | Ez nem matematikai azonosság, hanem a véges pontosság következménye. | + | if (/ |
| + | value = NaN; | ||
| + | } else if (/ | ||
| + | value = Infinity; | ||
| + | } else if (/ | ||
| + | value = -Infinity; | ||
| + | } else if (/ | ||
| + | value = Number(text); | ||
| + | if (!Number.isFinite(value)) { | ||
| + | el(" | ||
| + | "A bemenet | ||
| + | el(" | ||
| + | return; | ||
| + | } | ||
| + | } else { | ||
| + | el(" | ||
| + | " | ||
| + | el(" | ||
| + | return; | ||
| + | } | ||
| - | ==== 7. Egész és lebegőpontos számábrázolás összehasonlítása ==== | + | view.setFloat32(0, |
| + | word = view.getUint32(0, | ||
| + | const stored | ||
| - | ^ Tulajdonság ^ Kettes komplemens egész szám ^ IEEE 754 lebegőpontos szám ^ | + | el(" |
| - | | Tárolható értékek | egészek | törtrészes és nagyon kis vagy nagy számok | | + | if (Number.isFinite(value) && !Number.isFinite(stored)) { |
| - | | Pontosság | a tartományon belül pontos | gyakran közelítő | | + | el(" |
| - | | Előjel kezelése | a legmagasabb bit helyiértékének része | külön | + | " |
| - | | Túlcsordulás | a bitsorozat hibás | + | el(" |
| - | | Különleges értékek | általában nincsenek | ±0, ±végtelen, | + | } else if (value !== 0 && stored === 0) { |
| - | | Jellemző alkalmazás | számlálók, | + | |
| + | " | ||
| + | } else if (Number.isFinite(value) && stored !== value) { | ||
| + | el(" | ||
| + | " | ||
| + | } else { | ||
| + | el(" | ||
| + | "A beolvasott érték binary32-re alakításakor nem történt további kerekítés."; | ||
| + | } | ||
| - | ==== 8. Összefoglalás ==== | + | if (!Number.isFinite(value)) { |
| + | el(" | ||
| + | } | ||
| - | * Az előjel nélküli '' | + | renderFloat(false); |
| - | * Az előjeles egész számokat a modern számítógépek jellemzően kettes komplemens alakban tárolják. | + | } |
| - | * Egy negatív kettes komplemens számot a pozitív alak bitjeinek megfordításával, | + | |
| - | * Az '' | + | |
| - | * A bináris törtrész helyiértékei '' | + | |
| - | * Az IEEE 754 lebegőpontos szám előjelből, | + | |
| - | * Sok tízes tört, például a 0,1, binárisan csak közelítőleg tárolható. | + | |
| - | * Lebegőpontos számokat általában nem közvetlen egyenlőségvizsgálattal, | + | |
| - | * Pénzügyi és más, pontos tizedes számítást igénylő feladatokhoz célszerű decimális vagy skálázott egész számábrázolást használni. | + | |
| - | ==== 9. Ellenőrző kérdések és feladatok ==== | + | root.querySelector(' |
| + | | ||
| - | - Miért nem határozható meg egy bitsorozat értéke az adattípus ismerete nélkül? | + | floatInput.addEventListener(" |
| - | - Mi a 45 előjel nélküli 8 bites bináris alakja? | + | |
| - | - Ábrázolja a −18 számot 8 bites kettes komplemens formában! | + | }); |
| - | - Milyen értéket jelent a '' | + | |
| - | - Mi a 8 bites előjeles egészek legkisebb és legnagyobb értéke? | + | |
| - | - Végezze el 8 biten a '' | + | |
| - | - Miért okoz túlcsordulást 8 biten a '' | + | |
| - | - Alakítsa át a '' | + | |
| - | - Alakítsa át a '' | + | |
| - | - Milyen három fő mezőből áll egy IEEE 754 lebegőpontos szám? | + | |
| - | - Miért nem tárolható pontosan a 0,1 a szokásos bináris lebegőpontos formátumokban? | + | |
| - | - Mit jelent a NaN érték? | + | |
| - | ==== 10. A feladatok rövid megoldása ==== | + | root.querySelectorAll(" |
| + | button.addEventListener(" | ||
| + | floatInput.value = button.dataset.float; | ||
| + | convertFloat(); | ||
| + | }); | ||
| + | }); | ||
| - | | + | root.querySelectorAll(" |
| - | - '' | + | |
| - | - '' | + | root.querySelectorAll(" |
| - | | + | tab.setAttribute(" |
| - | - A tartomány −128-tól 127-ig tart. | + | }); |
| - | | + | root.querySelectorAll(" |
| - | - Az eredmény 140 lenne, amely nagyobb a legnagyobb 8 bites előjeles értéknél, | + | |
| - | - '' | + | }); |
| - | - '' | + | }); |
| - | - Előjelbitből, | + | }); |
| - | - Mert a 0,1 bináris alakja végtelen, ismétlődő tört, miközben a tárolásra véges számú bit áll rendelkezésre. | + | |
| - | - A NaN matematikailag nem értelmezhető lebegőpontos művelet eredményét jelöli. | + | |
| + | renderInteger(); | ||
| + | convertFloat(); | ||
| + | })(); | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
tanszek/oktatas/infrendalapjai_architekturak/logika_alapjai/szamabrazolas.txt · Last modified: by knehez
