User Tools

Site Tools


tanszek:oktatas:techcomm:encoding_integers

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:techcomm:encoding_integers [2024/09/30 18:21] – kneheztanszek:oktatas:techcomm:encoding_integers [2026/10/12 18:32] (current) – knehez
Line 1: Line 1:
-==== Integer representations =====+===== Integer representations =====
  
-We have a byte, which consists of 8 bits. What integers can be represented using a byte? The answer depends on how we interpret the bits. With 8 bits, we have \( 2^8 = 256 \) different possible combinations, so 256 different values can be stored.+Computers store data as bits. Each bit can have one of two values: 0 or 1. A byte consists of 8 bits, so it has 2<sup>8</sup> = 256 possible bit patterns.
  
-For example, one everyday use of these 8 bits is to represent __unsigned integers__ in the range [0..255]. These numbers are all //non-negative//; this data type is typically referred to as a byte or an __unsigned short int__ in many programming languages.+**A bit pattern does not tell us its meaning by itself.** We also need to know how the bits should be interpreted.
  
-**Example:** how to add two binary numbers?+For example, the same eight bits can represent an unsigned integer or a signed integer. An **unsigned integer** can be zero or positive. A **signed integer** can also be negative.
  
-     10110110   (182) +We will use 8-bit examples throughout this section. The same principles apply to larger groups of bits.
-  +  01101101   (109) +
-  ------------ +
-    100100011   (291)+
  
-But what happens if we need to store negative numbers as well? How can we represent both positive and negative integers?+=== Unsigned integers ===
  
-One common solution is reserving the //highest-order bit// (the most significant bit, also known as the 7th bit, since counting starts from zero) as a sign bit. This bit indicates the sign of the number, and it is often denoted as the sign bit, 's'.+In ordinary decimal notation, digit positions have weights of 1, 10, 100, and so on, starting from the right.
  
-  * If the sign bit (s) is 0, the number is positive or zero. +In binary notation, the weights are powers of two:
-  * If the sign bit (s) is 1, the number is negative.+
  
-The remaining **7 bits** are used to represent the magnitude of the number, either positive or negative. This method allows us to represent integers in the range [-128..+127]. In other words:+^ Bit position ^ 7 ^ 6 ^ 5 ^ 4 ^ 3 ^ 2 ^ 1 ^ 0 ^ 
 +| Weight | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
  
-  * If the sign bit is 0, the number is in the range [0 .. 127]. +Bit positions are numbered from zero, starting on the right. Bit 7 is therefore the leftmost bit in a byte. It is called the **most significant bit**, because it has the greatest weight in unsigned representation.
-  * If the sign bit is 1, the number is in the range [-1 .. -128].+
  
-This is a simple form of sign-magnitude representation.+To find the value of an unsigned binary number, add the weights of the positions containing a 1.
  
-=== Two's Complement Representation ===+**Example: interpret the bit pattern 10011100.**
  
-In modern computing, __two's complement__ is a more commonly used method for representing signed integers. In this system, the highest-order bit is also used as the sign bit, but the way negative numbers are stored differs. Here’s how it works:+<code> 
 +Bits:       1    0    0    1    1    1    0    0 
 +Weights:  128   64   32   16    8    4    2    1
  
-  * The most significant bit is still used as the sign bit, where 0 indicates a positive number, and 1 indicates a negative number. +Value = 128 + 16 + 8 + 4 = 156 
-  * However, negative numbers are represented by taking the two’s complement of their absolute value. This involves inverting all the bits and then adding 1 to the result.+</code>
  
-**Example**: Encode -5 with two's complement method with 8 bits.+The smallest unsigned 8-bit value is 00000000, which represents 0. The largest is 11111111:
  
-  * The number 5 in binary (in an 8-bit system) is represented as **00000101** +<code> 
-  * Invert the bits: **11111010** +128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 = 255 
-  * Add one: **11111011**+</code>
  
-**Example**: Add -5 + 7 in 8 bits binary format+Therefore, the range of an **8-bit unsigned integer is 0 to 255**.
  
