# CS23B001 - Lab 8 Report ## Q1 To convert 0.1 from decimal system to binary, we perform the following steps: 1. 0.1 x 2 = 0.2 -> Integer part: 0, Fractional part: 0.2 2. 0.2 x 2 = 0.4 -> Integer part: 0, Fractional part: 0.4 3. 0.4 x 2 = 0.8 -> Integer part: 0, Fractional part: 0.8 4. 0.8 x 2 = 1.6 -> Integer part: 1, Fractional part: 0.6 5. 0.6 x 2 = 1.2 -> Integer part: 1, Fractional part: 0.2 6. 0.2 x 2 = 0.4 -> Integer part: 0, Fractional part: 0.4 7. 0.4 x 2 = 0.8 -> Integer part: 0, Fractional part: 0.8 8. 0.8 x 2 = 1.6 -> Integer part: 1, Fractional part: 0.6 9. 0.6 x 2 = 1.2 -> Integer part: 1, Fractional part: 0.2 10. 0.2 x 2 = 0.4 -> Integer part: 0, Fractional part: 0.4 11. 0.4 x 2 = 0.8 -> Integer part: 0, Fractional part: 0.8 If we observe the integer parts, we get *00011001100...* with the sequence *1100* repeating indefinitely. Therefore, 0.1<sub>ten</sub> is 0.00011001100110011...<sub>2</sub> ## Q2 To convert a decimal number to binary using IEEE 754 standard, we follow the below steps: 1. Convert 0.1<sub>ten</sub> to binary: - From Q1, we found out that 0.1<sub>ten</sub> is 0.00011001100110011...<sub>2</sub> 2. Normalize the binary fraction: - Using scientific notation, shift the binary point to the right until there's exactly one non-zero digit before the point. - 0.00011001100110011...<sub>2</sub> = 1.1001100110011..<sub>2</sub> x 2<sup>-4</sup> - Here, we define two terms: - **Mantissa:** 1.1001100110011... - **Exponent:** -4 3. Determine the Sign Bit: - Since 0.1 is positive, the signed bit is 0. 4. IEEE uses an excess-127 biasing system, where: - E = Actual exponent + 127 - Here, E = (-4) + 127 = 123 - Converting 123<sub>10</sub> to binary, 123<sub>10</sub> to 01111011<sub>2</sub> (8 bits) 5. Form the Mantissa (32 bits): - IEEE stores only the fractional part (after the leading 1) in 23 bits: - Mantissa = 10011001100110011001100 6. Assemble the IEEE 754 Representation: | Sign (1 bit) | Exponent (8 bits) | Mantissa (23 bits) | | :------------: | :-----------------: | :--------------------: | | 0 | 01111011 | 10011001100110011001100 | Thus, the IEEE 754 single-precision representation of 0.1<sub>ten</sub> in 32-bit format is: **0 01111011 10011001100110011001100** ## Q3 We perform the following steps to convert 0.2<sub>ten</sub> to binary using IEEE 754 standard: 1. Convert 0.1<sub>ten</sub> to binary: 0.2 * 2 = 0.4 -> Integer part: 0, Fractional part: 0.4 0.4 * 2 = 0.8 -> Integer part: 0, Fractional part: 0.8 0.8 * 2 = 1.6 -> Integer part: 1, Fractional part: 0.6 0.6 * 2 = 1.2 -> Integer part: 1, Fractional part: 0.2 0.2 * 2 = 0.4 -> Integer part: 0, Fractional part: 0.4 If we observe the integer parts, we get *0011001100...* with the sequence *0011* repeating indefinitely. Therefore, 0.2<sub>ten</sub> is 0.0011001100110011...<sub>2</sub> 2. Normalize the binary fraction: 0.001100110011...<sub>2</sub> = 1.100110011...<sub>2</sub> x 2<sup>-3</sup> **Matnisaa:** 1.1001100110011... **Exponent:** -3 3. Determine the Sign Bit: Since 0.2 is positive, the sign bit is 0 4. Apply the excess-127 biasing system: E = (-3) + 127 = 124 124<sub>10</sub> = 01111100<sub>2</sub> (8 bits) 5. From the Mantissa: Mantissa = 10011001100110011001100 (23 bits) 6. Assemble the IEEE 754 Representation: | Sign (1 bit) | Exponent (8 bits) | Mantissa (23 bits) | | :------------: | :-----------------: | :--------------------: | | 0 | 01111100 | 10011001100110011001100 | Thus, the IEEE 754 single-precision representation of 0.2<sub>ten</sub> in 32-bit format is: **0 01111100 10011001100110011001100** 7. Find the numerical exponent from the 8-bit exponent. Binary of **01111100** = **124**. This exponent is stored in bias-127 form as **124 - 127 = -3**. 8. Decoding the Mantissa: 1.100110011001100<sub>2</sub> is converted into decimal as 1 + 1x2<sup>-1</sup> + 0x2<sup>-2</sup> + 0x2<sup>-3</sup> + 1x2<sup>-4</sup> + ... $\approx$ 1.5999999046325684 $\approx$ 1.6 9. We combine the values using the formula: Value = (-1)<sup>sign</sup> x significand x 2<sup>exponent</sup> Here, value = (-1)<sup>0</sup> x 1.6 x 2<sup>-3</sup> = 1.6 x (1/8) = 0.2 ## Q4 **Design:** My floating-point representation will consist of three components: 1. **Sign bit:** 0 if the number if positive, 1 if the number is negative 2. **Exponent:** Represents the position of the decimal point 3. **Mantissa:** Represents the significant digits of the number **Storage:** We use three memory locations for each floating-point number: 1. 1 bit for the *Sign Bit* 2. 8 bits for the *Exponent* 3. 23 bits for the *Mantissa* **Normalization:** We normalize our numbers to have the form 1.xxx x 2<sup>y</sup>, where: 1. 1.xxx represents the *mantissa* 2. y represents the *exponent* Since the leading digit in the normalized form is always 1 (*hidden bit*), we don't need to store it. **Bias for Exponent:** To handle both positive and negative exponents, we used a bias of 127, which basically means we add 127 to the current exponent. *Stored exponent = Actual exponent + 127* **Register-based Implementation:** For floating-point numbers, we can use a **two-register** approach: 1. **Integer Register:** Stores the integer part of the numbet (before the decimal point) 2. **Fraction Register:** Stores the fractional part (after the decimal point) **Register Specifications:** 1. **Integer Register:** 32-bit signed register 2. **Fraction Register:** 32-bit unsigned integer representing fractional values - For the fraction register, we'll use a fixed-point representation where the value represents the fraction as if divided by 10<sup>n</sup>, where n is the number of decimal places we want to support. - For example, with n=3, the fraction 0.391 would be stored as 391. **Example:** 1. **5.391:** - Integer Register: 5 - Fractional Register: 391 2. **3.012:** - Integer Register: 3 - Fractional Register: 012 (To maintain precision, we use 3 decimal places for all numbers, hence we store 0.012 as 012 and not as 12) **Floating-Point Addition using Registers:** 1. Add the integer registers 2. Add the fractional registers 3. Handle any overflow from the fractional part to the integer part In our example: 1. **Add integer parts:** 5 + 3 = 8 2. **Add fractional parts:** 391 + 012 = 403 3. **Check for overflow:** Since 403 < 1000 (where 1000 represents 1.000), there's no overflow to handle 4. **Result:** - Integer Register: 8 - Fractional Register: 403 - This gives us 8.403 which is the sum of 5.391 and 3.012 **Handling Overflow:** 1. Consider the addition of 5.9 and 3.2. 2. Integer: 5 + 3 = 8 3. Fractional: 900 + 200 = 1100 > 1000 4. Integer: 8 + 1 = 9 (Add the overflow) 5. Fraction: 1100 - 1000 = 100 6. **Result:** 9.1 ## Q5 - The assembly code to add 2 floating point numbers and store the sum in a memory location is given below. - Comments have been used to explain the functioning of the code. - IEEE 754 single-precision floating-point addition has been manually implemented using integer registers due to the inability of my Ripes simulator to support floating-point instructions. ``` .data num1: .word 0b00111101110011001100110011001101 # IEEE 754 representation of 0.1 num2: .word 0b00111110010011001100110011001101 # IEEE 754 representation of 0.2 result: .word 0 # Space to store the final result .text .globl main main: # Load the floating-point numbers (stored as integers) la t0, num1 lw t1, 0(t0) # Load num1 into t1 la t0, num2 lw t2, 0(t0) # Load num2 into t2 # Step 1: Extract sign, exponent, and mantissa li t3, 0x80000000 # Bit mask to isolate the sign bit and t4, t1, t3 # Get the sign of num1 (t4 = sign1) and t5, t2, t3 # Get the sign of num2 (t5 = sign2) li t3, 0x7F800000 # Bit mask for the exponent bits and t6, t1, t3 # Extract exponent of num1 srli t6, t6, 23 # Shift right to get the actual exponent value and s7, t2, t3 # Extract exponent of num2 srli s7, s7, 23 # Shift right to get the actual exponent value li t3, 0x007FFFFF # Bit mask for the mantissa and s1, t1, t3 # Extract mantissa of num1 and s2, t2, t3 # Extract mantissa of num2 li t3, 0x00800000 # Adding implicit 1 at the start of the mantissa or s1, s1, t3 or s2, s2, t3 # Step 2: Align exponents by shifting the smaller number align_exponents: beq t6, s7, add_mantissas # If exponents are equal, move to addition blt t6, s7, shift_mantissa1 srli s2, s2, 1 # Shift right to align the mantissa addi s7, s7, 1 # Increase the smaller exponent j align_exponents shift_mantissa1: srli s1, s1, 1 # Shift the other mantissa instead addi t6, t6, 1 # Increase the exponent j align_exponents # Step 3: Add or subtract the mantissas add_mantissas: add s3, s1, s2 # Adding mantissas (assuming both numbers have the same sign for now) # Step 4: Normalize the result to fit IEEE 754 format normalize: li t3, 0x01000000 # Check if the result overflowed bge s3, t3, shift_right li t3, 0x00800000 # Check if the result is too small bge s3, t3, pack_result slli s3, s3, 1 # Shift left to normalize addi t6, t6, -1 # Adjust exponent j normalize shift_right: srli s3, s3, 1 # Shift right if needed addi t6, t6, 1 # Adjust exponent # Step 5: Pack the result back into IEEE 754 format pack_result: slli t6, t6, 23 # Put the exponent back in place li t3, 0x007FFFFF # Mask to keep only mantissa bits and s3, s3, t3 # Keep only the mantissa or t0, t6, s3 # Combine exponent and mantissa or t0, t0, t4 # Add the sign bit back # Store the computed result la t1, result sw t0, 0(t1) # Exit the program li a7, 10 # Exit system call ecall ```