### CSC 373: Computer System I Assignment #2 Complete Solution

Question Details: #6249
CSC 373: 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:

/*-------------------------------------------------------------------------*
*---                                    ---*
*---                                    ---*
*---        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.

//  PURPOSE:  To be the mask to keep everything but the sign bit.

//--            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.

//  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.

//  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;

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;

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 */

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;

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

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

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)
{

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

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

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    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)
{

//  (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.
//
//  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
//    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
{
fgets(text,TEXT_LEN,stdin);
f = atof(text);

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()

Example output:

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

You say  1 + 2 == 3
The hardware says 1 + 2 == 3
You say  2 + 3 == 5
The hardware says 2 + 3 == 5
You say  1.234 + 4.321 == 5.555
The hardware says 1.234 + 4.321 == 5.555
You say  -1 + -0.5 == -1.5
The hardware says -1 + -0.5 == -1.5
You say  -2 + -0.5 == -2.5
The hardware says -2 + -0.5 == -2.5
You say  -16 + -0.125 == -16.125
The hardware says -16 + -0.125 == -16.125
You say  -256 + -0.125 == -256.125
The hardware says -256 + -0.125 == -256.125
You say  -65536 + -0.125 == -65536.1
The hardware says -65536 + -0.125 == -65536.1
You say  -1.4013e-45 + -1.4013e-45 == -2.8026e-45
The hardware says -1.4013e-45 + -1.4013e-45 == -2.8026e-45
You say  131072 + 0.03125 == 131072
The hardware says 131072 + 0.03125 == 131072
You say  1 + -2 == -1
The hardware says 1 + -2 == -1
You say  3 + -1 == 2
The hardware says 3 + -1 == 2
You say  -4.25 + 4 == -0.25
The hardware says -4.25 + 4 == -0.25
You say  inf + 9 == inf
The hardware says inf + 9 == inf
You say  -inf + 9 == -inf
The hardware says -inf + 9 == -inf
You say  0 + 9 == 9
The hardware says 0 + 9 == 9
[instructor@JoesLaptopFedora16 Assign3]\$

• Posted by: TutorMaster
• Subjects: Computer Science Painting
• Attachments:

Solution Details: #6254
CSC 373: Computer System I Assignment #2 Complete Solution

This Tutorial is rated A+ p...
Buy now with PayPal's online protection..
• Purchased: 11 x
• Average Rating: A+
• Posted By: TutorMaster 