-Now we can add the two binary numbers:+Programming-language names for integer types vary. A type called ''unsigned short int'' should not be assumed to have 8 bits. 
 + 
 +=== Converting a decimal integer to binary === 
 + 
 +To convert a non-negative decimal integer to binary, repeatedly divide it by 2. At each step, record the integer quotient and the remainder. 
 + 
 +The remainder is always 0 or 1. 
 + 
 +**Example: convert 156 to binary.** 
 + 
 +^ Division ^ Integer quotient ^ Remainder ^ 
 +| 156 ÷ 2 | 78 | 0 | 
 +| 78 ÷ 2 | 39 | 0 | 
 +| 39 ÷ 2 | 19 | 1 | 
 +| 19 ÷ 2 | 9 | 1 | 
 +| 9 ÷ 2 | 4 | 1 | 
 +| 4 ÷ 2 | 2 | 0 | 
 +| 2 ÷ 2 | 1 | 0 | 
 +| 1 ÷ 2 | 0 | 1 | 
 + 
 +Stop when the quotient becomes zero. Read the remainders **from bottom to top**:
  
 <code> <code>
-  11111011   (-5 in two's complement) +156 in decimal = 10011100 in binary
-+ 00000111   (7) +
------------- +
-  00000010   (2)+
 </code> </code>
  
-This is the reason why we are using the special two's complement form. Without using this encoding, we cannot add negative and positive numbers.+We can check the result using the positional weights: 
 + 
 +<code> 
 +128 + 16 + 8 + 4 = 156 
 +</code> 
 + 
 +=== Binary addition and the available number of bits === 
 + 
 +Binary addition follows rules similar to decimal addition. However, a binary digit can only be 0 or 1. 
 + 
 +<code> 
 +0 + 0 =  0 
 +0 + 1 =  1 
 +1 + 0 =  1 
 +1 + 1 = 10 
 +</code> 
 + 
 +In the last case, we write 0 in the current position and carry 1 to the next position on the left. 
 + 
 +**Example: add 182 and 109.** 
 + 
 +<code> 
 +   10110110   (182) 
 ++  01101101   (109) 
 +----------- 
 +  100100011   (291) 
 +</code> 
 + 
 +The correct mathematical result needs **9 bits**. It cannot fit in an unsigned 8-bit value. 
 + 
 +If only the lowest 8 bits are retained, the stored pattern is: 
 + 
 +<code> 
 +00100011   (35) 
 +</code> 
 + 
 +This is an example of **unsigned overflow**: the mathematical result is outside the available range. 
 + 
 +Here, retaining only 8 bits gives 291 − 256 = 35. The extra bit on the left is called the **carry-out**. 
 + 
 +=== Representing negative integers: sign and magnitude === 
 + 
 +How can we include negative numbers without adding a separate minus-sign character? 
 + 
 +One possible approach is to reserve the leftmost bit for the sign: 
 + 
 +  * 0 means non-negative. 
 +  * 1 means negative. 
 + 
 +The remaining seven bits store the **magnitude**, which is the absolute value of the number. 
 + 
 +This method is called **sign-magnitude representation**. 
 + 
 +**Example: represent +5 and −5.** 
 + 
 +<code> 
 +          Sign   Magnitude 
 ++5:         0     0000101 
 +−5:         1     0000101 
 +</code> 
 + 
 +Seven magnitude bits can represent values from 0 to 127. Therefore, the signed range is **−127 to +127**. 
 + 
 +There are two bit patterns for zero: 
 + 
 +<code> 
 +00000000   (+0) 
 +10000000   (−0) 
 +</code> 
 + 
 +The 256 bit patterns therefore represent only 255 different numerical values. 
 + 
 +Sign-magnitude representation is easy to understand, but arithmetic requires special handling of the signs and magnitudes. 
 + 
 +For example, ordinary binary addition does not directly give the correct answer for −5 + 7: 
 + 
 +<code> 
 +  10000101   (−5 in sign-magnitude representation) 
 ++ 00000111   (+7) 
 +---------- 
 +  10001100   (−12 in sign-magnitude representation) 
 +</code> 
 + 
 +The expected result is +2. To get it, an arithmetic procedure for sign-magnitude numbers must account for the signs and subtract the magnitudes. 
 + 
 +=== Two's complement representation === 
 + 
 +A widely used alternative for signed integers is **two's complement representation**. 
 + 
 +Its main advantage is that you can add positive and negative integers using the same binary addition procedure as with unsigned integers. 
 + 
 +Let us first see what bit pattern would make this possible. 
 + 
 +We want: 
 + 
 +<code> 
 +−5 + 5 = 0 
 +</code> 
 + 
 +When only 8 bits are retained, the value 256 becomes 0 because its binary representation needs a ninth bit: 
 + 
 +<code> 
 +256 = 100000000 in binary 
 +Lowest 8 bits: 00000000 
 +</code> 
 + 
 +Therefore, we can use the bit pattern for 256 − 5 = 251 to represent −5: 
 + 
 +<code> 
 +  11111011   (251 when interpreted as unsigned) 
 ++ 00000101   (5) 
 +---------- 
 + 100000000 
 + 
 +Retain 8 bits: 
 +  00000000   (0) 
 +</code> 
 + 
 +This is the key idea behind 8-bit two's complement representation. 
 + 
 +**For a negative integer −m, the unsigned value of its 8-bit two's complement pattern is 256 − m.** 
 + 
 +For this representation, m can range from 1 to 128. Positive integers and zero use their ordinary binary patterns, with a leftmost bit of 0. 
 + 
 +=== Encoding a negative integer === 
 + 
 +A convenient way to obtain the two's complement representation of a negative integer is: 
 + 
 +  - Write its positive magnitude in binary, using the chosen number of bits. 
 +  - Invert every bit: replace 0 with 1 and 1 with 0. 
 +  - Add 1, keeping the chosen number of bits. 
 + 
 +**Example: encode −5 using 8 bits.** 
 + 
 +<code> 
 ++5:               00000101 
 +Invert all bits:  11111010 
 +Add 1:            11111011 
 +</code> 
 + 
 +Therefore, **−5 is represented by 11111011**. 
 + 
 +The number of bits matters. Always establish the width before applying this procedure. 
 + 
 +=== Interpreting a two's complement bit pattern === 
 + 
 +In 8-bit two's complement representation, the positional weights are: 
 + 
 +^ Bit position ^ 7 ^ 6 ^ 5 ^ 4 ^ 3 ^ 2 ^ 1 ^ 0 ^ 
 +| Weight | **−128** | 64 | 32 | 16 | 8 | 4 | 2 | 1 | 
 + 
 +Only the leftmost bit's weight differs from the unsigned case. 
 + 
 +Consequently: 
 + 
 +  * If the leftmost bit is 0, the number is zero or positive. 
 +  * If the leftmost bit is 1, the number is negative. 
 + 
 +However, **the remaining seven bits do not represent the magnitude of a negative number**. 
 + 
 +**Example: interpret 11111011.** 
 + 
 +<code> 
 +−128 + 64 + 32 + 16 + 8 + 2 + 1 = −5 
 +</code> 
 + 
 +Another method is to read the entire pattern as an unsigned value. If the leftmost bit is 1, subtract 256: 
 + 
 +<code> 
 +Unsigned interpretation:          251 
 +Two's complement interpretation:  251 − 256 = −5 
 +</code> 
 + 
 +The interpretation changes the value; the stored bits remain the same. 
 + 
 +=== Range and important bit patterns === 
 + 
 +^ Bit pattern ^ Unsigned value ^ Two's complement value ^ 
 +| 00000000 | 0 | 0 | 
 +| 00000001 | 1 | 1 | 
 +| 01111111 | 127 | 127 | 
 +| 10000000 | 128 | −128 | 
 +| 11111011 | 251 | −5 | 
 +| 11111111 | 255 | −1 | 
 + 
 +The range of an **8-bit two's complement integer is −128 to +127**. 
 + 
 +There is only one representation of zero. The range contains one more negative value than positive values. 
 + 
 +In general, with n bits: 
 + 
 +  * Unsigned range: 0 to 2<sup>n</sup> − 1. 
 +  * Two's complement range: −2<sup>n−1</sup> to 2<sup>n−1</sup> − 1. 
 + 
 +=== Adding positive and negative integers === 
 + 
 +**Example: calculate −5 + 7 using 8-bit two's complement representation.** 
 + 
 +<code> 
 +   11111011   (−5) 
 ++  00000111   (+7) 
 +----------- 
 +  100000010 
 +</code> 
 + 
 +Retain the lowest 8 bits: 
 + 
 +<code> 
 +00000010   (+2) 
 +</code> 
 + 
 +The result is correct. 
 + 
 +This fixed-width calculation discards the carry-out. **A carry-out does not, by itself, indicate signed overflow.** 
 + 
 +Two's complement makes addition convenient, but the result must still fit in the available signed range. 
 + 
 +=== Signed overflow === 
 + 
 +**Signed overflow** occurs when the mathematical result is outside the representable signed range. 
 + 
 +For example, 100 and 60 both fit in an 8-bit signed integer, but their sum, 160, does not: 
 + 
 +<code> 
 +  01100100   (+100) 
 ++ 00111100   (+60) 
 +---------- 
 +  10100000   (−96 when interpreted as two's complement) 
 +</code> 
 + 
 +Adding two positive numbers has produced a pattern representing a negative number. This indicates signed overflow. 
 + 
 +For two's complement addition, overflow occurs when: 
 + 
 +  * Two positive operands produce a negative result. 
 +  * Two negative operands produce a non-negative result. 
 + 
 +Adding operands with opposite signs cannot cause signed overflow. 
 + 
 +Notice that the example has no carry-out, yet signed overflow occurs. In the earlier example, −5 + 7 had a carry-out but no signed overflow. 
 + 
 +**Carry-out and signed overflow describe different conditions.** 
 + 
 +These examples describe fixed-width binary arithmetic. Programming languages may handle out-of-range calculations differently, so you must also check their rules when writing a program. 
 + 
 +=== Check your understanding === 
 + 
 +  - What range can an unsigned 8-bit integer represent? 
 +  - Why does 8-bit sign-magnitude representation have two zeros? 
 +  - Encode −12 using 8-bit two's complement representation. 
 +  - Interpret 11110110 as an unsigned integer and as a two's complement integer. 
 +  - Can +156 be represented as an 8-bit two's complement integer? 
 +  - What happens when +127 and +1 are added using 8-bit two's complement arithmetic? 
 + 
 +**Answers** 
 + 
 +  - 0 to 255. 
 +  - The sign bit can be either 0 or 1 while all magnitude bits are zero. 
 +  - +12 is 00001100. Inverting gives 11110011; adding 1 gives **11110100**. 
 +  - Unsigned: **246**. Two's complement: 246 − 256 = **−10**. 
 +  - No. The greatest positive value is +127. The unsigned pattern for 156, 10011100, represents −100 when interpreted as two's complement. 
 +  - The resulting pattern is **10000000**, which represents −128. The mathematical result, +128, is outside the range, so signed overflow occurs. 
 + 
 +<html> 
 +<div class="tc-lab"> 
 +  <style> 
 +    .tc-lab { 
 +      max-width: 900px; 
 +      margin: 24px auto; 
 +      padding: 24px; 
 +      border: 1px solid #cbd5e1; 
 +      border-radius: 16px; 
 +      background: #f8fafc; 
 +      color: #172033; 
 +      font: 16px/1.6 system-ui, sans-serif; 
 +    } 
 +    .tc-lab * { box-sizing: border-box; } 
 +    .tc-lab h2, .tc-lab h3 { color: #172033; margin: 0 0 12px; } 
 +    .tc-lab p { margin: 10px 0; } 
 +    .tc-lab button, .tc-lab input { font: inherit; } 
 +    .tc-lab button { 
 +      padding: 8px 14px; 
 +      border: 1px solid #94a3b8; 
 +      border-radius: 8px; 
 +      background: #fff; 
 +      color: #172033; 
 +      cursor: pointer; 
 +    } 
 +    .tc-lab button:hover { background: #e2e8f0; } 
 +    .tc-lab button:focus-visible, .tc-lab input:focus-visible { 
 +      outline: 3px solid #2563eb; 
 +      outline-offset: 3px; 
 +    } 
 +    .tc-lab .tc-card { 
 +      padding: 20px; 
 +      margin-top: 18px; 
 +      border: 1px solid #dbe3ee; 
 +      border-radius: 12px; 
 +      background: #fff; 
 +    } 
 +    .tc-lab .tc-controls { 
 +      display: flex; 
 +      gap: 10px; 
 +      align-items: center; 
 +      flex-wrap: wrap; 
 +      margin: 12px 0; 
 +    } 
 +    .tc-lab input[type="number"] { 
 +      width: 110px; 
 +      padding: 7px 10px; 
 +      border: 1px solid #94a3b8; 
 +      border-radius: 7px; 
 +      background: #fff; 
 +      color: #172033; 
 +    } 
 +    .tc-lab input[type="range"] { width: 100%; margin: 12px 0; } 
 +    .tc-lab .tc-bits { 
 +      display: grid; 
 +      grid-template-columns: repeat(8, minmax(0, 1fr)); 
 +      gap: 6px; 
 +      margin: 16px 0; 
 +    } 
 +    .tc-lab .tc-bit-cell { text-align: center; min-width: 0; } 
 +    .tc-lab .tc-bit { 
 +      display: block; 
 +      width: 100%; 
 +      padding: 10px 0; 
 +      font: bold 25px/1.2 monospace; 
 +      border: 2px solid #cbd5e1; 
 +      background: #f1f5f9; 
 +    } 
 +    .tc-lab .tc-bit[aria-pressed="true"] { 
 +      background: #dbeafe; 
 +      border-color: #2563eb; 
 +      color: #1e40af; 
 +    } 
 +    .tc-lab .tc-sign .tc-bit[aria-pressed="true"] { 
 +      background: #ffedd5; 
 +      border-color: #c2410c; 
 +      color: #9a3412; 
 +    } 
 +    .tc-lab .tc-weight { 
 +      display: block; 
 +      font-size: 13px; 
 +      padding-top: 5px; 
 +      color: #475569; 
 +    } 
 +    .tc-lab .tc-results { 
 +      display: flex; 
 +      flex-wrap: wrap; 
 +      gap: 12px; 
 +      margin: 12px 0; 
 +    } 
 +    .tc-lab .tc-result { 
 +      flex: 1 1 180px; 
 +      padding: 12px; 
 +      border-radius: 8px; 
 +      background: #eff6ff; 
 +    } 
 +    .tc-lab .tc-value { display: block; font-size: 28px; font-weight: bold; } 
 +    .tc-lab .tc-mono { 
 +      font-family: ui-monospace, monospace; 
 +      white-space: pre-wrap; 
 +      overflow-wrap: anywhere; 
 +    } 
 +    .tc-lab .tc-note { color: #475569; font-size: 14px; } 
 +    .tc-lab .tc-feedback { 
 +      margin-top: 12px; 
 +      padding: 12px; 
 +      border-left: 4px solid #64748b; 
 +      background: #f1f5f9; 
 +    } 
 +    .tc-lab .tc-feedback[data-kind="success"] { 
 +      border-color: #15803d; 
 +      background: #f0fdf4; 
 +    } 
 +    .tc-lab .tc-feedback[data-kind="error"] { 
 +      border-color: #b45309; 
 +      background: #fffbeb; 
 +    } 
 +    .tc-lab .tc-primary { background: #1d4ed8; color: #fff; border-color: #1d4ed8; } 
 +    .tc-lab .tc-primary:hover { background: #1e40af; } 
 +    .tc-lab .tc-target { font-size: 30px; font-weight: bold; color: #1d4ed8; } 
 +    .tc-lab [hidden] { display: none !important; } 
 +    @media (max-width: 520px) { 
 +      .tc-lab { padding: 12px; } 
 +      .tc-lab .tc-card { padding: 12px; } 
 +      .tc-lab .tc-bits { gap: 3px; } 
 +      .tc-lab .tc-bit { font-size: 21px; } 
 +      .tc-lab .tc-weight { font-size: 11px; } 
 +    } 
 +  </style> 
 + 
 +  <h2>Two's Complement: Explore and Play</h2> 
 +  <p> 
 +    Eight bits can represent signed integers from <strong>−128 to +127</strong>. 
 +    Click the bits to see how the same pattern can have different meanings. 
 +  </p> 
 + 
 +  <section class="tc-card"> 
 +    <h3>1. Explore the bits</h3> 
 +    <div class="tc-controls"> 
 +      <label> 
 +        Signed decimal value: 
 +        <input data-role="number" type="number" min="-128" max="127" step="1" value="-5"> 
 +      </label> 
 +      <button type="button" data-preset="-128">−128</button> 
 +      <button type="button" data-preset="-5">−5</button> 
 +      <button type="button" data-preset="-1">−1</button> 
 +      <button type="button" data-preset="0">0</button> 
 +      <button type="button" data-preset="127">127</button> 
 +    </div> 
 + 
 +    <input data-role="slider" type="range" min="-128" max="127" value="-5" 
 +           aria-label="Signed decimal value"> 
 + 
 +    <div data-role="explore-bits" class="tc-bits"></div> 
 +    <p class="tc-note"> 
 +      The weights below the bits apply to two's complement. 
 +      The leftmost bit has weight <strong>−128</strong>. 
 +    </p> 
 + 
 +    <div class="tc-results" aria-live="polite"> 
 +      <div class="tc-result"> 
 +        Two's complement value 
 +        <span data-role="signed" class="tc-value"></span> 
 +      </div> 
 +      <div class="tc-result"> 
 +        Unsigned value 
 +        <span data-role="unsigned" class="tc-value"></span> 
 +      </div> 
 +    </div> 
 + 
 +    <div data-role="sum" class="tc-mono"></div> 
 +    <p data-role="interpretation"></p> 
 + 
 +    <div class="tc-controls"> 
 +      <button type="button" data-action="negate">Negate: invert bits and add 1</button> 
 +      <button type="button" data-action="increment">Add 1</button> 
 +    </div> 
 +    <div data-role="operation" class="tc-feedback tc-mono" 
 +         aria-live="polite">Try negating −5, or adding 1 to 127.</div> 
 +  </section> 
 + 
 +  <section class="tc-card"> 
 +    <h3>2. Build the negative number</h3> 
 +    <p> 
 +      Set the eight bits to encode this number in two's complement: 
 +      <span data-role="target" class="tc-target"></span> 
 +    </p> 
 +    <p>Click a bit to switch between 0 and 1. Then check your answer.</p> 
 + 
 +    <div data-role="game-bits" class="tc-bits"></div> 
 + 
 +    <div class="tc-controls"> 
 +      <button type="button" data-action="check" class="tc-primary">Check answer</button> 
 +      <button type="button" data-action="hint">Show a hint</button> 
 +      <button type="button" data-action="solution">Show solution</button> 
 +      <button type="button" data-action="next">Next number</button> 
 +    </div> 
 + 
 +    <p data-role="score" class="tc-note"></p> 
 +    <div data-role="feedback" class="tc-feedback" aria-live="polite"></div> 
 +    <div data-role="hint" class="tc-feedback tc-mono" hidden></div> 
 +    <div data-role="solution" class="tc-feedback tc-mono" hidden></div> 
 +  </section> 
 + 
 +  <script> 
 +    (function () { 
 +      "use strict"; 
 + 
 +      const root = document.currentScript.parentElement; 
 +      const find = role => root.querySelector('[data-role="' + role + '"]'); 
 +      const weights = [-128, 64, 32, 16, 8, 4, 2, 1]; 
 + 
 +      let word = 251; 
 +      let gameWord = 0; 
 +      let target = -5; 
 +      let solved = false; 
 +      let revealed = false; 
 +      let score = 0; 
 +      let completed = 0; 
 + 
 +      const binary = n => (n & 255).toString(2).padStart(8, "0"); 
 +      const signed = n => n >= 128 ? n - 256 : n; 
 +      const display = n => n < 0 ? "−" + Math.abs(n) : String(n); 
 + 
 +      function createBits(container, onToggle) { 
 +        const buttons = []; 
 +        weights.forEach((weight, index) => { 
 +          const cell = document.createElement("div"); 
 +          cell.className = "tc-bit-cell" + (index === 0 ? " tc-sign" : ""); 
 + 
 +          const button = document.createElement("button"); 
 +          button.type = "button"; 
 +          button.className = "tc-bit"; 
 +          button.textContent = "0"; 
 +          button.setAttribute("aria-pressed", "false"); 
 +          button.addEventListener("click", () => onToggle(7 - index)); 
 + 
 +          const label = document.createElement("span"); 
 +          label.className = "tc-weight"; 
 +          label.textContent = display(weight); 
 + 
 +          cell.append(button, label); 
 +          container.append(cell); 
 +          buttons.push(button); 
 +        }); 
 +        return buttons; 
 +      } 
 + 
 +      function updateBits(buttons, value) { 
 +        buttons.forEach((button, index) => { 
 +          const bit = (value >> (7 - index)) & 1; 
 +          button.textContent = bit; 
 +          button.setAttribute("aria-pressed", bit ? "true" : "false"); 
 +          button.setAttribute( 
 +            "aria-label", 
 +            "Bit " + (7 - index) + ", weight " + weights[index] + 
 +            ", value " + bit + ". Click to toggle." 
 +          ); 
 +        }); 
 +      } 
 + 
 +      function feedback(element, message, kind) { 
 +        element.textContent = message; 
 +        element.dataset.kind = kind || ""; 
 +      } 
 + 
 +      const exploreButtons = createBits(find("explore-bits"), bit => { 
 +        word ^= 1 << bit; 
 +        renderExplore(); 
 +        feedback(find("operation"), "Bit changed. Compare the two interpretations."); 
 +      }); 
 + 
 +      const gameButtons = createBits(find("game-bits"), bit => { 
 +        gameWord ^= 1 << bit; 
 +        updateBits(gameButtons, gameWord); 
 +        if (!solved && !revealed) { 
 +          feedback(find("feedback"), "Ready? Check your answer."); 
 +        } 
 +      }); 
 + 
 +      function renderExplore() { 
 +        const value = signed(word); 
 +        find("number").value = value; 
 +        find("slider").value = value; 
 +        find("signed").textContent = display(value); 
 +        find("unsigned").textContent = word; 
 +        updateBits(exploreButtons, word); 
 + 
 +        const terms = weights.filter((weight, index) => word & (1 << (7 - index))); 
 +        find("sum").textContent = 
 +          (terms.length ? terms.map(display).join(" + ") : "0") + 
 +          " = " + display(value); 
 + 
 +        find("interpretation").textContent = value < 0 
 +          ? "The leftmost bit is 1. Read the pattern as unsigned, then subtract 256: " + 
 +            word + " − 256 = " + display(value) + "." 
 +          : "The leftmost bit is 0. Unsigned and two's complement interpretations agree."; 
 +      } 
 + 
 +      find("number").addEventListener("input", function () { 
 +        const value = this.valueAsNumber; 
 +        const valid = Number.isInteger(value) && value >= -128 && value <= 127; 
 +        this.setAttribute("aria-invalid", valid ? "false" : "true"); 
 +        if (!valid) { 
 +          feedback(find("operation"), "Enter an integer from −128 to 127.", "error"); 
 +          return; 
 +        } 
 +        word = value & 255; 
 +        renderExplore(); 
 +        feedback(find("operation"), "Value updated. Try changing an individual bit."); 
 +      }); 
 + 
 +      function setValue(value) { 
 +        word = value & 255; 
 +        find("number").setAttribute("aria-invalid", "false"); 
 +        renderExplore(); 
 +        feedback(find("operation"), "Value updated. Try changing an individual bit."); 
 +      } 
 + 
 +      find("slider").addEventListener("input", event => { 
 +        setValue(Number(event.target.value)); 
 +      }); 
 + 
 +      root.querySelectorAll("[data-preset]").forEach(button => { 
 +        button.addEventListener("click", () => setValue(Number(button.dataset.preset))); 
 +      }); 
 + 
 +      root.querySelector('[data-action="negate"]').addEventListener("click", () => { 
 +        const before = word; 
 +        const value = signed(before); 
 +        const inverted = before ^ 255; 
 +        word = (inverted + 1) & 255; 
 +        renderExplore(); 
 + 
 +        let message = 
 +          "Original:  " + binary(before) + "  (" + display(value) + ")\n" + 
 +          "Invert:    " + binary(inverted) + "\n" + 
 +          "Add 1:     " + binary(word) + "  (" + display(signed(word)) + ")"; 
 + 
 +        if (value === -128) { 
 +          message += "\nOverflow: +128 cannot be represented in 8-bit two's complement." + 
 +                     "\nKeeping 8 bits leaves the pattern for −128."; 
 +        } else if (value === 0) { 
 +          message += "\nZero remains zero. The carry-out is discarded."; 
 +        } else { 
 +          message += "\nThe sign has changed; the magnitude is unchanged."; 
 +        } 
 +        feedback(find("operation"), message, value === -128 ? "error" : ""); 
 +      }); 
 + 
 +      root.querySelector('[data-action="increment"]').addEventListener("click", () => { 
 +        const before = word; 
 +        const value = signed(before); 
 +        const total = before + 1; 
 +        word = total & 255; 
 +        renderExplore(); 
 + 
 +        let message = 
 +          "  " + binary(before) + "  (" + display(value) + ")\n" + 
 +          "+ 00000001  (+1)\n" + 
 +          "= " + total.toString(2).padStart(8, "0") + "\n" + 
 +          "Keep 8 bits: " + binary(word) + "  (" + display(signed(word)) + ")"; 
 + 
 +        if (value === 127) { 
 +          message += "\nSigned overflow: 128 is outside the range −128 to 127." + 
 +                     "\nThere is no carry-out, but the signed result is out of range."; 
 +        } else if (total > 255) { 
 +          message += "\nThe carry-out is discarded. −1 + 1 = 0: no signed overflow."; 
 +        } else { 
 +          message += "\nThe result fits: no signed overflow."; 
 +        } 
 +        feedback(find("operation"), message, value === 127 ? "error" : ""); 
 +      }); 
 + 
 +      function updateScore() { 
 +        find("score").textContent = 
 +          "Solved without revealing the solution: " + score + 
 +          " | Completed challenges: " + completed + 
 +          ". Hints are allowed."; 
 +      } 
 + 
 +      function startChallenge(first) { 
 +        const previous = target; 
 +        if (!first) { 
 +          do { 
 +            target = -(1 + Math.floor(Math.random() * 128)); 
 +          } while (target === previous); 
 +        } 
 + 
 +        gameWord = 0; 
 +        solved = false; 
 +        revealed = false; 
 +        find("target").textContent = display(target); 
 +        find("hint").hidden = true; 
 +        find("solution").hidden = true; 
 +        updateBits(gameButtons, gameWord); 
 +        feedback(find("feedback"), "Build the bit pattern, then press Check answer."); 
 +        updateScore(); 
 +      } 
 + 
 +      root.querySelector('[data-action="check"]').addEventListener("click", () => { 
 +        if (signed(gameWord) === target) { 
 +          if (!solved && !revealed) { 
 +            score++; 
 +            completed++; 
 +          } 
 +          solved = true; 
 +          updateScore(); 
 +          feedback( 
 +            find("feedback"), 
 +            "Correct! " + binary(gameWord) + " represents " + display(target) + 
 +            ". Press Next number for another challenge.", 
 +            "success" 
 +          ); 
 +        } else { 
 +          feedback( 
 +            find("feedback"), 
 +            binary(gameWord) + " represents " + display(signed(gameWord)) + 
 +            ", not " + display(target) + ". Adjust the bits and try again.", 
 +            "error" 
 +          ); 
 +        } 
 +      }); 
 + 
 +      root.querySelector('[data-action="hint"]').addEventListener("click", () => { 
 +        const magnitude = Math.abs(target); 
 +        find("hint").hidden = false; 
 +        find("hint").textContent = 
 +          "Start with the magnitude " + magnitude + ": " + binary(magnitude) + 
 +          "\nInvert all eight bits, then add 1." + 
 +          "\nThe answer must begin with 1 because the target is negative." + 
 +          (target === -128 
 +            ? "\nHere, 10000000 is the unsigned magnitude 128 used in the calculation;" + 
 +              "\n+128 itself is outside the signed 8-bit range." 
 +            : ""); 
 +      }); 
 + 
 +      root.querySelector('[data-action="solution"]').addEventListener("click", () => { 
 +        if (!solved && !revealed) completed++; 
 +        revealed = true; 
 +        const magnitude = Math.abs(target); 
 +        const inverted = magnitude ^ 255; 
 +        const answer = (inverted + 1) & 255; 
 + 
 +        find("solution").hidden = false; 
 +        find("solution").textContent = 
 +          "Magnitude: " + binary(magnitude) + "  (" + magnitude + " unsigned)\n" + 
 +          "Invert:    " + binary(inverted) + "\n" + 
 +          "Add 1:     " + binary(answer) + "  (" + display(target) + " signed)\n\n" + 
 +          "Check: " + answer + " − 256 = " + display(target); 
 + 
 +        feedback(find("feedback"), "Solution shown. Press Next number when you are ready."); 
 +        updateScore(); 
 +      }); 
 + 
 +      root.querySelector('[data-action="next"]').addEventListener("click", () => { 
 +        startChallenge(false); 
 +      }); 
 + 
 +      renderExplore(); 
 +      startChallenge(true); 
 +    })(); 
 +  </script> 
 +</div> 
 +</html>
tanszek/oktatas/techcomm/encoding_integers.1727720494.txt.gz · Last modified: by knehez