User Tools

Site Tools


tanszek:oktatas:szamitastechnika:szamabrazolas

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
tanszek:oktatas:szamitastechnika:szamabrazolas [2026/10/01 20:11] – [3. Kettes komplemens: legyen egyszerű az összeadás!] kneheztanszek:oktatas:szamitastechnika:szamabrazolas [2026/10/01 20:34] (current) – knehez
Line 70: Line 70:
  
 Miért működik a megfordítás és az egy hozzáadása? A nyolc egyesből álló szám értéke 255. Egy pozitív x szám bitjeinek megfordítása 255 − x-et ad, az ezt követő +1 pedig 256 − x-et. Pontosan ezt kerestük. Miért működik a megfordítás és az egy hozzáadása? A nyolc egyesből álló szám értéke 255. Egy pozitív x szám bitjeinek megfordítása 255 − x-et ad, az ezt követő +1 pedig 256 − x-et. Pontosan ezt kerestük.
- 
-**A „megfordítás és +1” műveletet nem kell a pozitív számokra elvégezni a tárolásukhoz.** Például +5 továbbra is ''00000101''. 
  
 === Hogyan olvassuk vissza a számot? === === Hogyan olvassuk vissza a számot? ===
Line 139: Line 137:
  
 A −128 pozitív párja, +128 nem fér el nyolcbites kettes komplemensben. Ezért a legkisebb negatív érték előjelének megfordítása is túlcsordulhat. A −128 pozitív párja, +128 nem fér el nyolcbites kettes komplemensben. Ezért a legkisebb negatív érték előjelének megfordítása is túlcsordulhat.
- 
-=== Mi a túlcsordulás? === 
- 
-**Túlcsordulásnak** nevezzük, amikor a művelet matematikai eredménye kívül esik az ábrázolható tartományon. 
- 
-Nyolcbites kettes komplemensben például 127 + 1 eredménye nem ábrázolható: 
- 
-<code> 
-    01111111     127 
-  + 00000001       1 
-  ---------- 
-    10000000 
-</code> 
- 
-Az eredmény bitmintája kettes komplemens szerint −128 lenne, **nem a helyes matematikai 128**. Két pozitív szám összege negatívnak látszik: ez az előjeles túlcsordulás jele. 
- 
-Figyeljük meg: itt nem is keletkezett kilencedik bit. Az előjeles túlcsordulás és a legfelső helyről kijövő átvitel tehát két különböző dolog. 
- 
-A programozási nyelv és a művelet szabályai határozzák meg, mi történik túlcsorduláskor. Nem szabad minden programban automatikus „körbefordulásra” számítani. 
  
 === Mi történik, ha több bitet használunk? === === Mi történik, ha több bitet használunk? ===
Line 250: Line 229:
 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. A nem nulla szám abszolút értékét úgy rendezzük át, hogy a vessző előtt pontosan egy 1-es maradjon. Ezt az alakot **normalizált alaknak**, az átrendezést **normalizálásnak** nevezzük.
  
-Az ''1,10101'' részt **szignifikandnak** nevezzük; sok tananyag a **mantissza** elnevezést használja rá. Ez hordozza a szám értékes bináris jegyeit. Értéke normalizált alakban legalább 1, de kisebb 2-nél.+Az ''1,10101'' részt **szignifikansnak** nevezzük; sok tananyag a **mantissza** elnevezést használja rá. Ez hordozza a szám értékes bináris jegyeit. Értéke normalizált alakban legalább 1, de kisebb 2-nél.
  
 Egy egynél kisebb számnál negatív kitevőt kapunk: Egy egynél kisebb számnál negatív kitevőt kapunk:
Line 260: Line 239:
 ==== 9. IEEE 754: pontosan melyik bit mit tároljon? ==== ==== 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 szignifikand. Ha különböző számítógépek ugyanúgy szeretnék értelmezni az adatot, közös szabályokra van szükségük.+Az alapötlet még nem határozza meg, hány bitet kapjon az előjel, a kitevő és a szignifikáns. Ha különböző számítógépek ugyanúgy szeretnék értelmezni az adatot, közös szabályokra van szükségük.
  
 Az **IEEE 754** a lebegőpontos számábrázolás és aritmetika szabványa. Többek között tárolási formátumokat, kerekítési szabályokat és különleges értékeket határoz meg. Itt a **binary32** nevű, 32 bites bináris formátumot vezetjük le részletesen. Ezt egyszeres pontosságú ábrázolásnak is nevezik. Az **IEEE 754** a lebegőpontos számábrázolás és aritmetika szabványa. Többek között tárolási formátumokat, kerekítési szabályokat és különleges értékeket határoz meg. Itt a **binary32** nevű, 32 bites bináris formátumot vezetjük le részletesen. Ezt egyszeres pontosságú ábrázolásnak is nevezik.
