---
# System prepended metadata

title: CS23B001 - Lab 8 Report

---

# 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
```