tanszek:oktatas:techcomm:encoding_integers
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| tanszek:oktatas:techcomm:encoding_integers [2024/09/30 18:54] – [How to convert decimal integers to binary form] knehez | tanszek: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 | + | 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</ |
| - | For example, one everyday use of these 8 bits is to represent __unsigned integers__ in the range [0..255]. These numbers are all // | + | **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. |
| - | | + | We will use 8-bit examples throughout this section. The same principles apply to larger groups of bits. |
| - | + 01101101 | + | |
| - | | + | |
| - | 100100011 | + | |
| - | But what happens if we need to store negative numbers as well? How can we represent both positive and negative | + | === Unsigned |
| - | One common solution is reserving the // | + | In ordinary decimal notation, digit positions have weights |
| - | * 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 | + | Bit positions are numbered from zero, starting on the right. Bit 7 is therefore |
| - | | + | |
| - | 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' | + | < |
| + | Bits: 1 0 0 1 1 1 0 0 | ||
| + | Weights: | ||
| - | * 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. | + | </ |
| - | **Example**: | + | The smallest unsigned |
| - | * The number 5 in binary (in an 8-bit system) is represented as **00000101** | + | < |
| - | * Invert the bits: **11111010** | + | 128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 = 255 |
| - | * Add one: **11111011** | + | </ |
| - | **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 | + | Programming-language names for integer types vary. A type called '' |
| + | |||
| + | === 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 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**: | ||
| < | < | ||
| - | 11111011 | + | 156 in decimal = 10011100 in binary |
| - | + 00000111 | + | |
| - | ------------ | + | |
| - | 00000010 | + | |
| </ | </ | ||
| - | This is the reason why we are using the special two's complement | + | We can check the result using the positional weights: |
| + | |||
| + | < | ||
| + | 128 + 16 + 8 + 4 = 156 | ||
| + | </ | ||
| + | |||
| + | === 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. | ||
| + | |||
| + | < | ||
| + | 0 + 0 = 0 | ||
| + | 0 + 1 = 1 | ||
| + | 1 + 0 = 1 | ||
| + | 1 + 1 = 10 | ||
| + | </ | ||
| + | |||
| + | 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.** | ||
| + | |||
| + | < | ||
| + | | ||
| + | + 01101101 | ||
| + | ----------- | ||
| + | 100100011 | ||
| + | </ | ||
| + | |||
| + | 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: | ||
| + | |||
| + | < | ||
| + | 00100011 | ||
| + | </ | ||
| + | |||
| + | This is an example of **unsigned overflow**: | ||
| + | |||
| + | 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 | ||
| + | |||
| + | * 0 means non-negative. | ||
| + | * 1 means negative. | ||
| + | |||
| + | The remaining seven bits store the **magnitude**, | ||
| + | |||
| + | This method is called **sign-magnitude representation**. | ||
| + | |||
| + | **Example: represent +5 and −5.** | ||
| + | |||
| + | < | ||
| + | Sign | ||
| + | +5: | ||
| + | −5: | ||
| + | </ | ||
| + | |||
| + | 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: | ||
| + | |||
| + | < | ||
| + | 00000000 | ||
| + | 10000000 | ||
| + | </ | ||
| + | |||
| + | The 256 bit patterns therefore represent only 255 different numerical values. | ||
| + | |||
| + | Sign-magnitude representation is easy to understand, but arithmetic requires | ||
| + | |||
| + | For example, ordinary binary addition does not directly give the correct answer for −5 + 7: | ||
| + | |||
| + | < | ||
| + | 10000101 | ||
| + | + 00000111 | ||
| + | ---------- | ||
| + | 10001100 | ||
| + | </ | ||
| + | |||
| + | 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 | ||
| + | |||
| + | Its main advantage is that you can add positive and negative integers | ||
| + | |||
| + | Let us first see what bit pattern would make this possible. | ||
| + | |||
| + | We want: | ||
| + | |||
| + | < | ||
| + | −5 + 5 = 0 | ||
| + | </ | ||
| + | |||
| + | When only 8 bits are retained, the value 256 becomes 0 because its binary representation needs a ninth bit: | ||
| + | |||
| + | < | ||
| + | 256 = 100000000 in binary | ||
| + | Lowest 8 bits: 00000000 | ||
| + | </ | ||
| + | |||
| + | Therefore, we can use the bit pattern for 256 − 5 = 251 to represent −5: | ||
| + | |||
| + | < | ||
| + | 11111011 | ||
| + | + 00000101 | ||
| + | ---------- | ||
| + | | ||
| + | |||
| + | Retain 8 bits: | ||
| + | 00000000 | ||
| + | </ | ||
| + | |||
| + | This is the key idea behind 8-bit two's complement representation. | ||
| + | |||
| + | **For a negative | ||
| + | |||
| + | For this representation, | ||
| + | |||
| + | === 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.** | ||
| + | |||
| + | < | ||
| + | +5: | ||
| + | Invert all bits: 11111010 | ||
| + | Add 1: 11111011 | ||
| + | </ | ||
| + | |||
| + | 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, | ||
| + | |||
| + | ^ 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.** | ||
| + | |||
| + | < | ||
| + | −128 + 64 + 32 + 16 + 8 + 2 + 1 = −5 | ||
| + | </ | ||
| + | |||
| + | Another method is to read the entire pattern as an unsigned value. If the leftmost bit is 1, subtract 256: | ||
| + | |||
| + | < | ||
| + | Unsigned interpretation: | ||
| + | Two's complement interpretation: | ||
| + | </ | ||
| + | |||
| + | 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< | ||
| + | * Two's complement range: −2< | ||
| + | |||
| + | === Adding positive and negative integers === | ||
| + | |||
| + | **Example: calculate −5 + 7 using 8-bit two's complement representation.** | ||
| + | |||
| + | < | ||
| + | | ||
| + | + 00000111 | ||
| + | ----------- | ||
| + | 100000010 | ||
| + | </ | ||
| + | |||
| + | Retain the lowest 8 bits: | ||
| + | |||
| + | < | ||
| + | 00000010 | ||
| + | </ | ||
| + | |||
| + | 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: | ||
| + | |||
| + | < | ||
| + | 01100100 | ||
| + | + 00111100 | ||
| + | ---------- | ||
| + | 10100000 | ||
| + | </ | ||
| + | |||
| + | Adding two positive numbers | ||
| + | |||
| + | 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, | ||
| + | |||
| + | === 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**, | ||
| + | |||
| + | < | ||
| + | <div class=" | ||
| + | < | ||
| + | .tc-lab { | ||
| + | max-width: 900px; | ||
| + | margin: 24px auto; | ||
| + | padding: 24px; | ||
| + | border: 1px solid #cbd5e1; | ||
| + | border-radius: | ||
| + | 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: | ||
| + | background: #fff; | ||
| + | color: #172033; | ||
| + | cursor: pointer; | ||
| + | } | ||
| + | .tc-lab button: | ||
| + | .tc-lab button: | ||
| + | outline: 3px solid #2563eb; | ||
| + | outline-offset: | ||
| + | } | ||
| + | .tc-lab .tc-card { | ||
| + | padding: 20px; | ||
| + | margin-top: 18px; | ||
| + | border: 1px solid #dbe3ee; | ||
| + | border-radius: | ||
| + | background: #fff; | ||
| + | } | ||
| + | .tc-lab .tc-controls { | ||
| + | display: flex; | ||
| + | gap: 10px; | ||
| + | align-items: | ||
| + | flex-wrap: wrap; | ||
| + | margin: 12px 0; | ||
| + | } | ||
| + | .tc-lab input[type=" | ||
| + | width: 110px; | ||
| + | padding: 7px 10px; | ||
| + | border: 1px solid #94a3b8; | ||
| + | border-radius: | ||
| + | background: #fff; | ||
| + | color: #172033; | ||
| + | } | ||
| + | .tc-lab input[type=" | ||
| + | .tc-lab .tc-bits { | ||
| + | display: grid; | ||
| + | grid-template-columns: | ||
| + | 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=" | ||
| + | background: #dbeafe; | ||
| + | border-color: | ||
| + | color: #1e40af; | ||
| + | } | ||
| + | .tc-lab .tc-sign .tc-bit[aria-pressed=" | ||
| + | background: #ffedd5; | ||
| + | border-color: | ||
| + | color: #9a3412; | ||
| + | } | ||
| + | .tc-lab .tc-weight { | ||
| + | display: block; | ||
| + | font-size: 13px; | ||
| + | padding-top: | ||
| + | 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: | ||
| + | background: #eff6ff; | ||
| + | } | ||
| + | .tc-lab .tc-value { display: block; font-size: 28px; font-weight: | ||
| + | .tc-lab .tc-mono { | ||
| + | font-family: | ||
| + | white-space: | ||
| + | overflow-wrap: | ||
| + | } | ||
| + | .tc-lab .tc-note { color: #475569; font-size: 14px; } | ||
| + | .tc-lab .tc-feedback { | ||
| + | margin-top: 12px; | ||
| + | padding: 12px; | ||
| + | border-left: | ||
| + | background: #f1f5f9; | ||
| + | } | ||
| + | .tc-lab .tc-feedback[data-kind=" | ||
| + | border-color: | ||
| + | background: #f0fdf4; | ||
| + | } | ||
| + | .tc-lab .tc-feedback[data-kind=" | ||
| + | border-color: | ||
| + | background: #fffbeb; | ||
| + | } | ||
| + | .tc-lab .tc-primary { background: #1d4ed8; color: #fff; border-color: | ||
| + | .tc-lab .tc-primary: | ||
| + | .tc-lab .tc-target { font-size: 30px; font-weight: | ||
| + | .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; } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | < | ||
| + | <p> | ||
| + | Eight bits can represent signed integers from < | ||
| + | Click the bits to see how the same pattern can have different meanings. | ||
| + | </ | ||
| + | |||
| + | <section class=" | ||
| + | < | ||
| + | <div class=" | ||
| + | < | ||
| + | Signed decimal value: | ||
| + | <input data-role=" | ||
| + | </ | ||
| + | <button type=" | ||
| + | <button type=" | ||
| + | <button type=" | ||
| + | <button type=" | ||
| + | <button type=" | ||
| + | </ | ||
| + | |||
| + | <input data-role=" | ||
| + | | ||
| + | |||
| + | <div data-role=" | ||
| + | <p class=" | ||
| + | The weights below the bits apply to two's complement. | ||
| + | The leftmost bit has weight < | ||
| + | </ | ||
| + | |||
| + | <div class=" | ||
| + | <div class=" | ||
| + | Two's complement value | ||
| + | <span data-role=" | ||
| + | </ | ||
| + | <div class=" | ||
| + | Unsigned value | ||
| + | <span data-role=" | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | <div data-role=" | ||
| + | <p data-role=" | ||
| + | |||
| + | <div class=" | ||
| + | <button type=" | ||
| + | <button type=" | ||
| + | </ | ||
| + | <div data-role=" | ||
| + | | ||
| + | </ | ||
| + | |||
| + | <section class=" | ||
| + | < | ||
| + | <p> | ||
| + | Set the eight bits to encode this number in two's complement: | ||
| + | <span data-role=" | ||
| + | </ | ||
| + | < | ||
| + | |||
| + | <div data-role=" | ||
| + | |||
| + | <div class=" | ||
| + | <button type=" | ||
| + | <button type=" | ||
| + | <button type=" | ||
| + | <button type=" | ||
| + | </ | ||
| + | |||
| + | <p data-role=" | ||
| + | <div data-role=" | ||
| + | <div data-role=" | ||
| + | <div data-role=" | ||
| + | </ | ||
| + | |||
| + | < | ||
| + | (function () { | ||
| + | "use strict"; | ||
| + | |||
| + | const root = document.currentScript.parentElement; | ||
| + | const find = role => root.querySelector(' | ||
| + | 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, | ||
| + | const signed = n => n >= 128 ? n - 256 : n; | ||
| + | const display = n => n < 0 ? " | ||
| + | |||
| + | function createBits(container, | ||
| + | const buttons = []; | ||
| + | weights.forEach((weight, | ||
| + | const cell = document.createElement(" | ||
| + | cell.className = " | ||
| + | |||
| + | const button = document.createElement(" | ||
| + | button.type = " | ||
| + | button.className = " | ||
| + | button.textContent = " | ||
| + | button.setAttribute(" | ||
| + | button.addEventListener(" | ||
| + | |||
| + | const label = document.createElement(" | ||
| + | label.className = " | ||
| + | label.textContent = display(weight); | ||
| + | |||
| + | cell.append(button, | ||
| + | container.append(cell); | ||
| + | buttons.push(button); | ||
| + | }); | ||
| + | return buttons; | ||
| + | } | ||
| + | |||
| + | function updateBits(buttons, | ||
| + | buttons.forEach((button, | ||
| + | const bit = (value >> (7 - index)) & 1; | ||
| + | button.textContent = bit; | ||
| + | button.setAttribute(" | ||
| + | button.setAttribute( | ||
| + | " | ||
| + | "Bit " + (7 - index) + ", weight " + weights[index] + | ||
| + | ", value " + bit + ". Click to toggle." | ||
| + | ); | ||
| + | }); | ||
| + | } | ||
| + | |||
| + | function feedback(element, | ||
| + | element.textContent = message; | ||
| + | element.dataset.kind = kind || ""; | ||
| + | } | ||
| + | |||
| + | const exploreButtons = createBits(find(" | ||
| + | word ^= 1 << bit; | ||
| + | renderExplore(); | ||
| + | feedback(find(" | ||
| + | }); | ||
| + | |||
| + | const gameButtons = createBits(find(" | ||
| + | gameWord ^= 1 << bit; | ||
| + | updateBits(gameButtons, | ||
| + | if (!solved && !revealed) { | ||
| + | feedback(find(" | ||
| + | } | ||
| + | }); | ||
| + | |||
| + | function renderExplore() { | ||
| + | const value = signed(word); | ||
| + | find(" | ||
| + | find(" | ||
| + | find(" | ||
| + | find(" | ||
| + | updateBits(exploreButtons, | ||
| + | |||
| + | const terms = weights.filter((weight, | ||
| + | find(" | ||
| + | (terms.length ? terms.map(display).join(" | ||
| + | " = " + display(value); | ||
| + | |||
| + | find(" | ||
| + | ? "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(" | ||
| + | const value = this.valueAsNumber; | ||
| + | const valid = Number.isInteger(value) && value >= -128 && value <= 127; | ||
| + | this.setAttribute(" | ||
| + | if (!valid) { | ||
| + | feedback(find(" | ||
| + | return; | ||
| + | } | ||
| + | word = value & 255; | ||
| + | renderExplore(); | ||
| + | feedback(find(" | ||
| + | }); | ||
| + | |||
| + | function setValue(value) { | ||
| + | word = value & 255; | ||
| + | find(" | ||
| + | renderExplore(); | ||
| + | feedback(find(" | ||
| + | } | ||
| + | |||
| + | find(" | ||
| + | setValue(Number(event.target.value)); | ||
| + | }); | ||
| + | |||
| + | root.querySelectorAll(" | ||
| + | button.addEventListener(" | ||
| + | }); | ||
| + | |||
| + | root.querySelector(' | ||
| + | const before = word; | ||
| + | const value = signed(before); | ||
| + | const inverted = before ^ 255; | ||
| + | word = (inverted + 1) & 255; | ||
| + | renderExplore(); | ||
| + | |||
| + | let message = | ||
| + | " | ||
| + | " | ||
| + | "Add 1: " | ||
| + | |||
| + | if (value === -128) { | ||
| + | message += " | ||
| + | " | ||
| + | } else if (value === 0) { | ||
| + | message += " | ||
| + | } else { | ||
| + | message += "\nThe sign has changed; the magnitude is unchanged."; | ||
| + | } | ||
| + | feedback(find(" | ||
| + | }); | ||
| + | |||
| + | root.querySelector(' | ||
| + | const before = word; | ||
| + | const value = signed(before); | ||
| + | const total = before + 1; | ||
| + | word = total & 255; | ||
| + | renderExplore(); | ||
| + | |||
| + | let message = | ||
| + | " | ||
| + | "+ 00000001 | ||
| + | "= " + total.toString(2).padStart(8, | ||
| + | "Keep 8 bits: " + binary(word) + " | ||
| - | ==== How to convert decimal integers to binary form ==== | + | if (value |
| + | message += " | ||
| + | " | ||
| + | } 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(" | ||
| + | }); | ||
| - | Let’s convert | + | function updateScore() { |
| + | find(" | ||
| + | " | ||
| + | " | Completed challenges: " + completed + | ||
| + | ". Hints are allowed."; | ||
| + | } | ||
| - | ==== Step 1: Divide the decimal number by 2 ==== | + | function startChallenge(first) { |
| - | Start by dividing the decimal number (156) by 2 and keep track of the quotient and remainder. The remainder will be either 0 or 1, which forms the binary digits from bottom to top. | + | const previous |
| + | if (!first) { | ||
| + | do { | ||
| + | target | ||
| + | } while (target | ||
| + | } | ||
| - | | **Division** | **Quotient** | **Remainder** | | + | |
| - | | 156 ÷ 2 | 78 | 0 | + | |
| - | | 78 ÷ 2 | 39 | + | |
| - | | 39 ÷ 2 | 19 | 1 | | + | |
| - | | 19 ÷ 2 | 9 | 1 | | + | |
| - | | 9 ÷ 2 | 4 | 1 | | + | |
| - | | 4 ÷ 2 | 2 | 0 | | + | |
| - | | 2 ÷ 2 | 1 | 0 | | + | feedback(find(" |
| - | | 1 ÷ 2 | 0 | 1 | | + | updateScore(); |
| + | } | ||
| - | ==== Step 2: Write the binary digits | + | root.querySelector(' |
| - | To get the binary | + | if (signed(gameWord) |
| + | if (!solved && !revealed) { | ||
| + | score++; | ||
| + | completed++; | ||
| + | } | ||
| + | solved | ||
| + | | ||
| + | feedback( | ||
| + | find(" | ||
| + | " | ||
| + | ". Press Next number for another challenge." | ||
| + | " | ||
| + | ); | ||
| + | } else { | ||
| + | feedback( | ||
| + | find(" | ||
| + | binary(gameWord) + " represents " + display(signed(gameWord)) + | ||
| + | ", not " + display(target) + ". Adjust | ||
| + | " | ||
| + | ); | ||
| + | } | ||
| + | }); | ||
| - | **10011100₂** | + | root.querySelector(' |
| + | const magnitude = Math.abs(target); | ||
| + | find(" | ||
| + | find(" | ||
| + | "Start with the magnitude " + magnitude + ": " + binary(magnitude) + | ||
| + | " | ||
| + | "\nThe answer must begin with 1 because the target is negative." | ||
| + | (target === -128 | ||
| + | ? " | ||
| + | " | ||
| + | : "" | ||
| + | }); | ||
| - | ==== Verification ==== | + | root.querySelector(' |
| - | To verify, we can convert the binary number back to decimal: | + | if (!solved && !revealed) completed++; |
| + | revealed | ||
| + | const magnitude | ||
| + | const inverted | ||
| + | const answer = (inverted + 1) & 255; | ||
| - | | + | find(" |
| - | = 128 + 0 + 0 + 16 + 8 + 4 + 0 + 0 | + | find(" |
| - | | + | " |
| + | " | ||
| + | " | ||
| + | " | ||
| - | Hence, the binary representation of 156 is correct. | + | feedback(find(" |
| + | updateScore(); | ||
| + | }); | ||
| + | root.querySelector(' | ||
| + | startChallenge(false); | ||
| + | }); | ||
| + | renderExplore(); | ||
| + | startChallenge(true); | ||
| + | })(); | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
tanszek/oktatas/techcomm/encoding_integers.1727722468.txt.gz · Last modified: by knehez