Line 269: Line 248:
 | Előjel | 1 bit | 0: pozitív, 1: negatív előjel | | 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 | | 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 szignifikand vessző utáni bitjei |+| Törtrész | 23 bit | A normalizált szignifikáns vessző utáni bitjei |
  
 Ez összesen **1 + 8 + 23 = 32 bit**, vagyis négy bájt. A következő levezetések a normál, véges, nem nulla számokra vonatkoznak. A nulla és más különleges esetek szabályait később külön tárgyaljuk. Ez összesen **1 + 8 + 23 = 32 bit**, vagyis négy bájt. A következő levezetések a normál, véges, nem nulla számokra vonatkoznak. A nulla és más különleges esetek szabályait később külön tárgyaljuk.
Line 277: Line 256:
 A normalizált bináris alak mindig ''1,''-gyel kezdődik. Ezt az első 1-est ezért nem szükséges külön eltárolni: visszaolvasáskor automatikusan eléírjuk a tárolt törtbiteknek. A normalizált bináris alak mindig ''1,''-gyel kezdődik. Ezt az első 1-est ezért nem szükséges külön eltárolni: visszaolvasáskor automatikusan eléírjuk a tárolt törtbiteknek.
  
-Például az ''1,10101'' szignifikandból csak az ''10101'' rész kerül a törtrészmezőbe. A hiányzó helyeket jobbról nullákkal töltjük ki.+Például az ''1,10101'' szignifikansból csak az ''10101'' rész kerül a törtrészmezőbe. A hiányzó helyeket jobbról nullákkal töltjük ki.
  
-Az elhagyott első 1-est **rejtett vezető bitnek** nevezik. Emiatt a 23 tárolt törtbit a normál számoknál **24 értékes bináris jegyet** biztosít. A szignifikand és a tárolt törtrészmező tehát nem pontosan ugyanaz.+Az elhagyott első 1-est **rejtett vezető bitnek** nevezik. Emiatt a 23 tárolt törtbit a normál számoknál **24 értékes bináris jegyet** biztosít. A szignifikans és a tárolt törtrészmező tehát nem pontosan ugyanaz.
  
 === Hogyan tárolunk negatív kitevőt? === === Hogyan tárolunk negatív kitevőt? ===
Line 309: Line 288:
 **13,25<sub>10</sub> = 1101,01<sub>2</sub> = 1,10101<sub>2</sub> × 2<sup>3</sup>**. **13,25<sub>10</sub> = 1101,01<sub>2</sub> = 1,10101<sub>2</sub> × 2<sup>3</sup>**.
  
-A valódi kitevő tehát **3**, a szignifikand **1,10101**.+A valódi kitevő tehát **3**, a szignifikáns **1,10101**.
  
 === 3. lépés: a kitevőmező === === 3. lépés: a kitevőmező ===
Line 345: Line 324:
   - A kitevőmező ''10000010'', vagyis 130. A valódi kitevő 130 − 127 = 3.   - A kitevőmező ''10000010'', vagyis 130. A valódi kitevő 130 − 127 = 3.
   - A törtmező elé visszaírjuk a rejtett 1-est: ''1,10101''.   - A törtmező elé visszaírjuk a rejtett 1-est: ''1,10101''.
-  - A szignifikand értéke 1 + 1/2 + 1/8 + 1/32 = 1,65625.+  - A szignifikáns értéke 1 + 1/2 + 1/8 + 1/32 = 1,65625.
   - Megszorozzuk 2<sup>3</sup>-nal: 1,65625 × 8 = 13,25.   - Megszorozzuk 2<sup>3</sup>-nal: 1,65625 × 8 = 13,25.
   - Alkalmazzuk a negatív előjelet: **−13,25**.   - Alkalmazzuk a negatív előjelet: **−13,25**.
