tanszek:oktatas:szamitastechnika:szamabrazolas
Differences
This shows you the differences between two versions of the page.
| Next revision | Previous revision | ||
| tanszek:oktatas:szamitastechnika:szamabrazolas [2026/10/01 20:08] – created knehez | tanszek:oktatas:szamitastechnika:szamabrazolas [2026/10/01 20:34] (current) – knehez | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ===== Karakterkódolás | + | ===== Negatív és lebegőpontos számok ábrázolása |
| - | Amikor leírjuk azt, hogy '' | + | 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 |
| - | Ebben a fejezetben megvizsgáljuk, | + | Ehhez meg kell állapodnunk |
| - | ==== 1. Hogyan lesz a betűből szám? ==== | + | ==== 1. Kiindulás: mit jelent egy bitsorozat? ==== |
| - | A szövegben szereplő betűket, számjegyeket, írásjeleket | + | 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 |
| - | Készítsünk egy nagyon egyszerű, **kitalált kódtáblázatot**! Állapodjunk meg abban, hogy három betűnek | + | Például |
| - | ^ Betű ^ Hozzárendelt szám ^ | + | ^ Helyi érték |
| - | | A | 1 | | + | | Bit | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | |
| - | | B | 2 | | + | |
| - | | C | 3 | | + | |
| - | Ezzel a táblázattal az '' | + | A szám tehát **8 + 4 + 1 = 13**. |
| - | Mi történne, ha a fogadó fél egy másik táblázatot használna, amelyben az 1 a B betűt, a 2 pedig az A betűt jelenti? Ugyanabból az '' | + | Nyolc bit együtt |
| - | **Az adó és a fogadó félnek ugyanazokat a kódolási szabályokat | + | Ha negatív számokat is szeretnénk tárolni, akkor ugyanezt |
| - | ==== 2. Hogyan tároljuk a hozzárendelt számokat? ==== | + | **A bitsorozat önmagában nem mondja meg, hogyan kell értelmezni.** Tudnunk kell, milyen számábrázolási szabály tartozik hozzá. |
| - | A számítógép a számokat kettes számrendszerben, | + | ==== 2. Első ötlet: külön |
| - | Nyolc biten 256 különböző érték különböztethető meg. Ha ezeket | + | 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 |
| - | Az előbbi kitalált példában tároljunk minden betűkódot | + | Állapodjunk meg abban, hogy az első bit 0 esetén pozitív, 1 esetén negatív |
| - | ^ Betű ^ Hozzárendelt szám ^ A szám nyolc biten ^ | + | ^ Szám ^ Előjelbit |
| - | | A | 1 | '' | + | | +5 | 0 | '' |
| - | | B | 2 | '' | + | | −5 | 1 | '' |
| - | | C | 3 | '' | + | |
| - | Az '' | + | 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: |
| - | Ezzel már egy teljes tárolási szabályt adtunk meg: megmondtuk, melyik betűhöz milyen szám tartozik, és azt is, hogy egy számot hány biten tárolunk. | + | * A nullának két alakja van: '' |
| + | * A bitsorozatok közönséges bináris összeadása önmagában nem adja meg helyesen az előjeles összeget. | ||
| - | A **karakterkódolás** meghatározza, hogyan alakítjuk a szöveg karaktereit tárolható bájtsorozattá. A visszaalakítást **dekódolásnak** nevezzük. | + | Például +5 és −5 matematikai összege 0. A fenti két bitsorozat szokásos bináris összeadása viszont '' |
| - | A saját táblázatunk csak szemléltetésre szolgál. A gyakorlatban közösen elfogadott, szabványos kódolásokat | + | Az egész számokhoz ezért általában más megoldást |
| - | ==== 3. ASCII: egy közösen elfogadott kódtáblázat | + | ==== 3. Kettes komplemens |
| - | Az egyik ilyen szabvány az **ASCII**. Teljes neve American Standard Code for Information Interchange. Az ASCII meghatározza, hogy az általa kezelt karakterekhez mely számok tartoznak. | + | Olyan bitsorozatot keresünk −5 számára, amelyet +5 bitsorozatához hozzáadva |
| - | Például a nagy '' | + | Nyolc biten legfeljebb 255 ábrázolható előjel nélkül. |
| - | ^ Karakter ^ ASCII-kód tízes számrendszerben ^ Tárolása egy bájton ^ | + | Melyik nemnegatív számmal kell az 5-öt kiegészíteni 256-ra? |
| - | | A | 65 | '' | + | |
| - | | B | 66 | '' | + | |
| - | | a | 97 | '' | + | |
| - | | 0 | 48 | '' | + | |
| - | | Szóköz | 32 | '' | + | |
| - | Az '' | + | Ezért nyolcbites kettes komplemensben |
| - | Az ASCII **128 kódértéket** használ, 0-tól 127-ig. Ennyi lehetőséghez 7 bit szükséges, | + | === Hogyan állítjuk elő a negatív szám bitmintáját? |
| - | === Mi fér bele az ASCII-ba? === | + | 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. |
| - | Az ASCII tartalmazza az angol ábécé nagy- és kisbetűit, | + | |
| + | - 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. | ||
| - | A magyar ékezetes betűk viszont nem szerepelnek benne. Az '' | + | **Példa: −5 előállítása.** |
| - | **Az ASCII korlátja tehát nem a számítógép sebessége, hanem a rendelkezésre álló jelek szűk köre.** A kódolás által kezelt karakterek összességét **karakterkészletnek** nevezzük. | + | < |
| + | +5 nyolc biten: | ||
| + | Bitek megfordítása: | ||
| + | Egy hozzáadása: | ||
| + | </ | ||
| - | ==== 4. Hogyan kerültek be az ékezetes betűk? ==== | + | Az eredmény tehát **−5 |
| - | Kézenfekvő megoldás volt a teljes bájt kihasználása: | + | Miért működik |
| - | Az összes nyelv betűi azonban 256 helyre sem férnek el. Ezért különböző nyelvekhez és régiókhoz eltérő táblázatokat készítettek. Ezeket **kódlapoknak** nevezzük. | + | === Hogyan olvassuk vissza a számot? === |
| - | Például a **Windows-1250** közép-európai karaktereket, köztük magyar ékezetes betűket tartalmaz. A **Windows-1252** elsősorban nyugat-európai nyelvekhez készült. | + | Nyolcbites kettes komplemensben az első bit helyi értéke |
| - | Nézzünk egy valódi eltérést: | + | ^ Helyi érték ^ −128 ^ 64 ^ 32 ^ 16 ^ 8 ^ 4 ^ 2 ^ 1 ^ |
| + | | −5 bitmintája | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | | ||
| - | ^ A fájlban tárolt bájt értéke ^ Windows-1250 szerint ^ Windows-1252 szerint ^ | + | Az érték: **−128 + 64 + 32 + 16 + 8 + 2 + 1 = −5**. |
| - | | 245 | ő | õ | | + | |
| - | Ha egy Windows-1250 szerint mentett fájlt Windows-1252 szerint olvasunk, | + | Ezért |
| - | További régi kódlapnevekkel is találkozhatunk: | + | Másik visszaolvasási módszer: az '' |
| - | ^ Név ^ Hol találkozhatunk vele? ^ | + | ==== 4. Miért hasznos |
| - | | IBM CP852 | Régi DOS-os, közép-európai szövegekben. | | + | |
| - | | ISO-8859-1, más néven Latin-1 | Nyugat-európai szövegekben; | + | |
| - | | ISO-8859-2, más néven Latin-2 | Közép- és kelet-európai szövegekben; | + | |
| - | Ezek nevét nem szükséges bemagolni. | + | 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. |
| - | Egyes programok | + | Vizsgáljuk meg az 5 + (−5) összeget: |
| - | ==== 5. Unicode: legyen közös azonosítójuk a karaktereknek! ==== | + | < |
| + | 00000101 | ||
| + | + 11111011 | ||
| + | ---------- | ||
| + | 1 00000000 | ||
| + | </ | ||
| - | A kódlapokkal két probléma adódik. Egyrészt ugyanaz a szám különböző karaktereket jelenthet. Másrészt egyetlen ilyen kódlapba | + | A bal oldali kilencedik bit nem fér bele a nyolcbites eredménybe. Az alsó nyolc bit '' |
| - | A **Unicode** olyan nemzetközi szabvány, amely közös rendszerben rendel számazonosítókat a karakterekhez. Tartalmazza számos mai és történeti írásrendszer betűit, valamint matematikai, | + | A kivonás is összeadássá alakítható: |
| - | Az alapgondolat egy nagy közös jegyzékhez hasonlítható: | + | < |
| + | 00000111 | ||
| + | + 11111011 | ||
| + | ---------- | ||
| + | 1 00000010 | ||
| + | </ | ||
| - | ^ Karakter ^ Unicode-azonosító tízes számrendszerben ^ | + | Az alsó nyolc bit értéke **2**. |
| - | | A | 65 | | + | |
| - | | ó | 243 | | + | |
| - | | ő | 337 | | + | |
| - | | Ω | 937 | | + | |
| - | | € | 8364 | | + | |
| - | A karakterhez rendelt ilyen azonosítót **kódpontnak** nevezzük. Például az '' | + | // |
| - | A Unicode megtartotta az ASCII karaktereinek számértékeit: | + | ==== 5. Mekkora számok férnek el? ==== |
| - | === Miért látunk betűket is a kódpontok leírásában? | + | Nyolcbites kettes komplemensben: |
| - | A szakmai leírások | + | * a legnagyobb pozitív érték '' |
| + | * a legkisebb érték '' | ||
| + | | ||
| - | Ebben a számrendszerben | + | A tartomány azért nem szimmetrikus, |
| - | Például a hexadecimális '' | + | ^ 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 | | ||
| - | A Unicode-kódpontok szokásos jelölése '' | + | Általánosan n bit esetén a kettes komplemens tartománya **−2< |
| - | ^ Karakter ^ Azonosító tízes számrendszerben ^ Ugyanaz a kódpont szokásos jelöléssel ^ | + | Ugyanaz a bitsorozat eltérő szabállyal mást jelent: |
| - | | A | 65 | '' | + | |
| - | | ó | 243 | '' | + | |
| - | | ő | 337 | '' | + | |
| - | A bevezető nullák a szám értékét nem változtatják meg. Az '' | + | ^ Bitsorozat ^ Előjel nélkül ^ Kettes komplemens szerint ^ |
| + | | '' | ||
| + | | '' | ||
| + | | '' | ||
| - | ==== 6. UTF-8: hogyan tároljuk | + | A −128 pozitív párja, +128 nem fér el nyolcbites kettes komplemensben. Ezért |
| - | A közös azonosítók bevezetésével még nem oldottunk meg mindent. Az '' | + | === Mi történik, ha több bitet használunk? |
| - | Erre szolgál például | + | Ha egy kettes komplemens számot változatlan értékkel több bitre bővítünk, |
| - | **A Unicode azt adja meg, melyik karakterről van szó. Az UTF-8 azt határozza meg, hogyan tároljuk azt bájtokkal.** | + | ^ Szám ^ Nyolc biten ^ Tizenhat biten ^ |
| + | | +5 | '' | ||
| + | | −5 | '' | ||
| - | Az UTF-8 egy kódolható kódponthoz 1, 2, 3 vagy 4 bájtot rendel. Az ASCII-karaktereket egy bájton, eredeti számértékükkel tárolja. | + | A szóköz csak az olvashatóságot segíti. Negatív szám elé tehát nem nullákat |
| - | ^ Karakter ^ Unicode-azonosító tízes | + | ==== 6. Hogyan írunk fel törteket kettes |
| - | | A | 65 | 65 | 1 | | + | |
| - | | ó | 243 | 195, 179 | 2 | | + | |
| - | | ő | 337 | 197, 145 | 2 | | + | |
| - | | € | 8364 | 226, 130, 172 | 3 | | + | |
| - | A táblázatban | + | Tízes számrendszerben |
| - | **Miért kell két bájt az ó betűhöz, ha a 243 még elférne egy bájtban?** Mert az UTF-8 nem egyszerűen a kódpont számértékét írja egy bájtba. Az egybájtos alakot a 0–127 közötti ASCII-kódoknak tartja fenn; a többi karakter tárolására külön szabályt alkalmaz. Ennek bitenkénti működését később, kiegészítésként vezetjük le. | + | ^ 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 | | ||
| - | === Hány bájt egy szó? === | + | Például a bináris **0,101** értéke: |
| - | Nézzük a '' | + | **1 × 1/2 + 0 × 1/4 + 1 × 1/8 = 0,625**. |
| - | ^ Betű ^ UTF-8-ban szükséges hely ^ | + | 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: |
| - | | m | 1 bájt | | + | |
| - | | é | 2 bájt | | + | |
| - | | r | 1 bájt | | + | |
| - | | ő | 2 bájt | | + | |
| - | | **Összesen** | **6 bájt** | | + | |
| - | A szó tehát | + | **0,101< |
| - | // | + | 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. |
| - | ==== 7. Mit jelent mindez a gyakorlatban? | + | === Példa: 13,25 felírása binárisan |
| - | === Miért jelenik meg hibás szöveg? === | + | Az egész részt és a tört részt külön vizsgáljuk: |
| - | Korábban láttuk, hogy két régi kódlap eltérően értelmezheti ugyanazt a bájtot. Hasonló hiba történhet akkor is, ha egy UTF-8-fájlt egy régi kódlap szerint nyitunk meg. | + | * 13 = 8 + 4 + 1, ezért az egész rész '' |
| + | * 0,25 = 1/4, ezért a tört rész '' | ||
| - | Az '' | + | Tehát **13,25< |
| - | **A fájl adatai még lehetnek helyesek; a program rossz szabály szerint olvassa | + | Ellenőrzés: 8 + 4 + 1 + 1/4 = 13,25. |
| - | A '' | + | === Általános módszer: |
| - | === Megnyitás és átkódolá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 csak a megmaradt törtrésszel dolgozunk. |
| - | Hibás ékezetek esetén először őrizzük meg az eredeti fájlt, és próbáljuk meg a készítésekor használt kódolással megnyitni. | + | Például 0,625 esetén: |
| - | * **Más kódolással történő megnyitáskor** ugyanazokat a bájtokat értelmezzük más szabály szerint. A fájl tartalmát ettől még nem írjuk át. | + | ^ Lépés ^ Szorzás ^ Következő bináris jegy ^ Továbbvitt törtrész ^ |
| - | * **Átkódoláskor** a már helyesen felismert szövegből más kódolású bájtsorozatot hozunk létre és mentünk el. | + | | 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 | | ||
| - | Például egy Windows-1250-fájl UTF-8-ra alakításakor az '' | + | A jegyeket keletkezésük sorrendjében olvassuk: **0,101< |
| - | Ha a helytelenül megjelenített szöveget mentjük újra, a hibát is elmenthetjük. Ha pedig olyan kódlapot választunk, | + | ==== 7. Hol tároljuk |
| - | === Mérési adatok megnyitása === | + | A memóriában nincs a bitek közé rajzolt vessző. A helyét is értelmezési szabállyal kell megadnunk. |
| - | A **CSV** olyan szöveges fájlformátum, | + | Az egyik lehetőség, |
| - | A fájl beolvasásakor három külön beállításra lehet szükség: | + | 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. |
| - | | + | **2 + 1 + 1/4 = 3,25**. |
| - | * **Mezőelválasztó: | + | |
| - | * **Tizedesjel: | + | |
| - | A hibás ékezet és az egy oszlopba összecsúszott táblázat tehát nem ugyanaz | + | 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**. |
| - | === A betűtípus szerepe === | + | Ebben az egyszerű formátumban két szomszédos szám távolsága mindig 1/16 = 0, |
| - | A karakterkódolás mellett a megjelenítésnek is helyesen kell működnie. A **betűtípus** adja meg a jelek kirajzolható alakját. Előfordulhat, hogy a program helyesen azonosít egy karaktert, de a választott betűtípusban nincs hozzá rajzolat. Ekkor például üres négyzet jelenhet meg. | + | **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? |
| - | Az értelmetlen ékezetes betűsor gyakran kódolási problémára, | + | ==== 8. A lebegőpontos ábrázolás alapötlete ==== |
| - | ==== 8. Kiegészítés: hogyan készül az UTF-8-bájtsorozat? | + | A mérnöki gyakorlatban gyakran használunk hatványalakot. Például: |
| - | Az UTF-8 bájtjai nemcsak a kódpont bitjeit tartalmazzák. Bizonyos bitek azt jelzik, hogy egyetlen bájtról, több bájtból álló sorozat kezdetéről vagy annak folytatásáról van-e szó. | + | * 13 250 = 1,325 × 10< |
| + | * 0,001325 = 1,325 × 10< | ||
| - | A következő táblázatban | + | Mindkét számban az 1,325 hordozza az értékes számjegyeket. |
| - | ^ Teljes hossz ^ Bitminta ^ | + | A negatív kitevő osztást jelent: 10< |
| - | | 1 bájt | '' | + | |
| - | | 2 bájt | '' | + | |
| - | | 3 bájt | '' | + | |
| - | | 4 bájt | '' | + | |
| - | Például | + | A **lebegőpontos számábrázolás** ezt az ötletet használja: külön tárolja |
| - | === Az ó betű levezetése === | + | A bináris lebegőpontos számoknál a hatvány alapja **2**, nem 10. |
| - | Az '' | + | === A szám rendezése egységes alakba === |
| - | A 243 nagyobb 127-nél, ezért nem használhatjuk az egybájtos alakot. A kétbájtos mintában viszont 5 + 6 = 11 adatbitnek van helye, ami elegendő. A nyolc bit elé ezért | + | A 13,25 korábban kapott bináris alakja '' |
| - | <code> | + | **1101,01<sub>2</sub> = 1, |
| - | 243 kettes számrendszerben: | + | |
| - | 11 bitre kiegészítve: | + | |
| - | Felbontás: | + | |
| - | </code> | + | |
| - | Ezután az első öt bit elé '' | + | 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 '' |
| - | Első bájt: | + | |
| - | Második bájt: 10 + 110011 = 10110011 | + | |
| - | </ | + | |
| - | Az első bájt értéke 195, a másodiké 179. Így kaptuk meg a korábbi táblázatban szereplő két számot. | + | Egy egynél kisebb számnál negatív kitevőt kapunk: |
| - | Hexadecimálisan 195 = '' | + | **0, |
| - | **A U+00F3 és a C3 B3 két különböző dolgot jelöl:** az első az '' | + | Itt a vesszőt jobbra mozdítottuk három hellyel, ezért |
| - | // | + | ==== 9. IEEE 754: pontosan melyik bit mit tároljon? ==== |
| - | ==== 9. Kiegészítés: | + | Az alapötlet még nem határozza meg, hány bitet kapjon az előjel, a kitevő |
| - | Ugyanazokat | + | 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, |
| - | Az '' | + | A 32 bitet három egymás utáni részre osztjuk. Az ilyen, meghatározott szerepű bitcsoportot **mezőnek** nevezzük. |
| - | ^ Sorrend neve ^ Az A tárolt bájtjai tízes számrendszerben | + | ^ Mező ^ Méret |
| - | | Big-endian | + | | Előjel | 1 bit | 0: pozitív, 1: negatív |
| - | | Little-endian | + | | Eltolt kitevő |
| + | | Törtrész | 23 bit | A normalizált szignifikáns vessző utáni bitjei | ||
| - | A két változat neve **UTF-16BE**, illetve **UTF-16LE**. A bájtsorrend itt a két bájt sorrendjét jelenti, nem az egy bájton belüli bitek megfordítását. | + | Ez összesen |
| - | A fájl elejére speciális jelzés is kerülhet, amely segít | + | === Miért csak a vessző utáni biteket tároljuk? === |
| - | A BOM használata nem minden esetben kötelező: a kódolást és a sorrendet más módon is megadhatják. UTF-8-fájl elején is előfordulhat BOM, de ott csak a kódolásra utaló jelzés, mert UTF-8-nál nincs választható bájtsorrend. | + | A normalizált bináris alak mindig '' |
| - | ==== 10. Base64: hogyan legyen egy fájlból továbbítható szöveg? ==== | + | Például az '' |
| - | Eddig szövegek tárolásáról volt szó. Most más feladatot vizsgálunk: | + | 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 |
| - | A fájl bájtjait nem kezelhetjük egyszerűen betűkként. Tetszőleges értékeik lehetnek, köztük olyanok, amelyeket a fogadó program vezérlőjelként értelmezne. Célszerű ezért az adatot egy szűk, előre rögzített készletből választott, | + | === Hogyan tárolunk negatív kitevőt? === |
| - | Erre szolgál a **Base64**. Tetszőleges bemeneti bájtokat alakít át betűkből, számjegyekből | + | A kitevő lehet pozitív és negatív is. A binary32 kitevőmezőjét azonban |
| - | **Az UTF-8 szöveges karaktereket alakít bájtokká. A Base64 tetszőleges bájtokat alakít szöveges jelekké.** | + | Ezt az állandó hozzáadást |
| - | A Base64 nem titkosítás: aki ismeri a szabályt, kulcs nélkül vissza tudja állítani az eredeti adatot. | + | * **Tárolás:** tárolt kitevő = valódi kitevő + 127. |
| + | * **Visszaolvasás: | ||
| - | === Miért éppen 64? === | + | ^ Valódi kitevő ^ Tárolt érték ^ A tárolt érték nyolc biten ^ |
| + | | −3 | 124 | '' | ||
| + | | 0 | 127 | '' | ||
| + | | +3 | 130 | '' | ||
| - | A Base64 a bemeneti biteket **hatos csoportokba** rendezi. Hat bit 64 különböző értéket adhat, 0-tól 63-ig. Mindegyik értékhez egy nyomtatható jelet rendel: | + | 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. |
| - | ^ A hat bit értéke ^ Hozzárendelt jel ^ | + | ==== 10. Teljes példa: −13,25 tárolása binary32 formátumban ==== |
| - | | 0–25 | '' | + | |
| - | | 26–51 | '' | + | |
| - | | 52–61 | '' | + | |
| - | | 62 | '' | + | |
| - | | 63 | ''/'' | + | |
| - | Az értékek sorrendben követik egymást: 0 jelentése '' | + | === 1. lépés: az előjel === |
| - | **Ez a Base64 saját táblázata, nem az ASCII-táblázat.** Például a '' | + | A szám negatív, ezért |
| - | === Példa: Man === | + | === 2. lépés: bináris alak és normalizálás |
| - | Használjuk bemenetként a '' | + | A korábbi levezetés |
| - | <code> | + | **13,25<sub>10</ |
| - | M: 77 | + | |
| - | a: 97 | + | A valódi kitevő tehát **3**, a szignifikáns **1, |
| - | n: 110 = 01101110 | + | |
| - | </ | + | === 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 '' | ||
| + | |||
| + | **10101000000000000000000**. | ||
| + | |||
| + | Itt nincs szükség kerekítésre, | ||
| + | |||
| + | === 5. lépés: a mezők összeillesztése === | ||
| + | |||
| + | ^ Előjel: 1 bit ^ Kitevő: 8 bit ^ Törtrész: 23 bit ^ | ||
| + | | '' | ||
| - | Ez összesen 24 bit. A bitek sorrendjén nem változtatunk, | + | A teljes 32 bites minta: |
| < | < | ||
| - | Három bájt: | + | 1 10000010 10101000000000000000000 |
| - | Négy hatos csoport: 010011 010110 000101 101110 | + | |
| </ | </ | ||
| - | A hatbites csoportokat számként értelmezzük, majd megkeressük | + | 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. |
| - | ^ Hat bit ^ Értéke tízes számrendszerben ^ Base64-jel ^ | + | **Fontos különbség: |
| - | | '' | + | |
| - | | '' | + | |
| - | | '' | + | |
| - | | '' | + | |
| - | Például '' | + | === Visszaellenőrzés: |
| - | Dekódoláskor ugyanezt végezzük fordítva: a négy jelből négy hatbites csoportot kapunk, majd a 24 bitet három nyolcbites bájtra bontjuk vissza. | + | - Az előjelbit 1, ezért az eredmény negatív. |
| + | - A kitevőmező '' | ||
| + | - A törtmező elé visszaírjuk a rejtett 1-est: '' | ||
| + | - A szignifikáns értéke 1 + 1/2 + 1/8 + 1/32 = 1,65625. | ||
| + | - Megszorozzuk 2< | ||
| + | - Alkalmazzuk | ||
| - | === Miért jelenik meg egyenlőségjel a végén? | + | === A szabály tömör képlettel |
| - | Nem minden fájl bájtszáma osztható hárommal. Ha a végén csak egy vagy két bájt marad, az utolsó hatbites csoporthoz nulla biteket kell hozzáadnunk. A négykarakteres kimeneti csoport hiányzó helyeit '' | + | Jelöljük az előjelbitet s-sel, |
| - | A '' | + | **érték = (−1)< |
| - | ^ Az utolsó csoportban maradt adat ^ Base64-adatjelek ^ Kitöltés ^ | + | 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**. |
| - | | 3 bájt | 4 jel | Nincs | | + | |
| - | | 2 bájt | 3 jel | Egy '' | + | |
| - | | 1 bájt | 2 jel | Két '' | + | |
| - | **Példa egyetlen bájttal:** legyen a bemenet az 1 értékű bájt, vagyis '' | + | ==== 11. Második példa: egy kicsi pozitív szám ==== |
| - | - Hat bit után elvágjuk: | + | Ábrázoljuk a **0,15625** számot! Mivel 0,15625 = 1/8 + 1/32, bináris alakja |
| - | - A második csoportot négy nullával egészítjük ki: '' | + | |
| - | - A két csoport értéke 0 és 16. A Base64-táblázat szerint ezek jele '' | + | |
| - | - Két adatjelünk van, ezért még két '' | + | |
| - | Az eredmény | + | Normalizálva: |
| - | === Mennyivel nő az adat mérete? === | + | * Az előjelbit **0**, mert a szám pozitív. |
| + | * A valódi kitevő **−3**, így a tárolt kitevő −3 + 127 = **124**, azaz '' | ||
| + | * A rejtett 1-es utáni törtbitek '' | ||
| - | A Base64 három bemeneti bájtból négy kimeneti karaktert állít elő. Ha ezeket ASCII-val vagy UTF-8-cal tároljuk, négy bájtot foglalnak. | + | ^ Előjel ^ Kitevő ^ Törtrész ^ |
| + | | '' | ||
| - | Például **300 bájt adatból 400 bájt** lesz, a sortöréseket és egyéb kiegészítéseket nem számítva. Ez körülbelül | + | Visszaolvasva a szignifikáns 1,25, a kettes hatvány 1/8, ezért az eredmény |
| - | A Base64 tehát **nem tömörítés**. Előnye az, hogy a bináris adat szöveges környezetben is továbbítható. Azt, hogy a kódolt szöveg tartalmazhat-e sortörést, | + | ==== 12. Miért |
| - | ==== Ellenőrző kérdések ==== | + | 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, |
| - | - Miért | + | |
| - | - Mit jelent a Unicode-kódpont? Hogyan kapcsolódik hozzá | + | Az ismételt kettővel szorzásnál is látszik az ismétlődés: |
| - | - Mit jelöl | + | |
| - | - Hány bájtot foglal | + | ^ Lépés ^ Szorzás ^ Kiírt bit ^ Maradó törtrész ^ |
| - | - Mi a különbség a más kódolással történő megnyitás és az átkódolás között? | + | | 1. | 0,1 × 2 = 0,2 | 0 | 0,2 | |
| - | - Miért nem szabad titkosításként használni | + | | 2. | 0,2 × 2 = 0,4 | 0 | 0,4 | |
| - | - Miért lesz három bájtból négy Base64-jel? | + | | 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 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 | ||
| + | |||
| + | 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< | ||
| + | | ||
| + | |||
| + | 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, | ||
| + | | 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< | ||
| + | |||
| + | A szubnormális érték képlete: **(−1)< | ||
| + | |||
| + | 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 | ||
| + | |||
| + | 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, | ||
| + | |||
| + | 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**, | ||
| + | |||
| + | ^ 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< | ||
| + | |||
| + | 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? ==== | ||
| + | |||
| + | | ||
| + | * **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, a nagyságrendhez | ||
| + | |||
| + | 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. | ||
| + | |||
| + | ==== Ellenőrző kérdések és feladatok ==== | ||
| + | |||
| + | - Írja fel a −6 értéket nyolcbites kettes komplemens ábrázolással! | ||
| + | - Mit jelent az '' | ||
| + | - Miért okoz problémát | ||
| + | | ||
| + | | ||
| + | - 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 | ||
| + | - Hogyan lehetséges, | ||
| === Megoldások === | === Megoldások === | ||
| - | - Eltérő táblázattal ugyanazokból | + | - +6: '' |
| - | - Az ASCII nem tartalmazza az '' | + | - Előjel nélkül 246, ezért kettes komplemens szerint 246 − 256 = **−10**. |
| - | - A kódpont | + | - A matematikai eredmény 140, de a legnagyobb ábrázolható érték 127. Túlcsordulás történik. |
| - | - Az '' | + | - 0,375 = 1/4 + 1/8, ezért **0, |
| - | - Hat bájtot: 1 + 2 + 1 + 2. | + | - 6,5 = 110, |
| - | - Megnyitáskor | + | - Előjel: |
| - | - Mert a kódolt adat kulcs nélkül visszaállítható. | + | - Csak az előjelbit változik 0-ról 1-re. |
| - | - Három bájt 24 bit; ebből négy hatbites csoport készül, és minden csoporthoz egy jel tartozik. | + | - A 0,1 bináris alakja végtelen szakaszos tört, |
| + | | ||
| + | |||
| + | ==== Források és további olvasnivaló ==== | ||
| + | |||
| + | * [[https:// | ||
| + | * [[https:// | ||
| + | |||
| + | |||
| + | < | ||
| + | <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 .field-title { font-weight: | ||
| + | #szam-demo [hidden] { display: none !important; } | ||
| + | @media (max-width: 500px) { | ||
| + | #szam-demo { padding: 12px; } | ||
| + | #szam-demo .bit { width: 38px; } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | <div class=" | ||
| + | <button type=" | ||
| + | Negatív egész számok | ||
| + | </ | ||
| + | <button type=" | ||
| + | IEEE 754 lebegőpontos számok | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | <section data-section=" | ||
| + | < | ||
| + | <p> | ||
| + | Kattints a bitekre! Ugyanazt a bitsorozatot előjel nélküli | ||
| + | egészként és kettes komplemens szerint is értelmezzük. | ||
| + | </ | ||
| + | |||
| + | <div class=" | ||
| + | <label for=" | ||
| + | <input id=" | ||
| + | | ||
| + | <button type=" | ||
| + | </ | ||
| + | |||
| + | <input data-role=" | ||
| + | | ||
| + | | ||
| + | |||
| + | <div class=" | ||
| + | <button type=" | ||
| + | <button type=" | ||
| + | <button type=" | ||
| + | <button type=" | ||
| + | <button type=" | ||
| + | <button type=" | ||
| + | </ | ||
| + | |||
| + | <div data-role=" | ||
| + | | ||
| + | |||
| + | <div class=" | ||
| + | < | ||
| + | < | ||
| + | <strong data-role=" | ||
| + | </ | ||
| + | <div data-role=" | ||
| + | </ | ||
| + | |||
| + | <p data-role=" | ||
| + | |||
| + | <div class=" | ||
| + | <button type=" | ||
| + | Adjunk hozzá 1-et! | ||
| + | </ | ||
| + | <button type=" | ||
| + | Bitek megfordítása és +1 | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | <p data-role=" | ||
| + | |||
| + | <p class=" | ||
| + | Próbáld ki: állíts be 127-et, majd adj hozzá 1-et! | ||
| + | A demonstráció nyolc bitet tart meg. | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | <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. | ||
| + | </ | ||
| + | |||
| + | <div class=" | ||
| + | <label for=" | ||
| + | <input id=" | ||
| + | | ||
| + | <button type=" | ||
| + | </ | ||
| + | |||
| + | <div class=" | ||
| + | <button type=" | ||
| + | <button type=" | ||
| + | <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, nem nulla értéket 17 értékes decimális jegyre írjuk ki. | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | <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. | ||
| + | </p> | ||
| + | | ||
| + | |||
| + | < | ||
| + | |||
| + | < | ||
| + | (function () { | ||
| + | "use strict"; | ||
| + | |||
| + | const root = document.getElementById(" | ||
| + | if (!root || root.dataset.initialized) return; | ||
| + | root.dataset.initialized = " | ||
| + | |||
| + | const el = name => root.querySelector('[data-role=" | ||
| + | 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 = " | ||
| + | |||
| + | const digit = document.createElement(" | ||
| + | button.appendChild(digit); | ||
| + | |||
| + | if (weight !== undefined) { | ||
| + | const label = document.createElement(" | ||
| + | label.textContent = weight; | ||
| + | button.appendChild(label); | ||
| + | } | ||
| + | |||
| + | button.addEventListener(" | ||
| + | container.appendChild(button); | ||
| + | |||
| + | return {button, digit, position}; | ||
| + | } | ||
| + | |||
| + | const intBits = []; | ||
| + | for (let p = 7; p >= 0; p--) { | ||
| + | intBits.push(makeBit( | ||
| + | el(" | ||
| + | p, | ||
| + | function () { | ||
| + | byte ^= 1 << p; | ||
| + | clearIntegerMessage(); | ||
| + | renderInteger(); | ||
| + | }, | ||
| + | p === 7 ? " | ||
| + | )); | ||
| + | } | ||
| + | |||
| + | function clearIntegerMessage() { | ||
| + | el(" | ||
| + | el(" | ||
| + | } | ||
| + | |||
| + | function renderInteger() { | ||
| + | const value = signedValue(); | ||
| + | |||
| + | intInput.value = value; | ||
| + | el(" | ||
| + | |||
| + | 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(" | ||
| + | " | ||
| + | el(" | ||
| + | return; | ||
| + | } | ||
| + | byte = value & 255; | ||
| + | clearIntegerMessage(); | ||
| + | renderInteger(); | ||
| + | } | ||
| + | |||
| + | root.querySelector('[data-action=" | ||
| + | .addEventListener(" | ||
| + | |||
| + | intInput.addEventListener(" | ||
| + | if (event.key === " | ||
| + | }); | ||
| + | |||
| + | el(" | ||
| + | setInteger(Number(event.target.value)); | ||
| + | }); | ||
| + | |||
| + | root.querySelectorAll(" | ||
| + | button.addEventListener(" | ||
| + | setInteger(Number(button.dataset.int)); | ||
| + | }); | ||
| + | }); | ||
| + | |||
| + | root.querySelector('[data-action=" | ||
| + | .addEventListener(" | ||
| + | const before = signedValue(); | ||
| + | byte = (byte + 1) & 255; | ||
| + | renderInteger(); | ||
| + | |||
| + | el(" | ||
| + | el(" | ||
| + | ? " | ||
| + | "A megtartott 10000000 bitminta előjelesen −128." | ||
| + | : before + " + 1 = " + signedValue() + | ||
| + | ". Az eredmény belefér a nyolcbites előjeles tartományba."; | ||
| + | }); | ||
| + | |||
| + | root.querySelector('[data-action=" | ||
| + | .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)) >>> | ||
| + | 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 | ||
| + | |||
| + | 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 nem nulla törtrész: NaN."; | ||
| + | } else if (exponent === 0) { | ||
| + | el(" | ||
| + | "E = 0: nulla vagy szubnormális szám. A skálázás | ||
| + | "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(" | ||
| + | " | ||
| + | numberText(1 + fraction / 8388608) + " | ||
| + | } | ||
| + | |||
| + | el(" | ||
| + | | ||
| + | el(" | ||
| + | |||
| + | if (updateInput) { | ||
| + | floatInput.value = Number.isNaN(value) | ||
| + | ? " | ||
| + | : Object.is(value, | ||
| + | } | ||
| + | } | ||
| + | |||
| + | function convertFloat() { | ||
| + | const text = floatInput.value.trim().replace(" | ||
| + | let value; | ||
| + | |||
| + | if (/ | ||
| + | value = NaN; | ||
| + | } else if (/ | ||
| + | value = Infinity; | ||
| + | } else if (/ | ||
| + | value = -Infinity; | ||
| + | } else if (/ | ||
| + | value = Number(text); | ||
| + | if (!Number.isFinite(value)) { | ||
| + | el(" | ||
| + | "A bemenet | ||
| + | | ||
| + | return; | ||
| + | } | ||
| + | } else { | ||
| + | el(" | ||
| + | " | ||
| + | el(" | ||
| + | return; | ||
| + | } | ||
| + | |||
| + | view.setFloat32(0, | ||
| + | word = view.getUint32(0, | ||
| + | const stored = view.getFloat32(0, | ||
| + | |||
| + | el(" | ||
| + | if (Number.isFinite(value) && !Number.isFinite(stored)) { | ||
| + | el(" | ||
| + | " | ||
| + | el(" | ||
| + | } else if (value !== 0 && stored === 0) { | ||
| + | el(" | ||
| + | "A szám túl kicsi: binary32-re kerekítve nulla lett."; | ||
| + | } 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."; | ||
| + | } | ||
| + | |||
| + | if (!Number.isFinite(value)) { | ||
| + | el(" | ||
| + | } | ||
| + | |||
| + | renderFloat(false); | ||
| + | } | ||
| + | |||
| + | root.querySelector(' | ||
| + | .addEventListener(" | ||
| + | |||
| + | floatInput.addEventListener(" | ||
| + | if (event.key === " | ||
| + | }); | ||
| + | |||
| + | root.querySelectorAll(" | ||
| + | button.addEventListener(" | ||
| + | floatInput.value = button.dataset.float; | ||
| + | convertFloat(); | ||
| + | }); | ||
| + | }); | ||
| + | |||
| + | root.querySelectorAll(" | ||
| + | button.addEventListener(" | ||
| + | root.querySelectorAll(" | ||
| + | tab.setAttribute(" | ||
| + | }); | ||
| + | root.querySelectorAll(" | ||
| + | section.hidden = section.dataset.section !== button.dataset.panel; | ||
| + | }); | ||
| + | }); | ||
| + | }); | ||
| + | renderInteger(); | ||
| + | convertFloat(); | ||
| + | })(); | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
tanszek/oktatas/szamitastechnika/szamabrazolas.1790885320.txt.gz · Last modified: by knehez
