Question: #6249

CSC373 Computer System I Assignment #2 Complete Solution

CSC 373: Computer System I, 2013 Fall, Assignment #2

Last revised 2015 June 29

Purpose:
To let you demonstrate your ability to manipulate C integers by implementing floating-point addition with integer operations.

Assignment
Finish the program below that does floating point addition.

    Cut and paste the following:

    /*-------------------------------------------------------------------------*
     *---                                    ---*
     *---        floatAdder.c                        ---*
     *---                                    ---*
     *---        This file adds 2 32-bit IEEE floating point numbers with     ---*
     *---    integer operations.  Doesn't handle '+inf', '-inf' or 'NaN'    ---*
     *---    properly, nor does it round properly.  Those are the only 2    ---*
     *---    bugs of which I'm aware.                    ---*
     *---                                    ---*
     *---    ----    ----    ----    ----    ----    ----    ----    ----    ---*
     *---                                    ---*
     *---             ---*
     *---                                    ---*
     *-------------------------------------------------------------------------*/

    #include <stdlib.h>
    #include <stdio.h>

    //--            Sign related constants                --//

    //  PURPOSE:  To tell how many bits to shift the sign bit from the least
    //    signficant position to where the sign bit belongs.
    #define     SIGN_SHIFT                31

    //  PURPOSE:  To be the mask to only keep the sign bit.
    #define     SIGN_MASK                (0x1 << SIGN_SHIFT)

    //  PURPOSE:  To be the mask to keep everything but the sign bit.
    #define     EVERYTHING_BUT_SIGN_MASK        (~SIGN_MASK)

 

    //--            Exponent related constants            --//

    //  PURPOSE:  To tell how many bits to shift the exponent bit field from the
    //    least signficant position to where the exponent bit field belongs.
    #define     EXPONENT_SHIFT                23

    //  PURPOSE:  To be the mask to only keep the exponent bit field.
    #define     EXPONENT_MASK            ((unsigned)0xFF << EXPONENT_SHIFT)

    //  PURPOSE:  To tell the exponent bit pattern for 'infinity' and
    //    'not-a-number'.
    #define     EXPONENT_INFINITE_BIT_PATTERN        0xFF

    //  PURPOSE:  To tell the exponent bit pattern for denormalized numbers
    //    (including 0.0).
    #define     EXPONENT_DENORMALIZED_BIT_PATTERN    0x00

    //  PURPOSE:  To tell the 'bias' of the exponent bit field:
    //    (powerOf2) = (exponentBitPattern) - EXPONENT_BIAS
    #define     EXPONENT_BIAS                0x7F

    //  PURPOSE:  To tell the power of 2 for 'infinity' and 'not-a-number'.
    #define     INFINITE_POWER_OF_2            +128

    //  PURPOSE:  To tell the power of 2 for denormalized numbers (including 0.0):
    #define     DENORMALIZED_POWER_OF_2        -127

    #define     INDISTINGUISHABLE_FROM_0_POWER_OF_2    (DENORMALIZED_POWER_OF_2-23)


    //--            Mantissa related constants            --//

    //  PURPOSE:  To tell the mask to only keep the mantissa bit field.
    #define     MANTISSA_MASK                0x007FFFFF

    //  PURPOSE:  To tell give the hidden bit in its proper position.
    #define     MANTISSA_HIDDEN_BIT            0x00800000

    //  PURPOSE:  To tell how many bits to shift the mantissa bit field from the
    //    least signficant position to where the mantissa bit field belongs.
    #define     MANTISSA_SHIFT                0

    //  PURPOSE:  To tell how many mantissa bits there are (including hidden bit)
    #define     NUM_MANTISSA_BITS            24

 

    //--            Miscellaneous related constants            --//

    //  PURPOSE:  To give the maximum length of C-strings.
    #define     TEXT_LEN                64

 

    //  PURPOSE:  To return 1 if 'f' is 0.0 or -0.0.  Returns 0 otherwise.
    int               isZero     (float f)
    {
      unsigned int    u = *(unsigned int*)&f;

      //  Your code here

      return(0 /* Perhaps change this */);
    }


    //  PURPOSE:  To return the +1 if the sign of 'f' is positive, or -1 otherwise.
    int        getSign     (float f)
    {
      unsigned int    u = *(unsigned int*)&f;

      //  Your code here

      return(0 /* Perhaps change this */);
    }


    //  PURPOSE:  To return the exponent (the X of 2^X) of the floating point
    //    'f' from 'DENORMALIZED_POWER_OF_2' to 'INFINITE_POWER_OF_2'.
    //    (Does _not_ return the bit pattern.)
    int        getPowerOf2    (float f)
    {
      unsigned int    u    = *(unsigned int*)&f;
      unsigned int     i    = 0; /* Perhaps change this */

      //  Your code here

      return(0 /* Perhaps change this */);
    }

 

    //  PURPOSE:  To return the mantissa of 'f', with the HIDDEN_BIT or-ed in if
    //     'f' is not denormalized.
    unsigned int    getMantissa    (float f)
    {
      unsigned int    mantissa    = *(unsigned int*)&f;

      //  Your code here

      return(0 /* Perhaps change this */);
    }

 

    //  PURPOSE:  To return the 0x0 when given +1, or 0x1 when given -1.
    unsigned char    signToSignBit    (int    sign)
    {
      //  Your code here

      return(0 /* Perhaps change this */);
    }


    //  PURPOSE:  To return the exponent field's bit pattern for power of 2
    //    'powerOf2'.  If 'powerOf2' is greater or equal to 'INFINITE_POWER_OF_2'
    //    then it returns 'EXPONENT_INFINITE_BIT_PATTERN'.  If 'powerOf2' is
    //    less than or equal to 'DENORMALIZED_POWER_OF_2' then it
    //    returns 'EXPONENT_DENORMALIZED_BIT_PATTERN'.  Otherwise it returns the
    //    corresponding bit pattern for 'powerOf2' given bias 'EXPONENT_BIAS'.
    unsigned char    pwrOf2ToExpBits    (int    powerOf2)
    {
      //  Your code here

      return(0 /* Perhaps change this */);
    }


    //  PURPOSE:  To return the mantissa _field_, 'mantissa' with its hidden
    //    bit turned off.
    unsigned int  mantissaField    (unsigned int    mantissa
                    )
    {
      //  Your code here

      return(0 /* Perhaps change this */);
    }


    //  PURPOSE:  To return the floating point number constructed from sign bit
    //    'signBit'
    float    buildFloat    (int        sign,
                 int        exp,
                 unsigned int    mantissaBits
                )
    {
      //  Leave this code alone!
      unsigned int    u    = (signToSignBit(sign)        << SIGN_SHIFT)       |
                  (pwrOf2ToExpBits(exp)        << EXPONENT_SHIFT) |
                  (mantissaField(mantissaBits)    << MANTISSA_SHIFT);
      float     f    = *(float*)&u;
      return(f);
    }


    //  PURPOSE:  To return 'f' added with 'g'.
    float    add    (float    f,
             float    g
            )
    {
      //  I.  Handle when either 'f' or 'g' is 0.0:
      if  ( isZero(f) )
        return(g);

      if  ( isZero(g) )
        return(f);

      //  II.  Do operation:
      int        signF        = getSign(f);
      int        signG        = getSign(g);
      int        powerOf2F    = getPowerOf2(f);
      int        powerOf2G    = getPowerOf2(g);
      unsigned int    mantissaF    = getMantissa(f);
      unsigned int    mantissaG    = getMantissa(g);
      unsigned int    mantissa;
      int           powerOf2;
      int        sign;

      if  (signF == signG)
      {
        //  II.A.  Do addition:

        //  (This is required.)
        //
        //  See which has the bigger power-of-2: 'f' or 'g'
        //  Shift the smaller of the two by the difference in power of 2.
        //  Then add the mantissas.
        //
        //  What is the value of 'powerOf2'?  What is the value of 'sign'?
        //
        //  How do you detect when the mantissa overflows?
        //  What do you do when the mantissa does overflow?

      }
      else
      {
        //  II.B.  Do subtraction:
        //  II.B.1.  Handle canceling to 0:
        if  ( (powerOf2F == powerOf2G) && (mantissaF == mantissaG) )
          return(buildFloat(+1,EXPONENT_DENORMALIZED_BIT_PATTERN,0x0));

        //  II.B.2.  Do subtraction:
        //  (This is +5 extra credit.)
        //
        //  Subtract the smaller from the bigger.
        //  How do you tell which is bigger from 'powerOf2F', 'powerOf2G', 'mantissaF' and 'mantissaG'?
        //  Do the same mantissa shifting as with addition.
        //
        //  What is the value of 'powerOf2'?  What is the value of 'sign'?
        //
        //  With addition you may be left with too many bits in the mantissa,
        //  with subtraction you may be left with too few.
        //  If that's the case, then keeping shifting the most significant bit
        //  in the mantissa until either it gets to the mantissa's most
        //  significant bit position (the hidden bit's position) or until
        //  'powerOf2' gets down to 'DENORMALIZED_POWER_OF_2'.
        //
        //  Each time you shift 'mantissa' what should you do to 'powerOf2'?

      }

      //  III.  Return built float:
      //  Leave this code alone!
      return(buildFloat(sign,powerOf2,mantissa));
    }


    //  PURPOSE:  To first test your 'getSign()', 'getPowerOf2()' and
    //    'getMantissa()' functions, and then your 'add()' function.  Ignores
    //    arguments from OS.  Returns 'EXIT_SUCCESS' to OS.
    int    main    ()
    {
      //  Leave this code alone!
      float    f;
      float    g;
      char    text[TEXT_LEN];

      do
      {
        printf("Please enter a floating point number or 0 to quit testing: ");
        fgets(text,TEXT_LEN,stdin);
        f = atof(text);

        printf("The sign     of %g is %+d\n",f,getSign(f));
        printf("The exponent of %g is 2^%d\n",f,getPowerOf2(f));
        printf("The mantissa of %g is 0xX\n",f,getMantissa(f));
      }
      while  ( !isZero(f) );

      printf("\n\n");

      do
      {
        printf("Please enter the 1st floating point number to add: ");
        fgets(text,TEXT_LEN,stdin);
        f = atof(text);

        printf("Please enter the 2nd floating point number to add: ");
        fgets(text,TEXT_LEN,stdin);
        g = atof(text);

        printf("         You say  %g + %g == %g\n",f,g,add(f,g));
        printf("The hardware says %g + %g == %g\n",f,g,f+g);
      }
      while  ( !isZero(f) && !isZero(g) );

      return(EXIT_SUCCESS);
    }

    Finish the following functions:
    What each should do is given in its comment.
        isZero()
        getSign()
        getPowerOf2()
        getMantissa()
        signToSignBit()
        pwrOf2ToExpBits()
        mantissaField()
        add()

    Example output:

    [instructor@JoesLaptopFedora16 Assign3]$ ./floatAdder
    Please enter a floating point number or 0 to quit testing: 1
    The sign     of 1 is +1
    The exponent of 1 is 2^0
    The mantissa of 1 is 0x800000
    Please enter a floating point number or 0 to quit testing: -1
    The sign     of -1 is -1
    The exponent of -1 is 2^0
    The mantissa of -1 is 0x800000
    Please enter a floating point number or 0 to quit testing: 4
    The sign     of 4 is +1
    The exponent of 4 is 2^2
    The mantissa of 4 is 0x800000
    Please enter a floating point number or 0 to quit testing: 6  
    The sign     of 6 is +1
    The exponent of 6 is 2^2
    The mantissa of 6 is 0xC00000
    Please enter a floating point number or 0 to quit testing: 7
    The sign     of 7 is +1
    The exponent of 7 is 2^2
    The mantissa of 7 is 0xE00000
    Please enter a floating point number or 0 to quit testing: 7.5
    The sign     of 7.5 is +1
    The exponent of 7.5 is 2^2
    The mantissa of 7.5 is 0xF00000
    Please enter a floating point number or 0 to quit testing: 7.75
    The sign     of 7.75 is +1
    The exponent of 7.75 is 2^2
    The mantissa of 7.75 is 0xF80000
    Please enter a floating point number or 0 to quit testing: 7.875
    The sign     of 7.875 is +1
    The exponent of 7.875 is 2^2
    The mantissa of 7.875 is 0xFC0000
    Please enter a floating point number or 0 to quit testing: 1
    The sign     of 1 is +1
    The exponent of 1 is 2^0
    The mantissa of 1 is 0x800000
    Please enter a floating point number or 0 to quit testing: 2
    The sign     of 2 is +1
    The exponent of 2 is 2^1
    The mantissa of 2 is 0x800000
    Please enter a floating point number or 0 to quit testing: 3
    The sign     of 3 is +1
    The exponent of 3 is 2^1
    The mantissa of 3 is 0xC00000
    Please enter a floating point number or 0 to quit testing: 4
    The sign     of 4 is +1
    The exponent of 4 is 2^2
    The mantissa of 4 is 0x800000
    Please enter a floating point number or 0 to quit testing: 5
    The sign     of 5 is +1
    The exponent of 5 is 2^2
    The mantissa of 5 is 0xA00000
    Please enter a floating point number or 0 to quit testing: 1.4013e-45
    The sign     of 1.4013e-45 is +1
    The exponent of 1.4013e-45 is 2^-127
    The mantissa of 1.4013e-45 is 0x000001
    Please enter a floating point number or 0 to quit testing: 1.7014115e+38
    The sign     of 1.70141e+38 is +1
    The exponent of 1.70141e+38 is 2^126
    The mantissa of 1.70141e+38 is 0xFFFFFD
    Please enter a floating point number or 0 to quit testing: 1.7014117e+38
    The sign     of 1.70141e+38 is +1
    The exponent of 1.70141e+38 is 2^126
    The mantissa of 1.70141e+38 is 0xFFFFFF
    Please enter a floating point number or 0 to quit testing: 1.7014118e+38
    The sign     of 1.70141e+38 is +1
    The exponent of 1.70141e+38 is 2^127
    The mantissa of 1.70141e+38 is 0x800000
    Please enter a floating point number or 0 to quit testing: inf
    The sign     of inf is +1
    The exponent of inf is 2^128
    The mantissa of inf is 0x800000
    Please enter a floating point number or 0 to quit testing: nan
    The sign     of nan is +1
    The exponent of nan is 2^128
    The mantissa of nan is 0xC00000
    Please enter a floating point number or 0 to quit testing: -inf
    The sign     of -inf is -1
    The exponent of -inf is 2^128
    The mantissa of -inf is 0x800000
    Please enter a floating point number or 0 to quit testing: 0
    The sign     of 0 is +1
    The exponent of 0 is 2^-127
    The mantissa of 0 is 0x000000


    Please enter the 1st floating point number to add: 1
    Please enter the 2nd floating point number to add: 2
             You say  1 + 2 == 3
    The hardware says 1 + 2 == 3
    Please enter the 1st floating point number to add: 2
    Please enter the 2nd floating point number to add: 3
             You say  2 + 3 == 5
    The hardware says 2 + 3 == 5
    Please enter the 1st floating point number to add: 1.234
    Please enter the 2nd floating point number to add: 4.321
             You say  1.234 + 4.321 == 5.555
    The hardware says 1.234 + 4.321 == 5.555
    Please enter the 1st floating point number to add: -1
    Please enter the 2nd floating point number to add: -.5
             You say  -1 + -0.5 == -1.5
    The hardware says -1 + -0.5 == -1.5
    Please enter the 1st floating point number to add: -2
    Please enter the 2nd floating point number to add: -.5
             You say  -2 + -0.5 == -2.5
    The hardware says -2 + -0.5 == -2.5
    Please enter the 1st floating point number to add: -16
    Please enter the 2nd floating point number to add: -0.125
             You say  -16 + -0.125 == -16.125
    The hardware says -16 + -0.125 == -16.125
    Please enter the 1st floating point number to add: -256
    Please enter the 2nd floating point number to add: -0.125
             You say  -256 + -0.125 == -256.125
    The hardware says -256 + -0.125 == -256.125
    Please enter the 1st floating point number to add: -65536
    Please enter the 2nd floating point number to add: -0.125
             You say  -65536 + -0.125 == -65536.1
    The hardware says -65536 + -0.125 == -65536.1
    Please enter the 1st floating point number to add: -1.4013e-45
    Please enter the 2nd floating point number to add: -1.4013e-45
             You say  -1.4013e-45 + -1.4013e-45 == -2.8026e-45
    The hardware says -1.4013e-45 + -1.4013e-45 == -2.8026e-45
    Please enter the 1st floating point number to add: 131072
    Please enter the 2nd floating point number to add: 0.03125
             You say  131072 + 0.03125 == 131072
    The hardware says 131072 + 0.03125 == 131072
    Please enter the 1st floating point number to add: 1
    Please enter the 2nd floating point number to add: -2
             You say  1 + -2 == -1
    The hardware says 1 + -2 == -1
    Please enter the 1st floating point number to add: 3
    Please enter the 2nd floating point number to add: -1
             You say  3 + -1 == 2
    The hardware says 3 + -1 == 2
    Please enter the 1st floating point number to add: -4.25
    Please enter the 2nd floating point number to add: 4
             You say  -4.25 + 4 == -0.25
    The hardware says -4.25 + 4 == -0.25
    Please enter the 1st floating point number to add: inf
    Please enter the 2nd floating point number to add: 9
             You say  inf + 9 == inf
    The hardware says inf + 9 == inf
    Please enter the 1st floating point number to add: -inf
    Please enter the 2nd floating point number to add: 9
             You say  -inf + 9 == -inf
    The hardware says -inf + 9 == -inf
    Please enter the 1st floating point number to add: 0
    Please enter the 2nd floating point number to add: 9
             You say  0 + 9 == 9
    The hardware says 0 + 9 == 9
    [instructor@JoesLaptopFedora16 Assign3]$

 

Solution: #6254

CSC373 Computer System I Assignment #2 Complete Solution

This Tutorial is rated A+ p...
Tutormaster
Rating: A+ Purchased: 11 x Posted By: Tutormaster
Comments
Posted by: Tutormaster

Online Users