Line 370: Line 349:
 | ''0'' | ''01111100'' | ''01000000000000000000000'' | | ''0'' | ''01111100'' | ''01000000000000000000000'' |
  
-Visszaolvasva a szignifikand 1,25, a kettes hatvány 1/8, ezért az eredmény **1,25 / 8 = 0,15625**.+Visszaolvasva a szignifikáns 1,25, a kettes hatvány 1/8, ezért az eredmény **1,25 / 8 = 0,15625**.
  
 ==== 12. Miért nem minden szám tárolható pontosan? ==== ==== 12. Miért nem minden szám tárolható pontosan? ====
Line 487: Line 466:
   - Csak az előjelbit változik 0-ról 1-re.   - 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 0,1 bináris alakja végtelen szakaszos tört, a tárolható bitek száma pedig véges.
-  - A tartomány a nagyságrendet korlátozza, a szignifikand hossza a pontosságot. Nagy értékeknél a szomszédos tárolható számok között egynél nagyobb távolság is lehet.+  - A tartomány a nagyságrendet korlátozza, a szignifikáns hossza pedig a pontosságot. Nagy értékeknél a szomszédos tárolható számok között egynél nagyobb távolság is lehet.
  
 ==== Források és további olvasnivaló ==== ==== Források és további olvasnivaló ====
Line 494: Line 473:
   * [[https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html|David Goldberg: What Every Computer Scientist Should Know About Floating-Point Arithmetic]]   * [[https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html|David Goldberg: What Every Computer Scientist Should Know About Floating-Point Arithmetic]]
  
-A jegyzet az egész számok és az IEEE 754 bináris formátumainak alapjait tárgyalja. A szabvány további formátumaira és részletes műveleti szabályaira nem tér ki. 
  
 +<html>
 +<div id="szam-demo">
 +  <style>
 +    #szam-demo {
 +      max-width: 1000px;
 +      margin: 20px auto;
 +      padding: 22px;
 +      box-sizing: border-box;
 +      border: 1px solid #cbd5e1;
 +      border-radius: 14px;
 +      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: 7px;
 +      background: white;
 +      color: #172033;
 +      cursor: pointer;
 +    }
 +    #szam-demo button:hover { background: #e2e8f0; }
 +    #szam-demo button:focus-visible,
 +    #szam-demo input:focus-visible {
 +      outline: 3px solid #2563eb;
 +      outline-offset: 2px;
 +    }
 +    #szam-demo .navigation,
 +    #szam-demo .controls,
 +    #szam-demo .presets {
 +      display: flex;
 +      flex-wrap: wrap;
 +      gap: 8px;
 +      align-items: center;
 +      margin-bottom: 15px;
 +    }
 +    #szam-demo .navigation button[aria-pressed="true"] {
 +      background: #1e40af;
 +      border-color: #1e40af;
 +      color: white;
 +    }
 +    #szam-demo input[type="text"],
 +    #szam-demo input[type="number"] {
 +      width: 180px;
 +      max-width: 100%;
 +      padding: 8px;
 +      border: 1px solid #94a3b8;
 +      border-radius: 6px;
 +      background: white;
 +      color: #172033;
 +    }
 +    #szam-demo input[type="range"] {
 +      display: block;
 +      width: 100%;
 +      margin: 18px 0;
 +      accent-color: #1e40af;
 +    }
 +    #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="true"] {
 +      background: #1e40af;
 +      color: white;
 +      border-color: #1e40af;
 +    }
 +    #szam-demo .bit small {
 +      display: block;
 +      font: 11px Arial, sans-serif;
 +    }
 +    #szam-demo .result {
 +      margin: 14px 0;
 +      padding: 14px;
 +      border-left: 4px solid #2563eb;
 +      border-radius: 5px;
 +      background: #eaf1ff;
 +      overflow-wrap: anywhere;
 +    }
 +    #szam-demo .mono {
 +      font-family: Consolas, monospace;
 +      overflow-wrap: anywhere;
 +    }
 +    #szam-demo .error {
 +      color: #a61b1b;
 +      font-weight: bold;
 +    }
 +    #szam-demo .hint {
 +      color: #475569;
 +      font-size: 14px;
 +    }
 +    #szam-demo .field {
 +      margin-top: 16px;
 +      padding: 12px;
 +      border-radius: 8px;
 +      background: white;
 +      border: 1px solid #dbe3ed;
 +    }
 +    #szam-demo .field-title { font-weight: bold; }
 +    #szam-demo [hidden] { display: none !important; }
 +    @media (max-width: 500px) {
 +      #szam-demo { padding: 12px; }
 +      #szam-demo .bit { width: 38px; }
 +    }
 +  </style>
 +
 +  <div class="navigation" aria-label="Demonstráció kiválasztása">
 +    <button type="button" data-panel="integer" aria-pressed="true">
 +      Negatív egész számok
 +    </button>
 +    <button type="button" data-panel="float" aria-pressed="false">
 +      IEEE 754 lebegőpontos számok
 +    </button>
 +  </div>
 +
 +  <section data-section="integer">
 +    <h3>Nyolc bit – kétféle értelmezés</h3>
 +    <p>
 +      Kattints a bitekre! Ugyanazt a bitsorozatot előjel nélküli
 +      egészként és kettes komplemens szerint is értelmezzük.
 +    </p>
 +
 +    <div class="controls">
 +      <label for="szam-int-input">Előjeles érték:</label>
 +      <input id="szam-int-input" type="number"
 +             min="-128" max="127" step="1" value="-5">
 +      <button type="button" data-action="set-integer">Beállítás</button>
 +    </div>
 +
 +    <input data-role="int-slider" type="range"
 +           min="-128" max="127" step="1" value="-5"
 +           aria-label="Előjeles egész szám">
 +
 +    <div class="presets">
 +      <button type="button" data-int="-128">−128</button>
 +      <button type="button" data-int="-5">−5</button>
 +      <button type="button" data-int="-1">−1</button>
 +      <button type="button" data-int="0">0</button>
 +      <button type="button" data-int="5">+5</button>
 +      <button type="button" data-int="127">+127</button>
 +    </div>
 +
 +    <div data-role="int-bits" class="bits"
 +         aria-label="Nyolcbites bitminta"></div>
 +
 +    <div class="result" aria-live="polite">
 +      <div>Előjel nélkül: <strong data-role="unsigned"></strong></div>
 +      <div>Kettes komplemens szerint:
 +        <strong data-role="signed"></strong>
 +      </div>
 +      <div data-role="int-equation" class="mono"></div>
 +    </div>
 +
 +    <p data-role="int-explanation"></p>
 +
 +    <div class="controls">
 +      <button type="button" data-action="increment">
 +        Adjunk hozzá 1-et!
 +      </button>
 +      <button type="button" data-action="negate">
 +        Bitek megfordítása és +1
 +      </button>
 +    </div>
 +
 +    <p data-role="int-message" aria-live="polite"></p>
 +
 +    <p class="hint">
 +      Próbáld ki: állíts be 127-et, majd adj hozzá 1-et!
 +      A demonstráció nyolc bitet tart meg.
 +    </p>
 +  </section>
 +
 +  <section data-section="float" hidden>
 +    <h3>Hogyan lesz egy számból 32 bit?</h3>
 +    <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>
 +
 +    <div class="controls">
 +      <label for="szam-float-input">Szám:</label>
 +      <input id="szam-float-input" type="text"
 +             value="-13,25" spellcheck="false">
 +      <button type="button" data-action="set-float">Átalakítás</button>
 +    </div>
 +
 +    <div class="presets">
 +      <button type="button" data-float="-13.25">−13,25</button>
 +      <button type="button" data-float="0.15625">0,15625</button>
 +      <button type="button" data-float="0.1">0,1</button>
 +      <button type="button" data-float="16777217">16 777 217</button>
 +      <button type="button" data-float="0">+0</button>
 +      <button type="button" data-float="-0">−0</button>
 +      <button type="button" data-float="Infinity">+∞</button>
 +      <button type="button" data-float="NaN">NaN</button>
 +    </div>
 +
 +    <p data-role="float-message" aria-live="polite"></p>
 +
 +    <div class="field">
 +      <div class="field-title">1. Előjel – 1 bit</div>
 +      <div data-role="sign-bits" class="bits"></div>
 +      <div data-role="sign-description"></div>
 +    </div>
 +
 +    <div class="field">
 +      <div class="field-title">2. Kitevő – 8 bit</div>
 +      <div data-role="exponent-bits" class="bits"></div>
 +      <div data-role="exponent-description"></div>
 +    </div>
 +
 +    <div class="field">
 +      <div class="field-title">3. Törtrész – 23 bit</div>
 +      <div data-role="fraction-bits" class="bits"></div>
 +      <div data-role="fraction-description"></div>
 +    </div>
 +
 +    <div class="result" aria-live="polite">
 +      <div>Típus: <strong data-role="float-class"></strong></div>
 +      <div data-role="float-formula" class="mono"></div>
 +      <div>
 +        Tárolt érték:
 +        <strong data-role="float-value" class="mono"></strong>
 +      </div>
 +      <div class="hint">
 +        A véges, nem nulla értéket 17 értékes decimális jegyre írjuk ki.
 +      </div>
 +    </div>
 +
 +    <p class="hint">
 +      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>
 +  </section>
 +
 +  <noscript>A demonstráció használatához engedélyezett JavaScript szükséges.</noscript>
 +
 +  <script>
 +  (function () {
 +    "use strict";
 +
 +    const root = document.getElementById("szam-demo");
 +    if (!root || root.dataset.initialized) return;
 +    root.dataset.initialized = "true";
 +
 +    const el = name => root.querySelector('[data-role="' + name + '"]');
 +    const intInput = root.querySelector("#szam-int-input");
 +    const floatInput = root.querySelector("#szam-float-input");
 +
 +    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 "NaN";
 +      if (value === Infinity) return "+∞";
 +      if (value === -Infinity) return "−∞";
 +      if (Object.is(value, -0)) return "−0";
 +      return String(value).replace(".", ",");
 +    }
 +
 +    function preciseText(value) {
 +      if (!Number.isFinite(value) || value === 0) {
 +        return numberText(value);
 +      }
 +      return value.toPrecision(17).replace(".", ",");
 +    }
 +
 +    function makeBit(container, position, handler, weight) {
 +      const button = document.createElement("button");
 +      button.type = "button";
 +      button.className = "bit";
 +
 +      const digit = document.createElement("span");
 +      button.appendChild(digit);
 +
 +      if (weight !== undefined) {
 +        const label = document.createElement("small");
 +        label.textContent = weight;
 +        button.appendChild(label);
 +      }
 +
 +      button.addEventListener("click", handler);
 +      container.appendChild(button);
 +
 +      return {button, digit, position};
 +    }
 +
 +    const intBits = [];
 +    for (let p = 7; p >= 0; p--) {
 +      intBits.push(makeBit(
 +        el("int-bits"),
 +        p,
 +        function () {
 +          byte ^= 1 << p;
 +          clearIntegerMessage();
 +          renderInteger();
 +        },
 +        p === 7 ? "−128" : String(2 ** p)
 +      ));
 +    }
 +
 +    function clearIntegerMessage() {
 +      el("int-message").textContent = "";
 +      el("int-message").className = "";
 +    }
 +
 +    function renderInteger() {
 +      const value = signedValue();
 +
 +      intInput.value = value;
 +      el("int-slider").value = value;
 +
 +      intBits.forEach(item => {
 +        const bit = (byte >>> item.position) & 1;
 +        item.digit.textContent = bit;
 +        item.button.setAttribute("aria-pressed", String(bit === 1));
 +        item.button.setAttribute(
 +          "aria-label",
 +          item.position + ". bit: " + bit + ", átkapcsolás"
 +        );
 +      });
 +
 +      el("unsigned").textContent = byte;
 +      el("signed").textContent = value;
 +
 +      const terms = [];
 +      for (let p = 7; p >= 0; p--) {
 +        if ((byte >>> p) & 1) {
 +          terms.push(p === 7 ? "−128" : String(2 ** p));
 +        }
 +      }
 +      el("int-equation").textContent =
 +        (terms.length ? terms.join(" + ") : "0") + " = " + value;
 +
 +      el("int-explanation").textContent = value < 0
 +        ? "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("int-message").textContent =
 +          "−128 és 127 közötti egész számot adj meg!";
 +        el("int-message").className = "error";
 +        return;
 +      }
 +      byte = value & 255;
 +      clearIntegerMessage();
 +      renderInteger();
 +    }
 +
 +    root.querySelector('[data-action="set-integer"]')
 +      .addEventListener("click", () => setInteger(intInput.valueAsNumber));
 +
 +    intInput.addEventListener("keydown", event => {
 +      if (event.key === "Enter") setInteger(intInput.valueAsNumber);
 +    });
 +
 +    el("int-slider").addEventListener("input", event => {
 +      setInteger(Number(event.target.value));
 +    });
 +
 +    root.querySelectorAll("[data-int]").forEach(button => {
 +      button.addEventListener("click", () => {
 +        setInteger(Number(button.dataset.int));
 +      });
 +    });
 +
 +    root.querySelector('[data-action="increment"]')
 +      .addEventListener("click", () => {
 +        const before = signedValue();
 +        byte = (byte + 1) & 255;
 +        renderInteger();
 +
 +        el("int-message").className = before === 127 ? "error" : "";
 +        el("int-message").textContent = before === 127
 +          ? "Túlcsordulás! 127 + 1 = 128, de ez nem fér 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="negate"]')
 +      .addEventListener("click", () => {
 +        const before = signedValue();
 +        const original = byte.toString(2).padStart(8, "0");
 +        const inverted = ((~byte) & 255).toString(2).padStart(8, "0");
 +
 +        byte = ((~byte) + 1) & 255;
 +        renderInteger();
 +
 +        el("int-message").className = before === -128 ? "error" : "";
 +        el("int-message").textContent =
 +          original + " → megfordítva: " + inverted +
 +          " → +1: " + byte.toString(2).padStart(8, "0") +
 +          (before === -128
 +            ? ". Túlcsordulás: +128 nem ábrázolható ezen a nyolc biten."
 +            : ". Az új előjeles érték: " + signedValue() + ".");
 +      });
 +
 +    const floatBits = [];
 +
 +    function addFloatBits(container, high, low) {
 +      for (let p = high; p >= low; p--) {
 +        floatBits.push(makeBit(container, p, function () {
 +          word = (word ^ (1 << p)) >>> 0;
 +          el("float-message").textContent =
 +            "Kézzel módosított bitminta; az értéket most ebből olvassuk vissza.";
 +          el("float-message").className = "";
 +          renderFloat(true);
 +        }));
 +      }
 +    }
 +
 +    addFloatBits(el("sign-bits"), 31, 31);
 +    addFloatBits(el("exponent-bits"), 30, 23);
 +    addFloatBits(el("fraction-bits"), 22, 0);
 +
 +    function renderFloat(updateInput) {
 +      view.setUint32(0, word, false);
 +      const value = view.getFloat32(0, false);
 +
 +      const sign = word >>> 31;
 +      const exponent = (word >>> 23) & 255;
 +      const fraction = word & 0x7fffff;
 +      const fractionBits = fraction.toString(2).padStart(23, "0");
 +
 +      floatBits.forEach(item => {
 +        const bit = (word >>> item.position) & 1;
 +        item.digit.textContent = bit;
 +        item.button.setAttribute("aria-pressed", String(bit === 1));
 +        item.button.setAttribute(
 +          "aria-label",
 +          item.position + ". bit: " + bit + ", átkapcsolás"
 +        );
 +      });
 +
 +      el("sign-description").textContent = sign
 +        ? "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("fraction-description").textContent =
 +        "A 23 bit előjel nélküli egész értéke: F = " + fraction + ".";
 +
 +      let classification;
 +      let formula;
 +
 +      if (exponent === 255) {
 +        el("exponent-description").textContent =
 +          "E = 255: különleges érték; nem alkalmazzuk az E − 127 szabályt.";
 +
 +        classification = fraction === 0 ? "Végtelen" : "NaN – nem szám";
 +        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("exponent-description").textContent =
 +          "E = 0: nulla vagy szubnormális szám. A skálázás 2⁻¹²⁶, " +
 +          "a vezető bit 0.";
 +
 +        classification = fraction === 0 ? "Előjeles nulla" : "Szubnormális szám";
 +        formula = fraction === 0
 +          ? "Nulla kitevő és nulla törtrész: " + numberText(value)
 +          : (sign ? "−" : "+") + "0," + fractionBits +
 +            "₂ × 2^(−126)";
 +      } else {
 +        const actualExponent = exponent - 127;
 +        classification = "Normál szám";
 +
 +        el("exponent-description").textContent =
 +          "E = " + exponent + "; valódi kitevő: " +
 +          exponent + " − 127 = " + actualExponent + ".";
 +
 +        formula = (sign ? "−" : "+") + "1," + fractionBits +
 +          "₂ × 2^(" + actualExponent + ")";
 +
 +        el("fraction-description").textContent +=
 +          " A rejtett 1-essel a szignifikáns: " +
 +          numberText(1 + fraction / 8388608) + ".";
 +      }
 +
 +      el("float-class").textContent = classification;
 +      el("float-formula").textContent = formula;
 +      el("float-value").textContent = preciseText(value);
 +
 +      if (updateInput) {
 +        floatInput.value = Number.isNaN(value)
 +          ? "NaN"
 +          : Object.is(value, -0) ? "-0" : String(value);
 +      }
 +    }
 +
 +    function convertFloat() {
 +      const text = floatInput.value.trim().replace("−", "-").replace(",", ".");
 +      let value;
 +
 +      if (/^[+-]?nan$/i.test(text)) {
 +        value = NaN;
 +      } else if (/^\+?(infinity|∞)$/i.test(text)) {
 +        value = Infinity;
 +      } else if (/^-(infinity|∞)$/i.test(text)) {
 +        value = -Infinity;
 +      } else if (/^[+-]?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i.test(text)) {
 +        value = Number(text);
 +        if (!Number.isFinite(value)) {
 +          el("float-message").textContent =
 +            "A bemenet a böngésző számkezelési tartományán kívül esik.";
 +          el("float-message").className = "error";
 +          return;
 +        }
 +      } else {
 +        el("float-message").textContent =
 +          "Számot adj meg, például −13,25 vagy 1e-40! Infinity és NaN is megadható.";
 +        el("float-message").className = "error";
 +        return;
 +      }
 +
 +      view.setFloat32(0, value, false);
 +      word = view.getUint32(0, false);
 +      const stored = view.getFloat32(0, false);
 +
 +      el("float-message").className = "";
 +      if (Number.isFinite(value) && !Number.isFinite(stored)) {
 +        el("float-message").textContent =
 +          "Binary32-túlcsordulás: a véges bemenetből végtelen lett.";
 +        el("float-message").className = "error";
 +      } else if (value !== 0 && stored === 0) {
 +        el("float-message").textContent =
 +          "A szám túl kicsi: binary32-re kerekítve nulla lett.";
 +      } else if (Number.isFinite(value) && stored !== value) {
 +        el("float-message").textContent =
 +          "Kerekítés történt a böngésző által beolvasott szám binary32-re alakításakor.";
 +      } else {
 +        el("float-message").textContent =
 +          "A beolvasott érték binary32-re alakításakor nem történt további kerekítés.";
 +      }
 +
 +      if (!Number.isFinite(value)) {
 +        el("float-message").textContent = "Különleges érték beállítva.";
 +      }
 +
 +      renderFloat(false);
 +    }
 +
 +    root.querySelector('[data-action="set-float"]')
 +      .addEventListener("click", convertFloat);
 +
 +    floatInput.addEventListener("keydown", event => {
 +      if (event.key === "Enter") convertFloat();
 +    });
 +
 +    root.querySelectorAll("[data-float]").forEach(button => {
 +      button.addEventListener("click", () => {
 +        floatInput.value = button.dataset.float;
 +        convertFloat();
 +      });
 +    });
 +
 +    root.querySelectorAll("[data-panel]").forEach(button => {
 +      button.addEventListener("click", () => {
 +        root.querySelectorAll("[data-panel]").forEach(tab => {
 +          tab.setAttribute("aria-pressed", String(tab === button));
 +        });
 +        root.querySelectorAll("[data-section]").forEach(section => {
 +          section.hidden = section.dataset.section !== button.dataset.panel;
 +        });
 +      });
 +    });
 +
 +    renderInteger();
 +    convertFloat();
 +  })();
 +  </script>
 +</div>
 +</html>
tanszek/oktatas/szamitastechnika/szamabrazolas.1790885487.txt.gz · Last modified: by knehez