Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Separates a floating point number into bit fields, and from those determine its:

ID: 3852745 • Letter: S

Question

Separates a floating point number into bit fields, and from those determine its:

sign (either -1 or +1) with getSign()

exponent (from EXPONENT_DENORMALIZED_BIT_PATTERN to EXPONENT_INFINITE_BIT_PATTERN) with getPowerOf2()

mantissa with getMantissa()

Reconstitutes the bits of a floating point number from its:

Sign with signBits(): given -1 return 0x1, or given +1 return 0x0.

Exponent with expBits(): given the mantissa and exponent, return the exponent bits.

Mantissa with mantissaBits(): given the mantissa, return the mantissa bits

/*-------------------------------------------------------------------------*

*---                                   ---*

*---                                   ---*

*---                                   ---*

*---      This file defines a C program that pulls an IEEE floating   ---*

*---   point number into its respective sign, exponent and mantissa   ---*

*---   fields, and reconstitutes it from those fields.           ---*

*---                                   ---*

*---   ----   ----   ----   ----   ----   ----   ----   ----   ---*

*---                                   ---*

*---                                   ---*

*---                                   ---*

*-------------------------------------------------------------------------*/

#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

// PURPOSE: To tell the lowest legal power of 2.

#define   LOWEST_LEGAL_POWER_OF_2       (DENORMALIZED_POWER_OF_2+1)

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

// Use EVERYTHING_BUT_SIGN_MASK to see if u is a +0.0 or -0.0

}

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

// HINT: See if SIGN_MASK is on in 'u'

}

// PURPOSE: To return the exponent (the n of 2^n) 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;

// Isolate the exponents bits u (use EXPONENT_MASK and EXPONENT_SHIFT)

// Compute the exponent using the bits and EXPONENT_BIAS

// If the computed exponent is greater than LOWEST_LEGAL_POWER_OF_2

// then return exponents

// else return LOWEST_LEGAL_POWER_OF_2

// (use more vars if you need to)

}

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

mantissa   = *(unsigned int*)&f;

exponent   = *(unsigned int*)&f;

// Use MANTISSA_MASK on mantissa

// Use EXPONENT_MASK on exponent

// If the exponent is denormalized (use EXPONENT_DENORMALIZED_BIT_PATTERN)

// then just return mantissa

// otherwise return mantissa combined with MANTISSA_HIDDEN_BIT

}

// PURPOSE: To return the 0x0 when given +1, or 0x1 when given -1.

unsigned char   signBits   (int   sign

               )

{

// If sign is negative return 0x1, else return 0x0

}

// PURPOSE: To return the exponent field's bit pattern for power of 2

//   'powerOf2' given mantissa bit field 'mantissaBits'. If the hidden bit

//   is off in 'mantissaBits' then 'EXPONENT_DENORMALIZED_BIT_PATTERN' is

//   returned. If 'powerOf2' is greater or equal to 'INFINITE_POWER_OF_2'

//   then it returns 'EXPONENT_INFINITE_BIT_PATTERN'. Otherwise it returns

//   the corresponding bit pattern for 'powerOf2' given bias

//   'EXPONENT_BIAS'.

unsigned char   expBits       (int       powerOf2,

               unsigned int   mantissaBits

               )

{

// If the hidden bit is off in mantissaBits

// then return EXPONENT_DENORMALIZED_BIT_PATTERN

// If powerOf2 is greater or equal to INFINITE_POWER_OF_2

// then return EXPONENT_INFINITE_BIT_PATTERN

// else return the exponent bits based on powerOf2 and EXPONENT_BIAS

}

// PURPOSE: To return the mantissa _field_, 'mantissa' with its hidden

//   bit turned off.

unsigned int mantissaBits   (unsigned int   mantissa

               )

{

// Return mantissa without the hidden bit on

// (Perhaps use MANTISSA_HIDDEN_BIT)

}

// PURPOSE: To test your 'getSign()', 'getPowerOf2()', 'getMantissa()'

//   functions, and then your 'add()' function. Ignores

//   arguments from OS. Returns 'EXIT_SUCCESS' to OS.

int   main   ()

{

char       text[TEXT_LEN];

float       f;

unsigned int   u;

float*   gPtr   = (float*)&u;

unsigned int*   vPtr   = (unsigned int*)&f;

do

{

printf("Please enter a floating point number or 0 to quit testing: ");

fgets(text,TEXT_LEN,stdin);

f                   = atof(text);

int           sign       = getSign(f);

unsigned int   mantissa   = getMantissa(f);

int           exp       = getPowerOf2(f);

unsigned char   signB       = signBits(sign);

unsigned int   mantissaB   = mantissaBits(mantissa);

unsigned char   expB       = expBits(exp,mantissa);

u                   = (signB << SIGN_SHIFT)   |

                      (expB   << EXPONENT_SHIFT)   |

                      (mantissaB << MANTISSA_SHIFT);

printf(" ");

printf("The sign of %g is %+d (should be either +1 or -1) ",f,sign);

printf("The exponent of %g is 2^%d (should be from -127 to +127) ",f,exp);

printf("The mantissa of %g is 0x%08X ",f,mantissa);

printf(" ");

printf(" Your bits: C library: ");

printf("Sign %+7d: 0x%X 0x%X ",

   sign,signB,*vPtr >> SIGN_SHIFT

      );

printf("Exponent %+4d: 0x%02X 0x%02X ",

   exp,expB,(*vPtr & EXPONENT_MASK) >> EXPONENT_SHIFT

      );

printf("Mantissa 0x%08X: 0x%08X 0x%08X ",

   mantissa,mantissaB, (*vPtr & MANTISSA_MASK) >> MANTISSA_SHIFT

      );

printf(" ");

printf("Original: %g Reconstituted: %g %s ",

   f,*gPtr,( (f == *gPtr) ? "Good!" : "Uh-oh!" )

      );

printf(" ");

}

while ( !isZero(f) );

printf(" ");

return(EXIT_SUCCESS);

}

Example output:

$ ./floatFields

Please enter a floating point number or 0 to quit testing: 4

The sign of 4 is +1 (should be either +1 or -1)

The exponent of 4 is 2^2 (should be from -127 to +127)

The mantissa of 4 is 0x00800000

       Your bits:   C library:

Sign +1: 0x0   0x0

Exponent +2: 0x81   0x81

Mantissa 0x00800000: 0x00000000   0x00000000

Original:   4

Reconstituted:   4

Good!

Please enter a floating point number or 0 to quit testing: 1

The sign of 1 is +1 (should be either +1 or -1)

The exponent of 1 is 2^0 (should be from -127 to +127)

The mantissa of 1 is 0x00800000

       Your bits:   C library:

Sign +1: 0x0   0x0

Exponent +0: 0x7F   0x7F

Mantissa 0x00800000: 0x00000000   0x00000000

Original:   1

Reconstituted:   1

Good!

Please enter a floating point number or 0 to quit testing: .75

The sign of 0.75 is +1 (should be either +1 or -1)

The exponent of 0.75 is 2^-1 (should be from -127 to +127)

The mantissa of 0.75 is 0x00C00000

       Your bits:   C library:

Sign +1: 0x0   0x0

Exponent -1: 0x7E   0x7E

Mantissa 0x00C00000: 0x00400000   0x00400000

Original:   0.75

Reconstituted:   0.75

Good!

Please enter a floating point number or 0 to quit testing: 3.1415926536

The sign of 3.14159 is +1 (should be either +1 or -1)

The exponent of 3.14159 is 2^1 (should be from -127 to +127)

The mantissa of 3.14159 is 0x00C90FDB

       Your bits:   C library:

Sign +1: 0x0   0x0

Exponent +1: 0x80   0x80

Mantissa 0x00C90FDB: 0x00490FDB   0x00490FDB

Original:   3.14159

Reconstituted:   3.14159

Good!

Please enter a floating point number or 0 to quit testing: 1.175494350e-38

The sign of 1.17549e-38 is +1 (should be either +1 or -1)

The exponent of 1.17549e-38 is 2^-126 (should be from -127 to +127)

The mantissa of 1.17549e-38 is 0x00800000

       Your bits:   C library:

Sign +1: 0x0   0x0

Exponent -126: 0x01   0x01

Mantissa 0x00800000: 0x00000000   0x00000000

Original:   1.17549e-38

Reconstituted:   1.17549e-38

Good!

Please enter a floating point number or 0 to quit testing: 5.877471754111e-39

The sign of 5.87747e-39 is +1 (should be either +1 or -1)

The exponent of 5.87747e-39 is 2^-126 (should be from -127 to +127)

The mantissa of 5.87747e-39 is 0x00400000

       Your bits:   C library:

Sign +1: 0x0   0x0

Exponent -126: 0x00   0x00

Mantissa 0x00400000: 0x00400000   0x00400000

Original:   5.87747e-39

Reconstituted:   5.87747e-39

Good!

Please enter a floating point number or 0 to quit testing: 0

The sign of 0 is +1 (should be either +1 or -1)

The exponent of 0 is 2^-126 (should be from -127 to +127)

The mantissa of 0 is 0x00000000

       Your bits:   C library:

Sign +1: 0x0   0x0

Exponent -126: 0x00   0x00

Mantissa 0x00000000: 0x00000000   0x00000000

Original:   0

Reconstituted:   0

Good!

Explanation / Answer

Here is the code and output.

/*-------------------------------------------------------------------------*

*--- ---*

*--- ---*

*--- ---*

*--- This file defines a C program that pulls an IEEE floating ---*

*--- point number into its respective sign, exponent and mantissa ---*

*--- fields, and reconstitutes it from those fields. ---*

*--- ---*

*--- ---- ---- ---- ---- ---- ---- ---- ---- ---*

*--- ---*

*--- ---*

*--- ---*

*-------------------------------------------------------------------------*/

#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

// PURPOSE: To tell the lowest legal power of 2.

#define LOWEST_LEGAL_POWER_OF_2 (DENORMALIZED_POWER_OF_2+1)

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

  

// Use EVERYTHING_BUT_SIGN_MASK to see if u is a +0.0 or -0.0

if(u & EVERYTHING_BUT_SIGN_MASK == 0)

return 1;

else

return 0;

}

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

  

// HINT: See if SIGN_MASK is on in 'u'

if(u & SIGN_MASK != 0)

return -1;

else

return 1;

}

// PURPOSE: To return the exponent (the n of 2^n) of the floating point

// 'f' from 'DENORMALIZED_POWER_OF_2' to 'INFINITE_POWER_OF_2'.

// (Does _not_s return the bit pattern.)

int getPowerOf2 (float f)

{

unsigned int u = *(unsigned int*)&f;

unsigned int expBits, exp;

unsigned int power = -1;

  

// Isolate the exponents bits u (use EXPONENT_MASK and EXPONENT_SHIFT)

expBits = (u & EXPONENT_MASK) >> EXPONENT_SHIFT;

// Compute the exponent using the bits and EXPONENT_BIAS

power = expBits - EXPONENT_BIAS;

// If the computed exponent is greater than LOWEST_LEGAL_POWER_OF_2

// then return exponents

// else return LOWEST_LEGAL_POWER_OF_2

//if(power > (1 & LOWEST_LEGAL_POWER_OF_2))

return power;

//else

   // return LOWEST_LEGAL_POWER_OF_2;

// (use more vars if you need to)

}

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

  

  

mantissa = *(unsigned int*)&f;

exponent = *(unsigned int*)&f;

  

// Use MANTISSA_MASK on mantissa

mantissa = ( mantissa & MANTISSA_MASK ) >> MANTISSA_SHIFT;

// Use EXPONENT_MASK on exponent

exponent = (exponent & exponent) >> EXPONENT_SHIFT;

// If the exponent is denormalized (use EXPONENT_DENORMALIZED_BIT_PATTERN)

// then just return mantissa

// otherwise return mantissa combined with MANTISSA_HIDDEN_BIT

if(exponent == EXPONENT_DENORMALIZED_BIT_PATTERN)

return mantissa;

else

return (mantissa | MANTISSA_HIDDEN_BIT);

}

// PURPOSE: To return the 0x0 when given +1, or 0x1 when given -1.

unsigned char signBits (int sign

)

{

// If sign is negative return 0x1, else return 0x0

if(sign == -1)

return 0x1;

else

return 0;

}

// PURPOSE: To return the exponent field's bit pattern for power of 2

// 'powerOf2' given mantissa bit field 'mantissaBits'. If the hidden bit

// is off in 'mantissaBits' then 'EXPONENT_DENORMALIZED_BIT_PATTERN' is

// returned. If 'powerOf2' is greater or equal to 'INFINITE_POWER_OF_2'

// then it returns 'EXPONENT_INFINITE_BIT_PATTERN'. Otherwise it returns

// the corresponding bit pattern for 'powerOf2' given bias

// 'EXPONENT_BIAS'.

unsigned char expBits (int powerOf2,

   unsigned int mantissaBits

   )

{

// If the hidden bit is off in mantissaBits

// then return EXPONENT_DENORMALIZED_BIT_PATTERN

if(mantissaBits & MANTISSA_HIDDEN_BIT == 0)

return EXPONENT_DENORMALIZED_BIT_PATTERN;

// If powerOf2 is greater or equal to INFINITE_POWER_OF_2

// then return EXPONENT_INFINITE_BIT_PATTERN

//if(powerOf2 >= (1 & INFINITE_POWER_OF_2))

// return EXPONENT_INFINITE_BIT_PATTERN;

  

// else return the exponent bits based on powerOf2 and EXPONENT_BIAS

//else

return ((unsigned char)powerOf2 + (unsigned char)EXPONENT_BIAS);

}

// PURPOSE: To return the mantissa _field_, 'mantissa' with its hidden

// bit turned off.

unsigned int mantissaBits (unsigned int mantissa

   )

{

// Return mantissa without the hidden bit on

// (Perhaps use MANTISSA_HIDDEN_BIT)

return mantissa ^ MANTISSA_HIDDEN_BIT;

}

// PURPOSE: To test your 'getSign()', 'getPowerOf2()', 'getMantissa()'

// functions, and then your 'add()' function. Ignores

// arguments from OS. Returns 'EXIT_SUCCESS' to OS.

int main ()

{

char text[TEXT_LEN];

float f;

unsigned int u;

float* gPtr = (float*)&u;

unsigned int* vPtr = (unsigned int*)&f;

unsigned int x = LOWEST_LEGAL_POWER_OF_2;

do

{

printf("Please enter a floating point number or 0 to quit testing: ");

fgets(text,TEXT_LEN,stdin);

  

f = atof(text);

int sign = getSign(f);

unsigned int mantissa = getMantissa(f);

int exp = getPowerOf2(f);

unsigned char signB = signBits(sign);

unsigned int mantissaB = mantissaBits(mantissa);

unsigned char expB = expBits(exp,mantissa);

u = (signB << SIGN_SHIFT) |

(expB << EXPONENT_SHIFT) |

(mantissaB << MANTISSA_SHIFT);

  

printf(" ");

printf("The sign of %g is %+d (should be either +1 or -1) ",f,sign);

printf("The exponent of %g is 2^%d (should be from -127 to +127) ",f,exp);

printf("The mantissa of %g is 0x%08X ",f,mantissa);

  

printf(" ");

printf(" Your bits: C library: ");

printf("Sign %+7d: 0x%X 0x%X ",

   sign,signB,*vPtr >> SIGN_SHIFT

   );

printf("Exponent %+4d: 0x%02X 0x%02X ",

   exp,expB,(*vPtr & EXPONENT_MASK) >> EXPONENT_SHIFT

   );

printf("Mantissa 0x%08X: 0x%08X 0x%08X ",

   mantissa,mantissaB, (*vPtr & MANTISSA_MASK) >> MANTISSA_SHIFT

   );

printf(" ");

printf("Original: %g Reconstituted: %g %s ",

   f,*gPtr,( (f == *gPtr) ? "Good!" : "Uh-oh!" )

   );

printf(" ");

}

while ( !isZero(f) );

  

printf(" ");

  

return(EXIT_SUCCESS);

}

1

Please enter a floating point number or 0 to quit testing:

The sign of 1 is +1 (should be either +1 or -1)

The exponent of 1 is 2^0 (should be from -127 to +127)

The mantissa of 1 is 0x00800000

       Your bits:   C library:

Sign +1: 0x0   0x0

Exponent +0: 0x7F   0x7F

Mantissa 0x00800000: 0x00000000   0x00000000

Original:   1

Reconstituted:   1

Good!

4

Please enter a floating point number or 0 to quit testing:

The sign of 4 is +1 (should be either +1 or -1)

The exponent of 4 is 2^2 (should be from -127 to +127)

The mantissa of 4 is 0x00800000

       Your bits:   C library:

Sign +1: 0x0   0x0

Exponent +2: 0x81   0x81

Mantissa 0x00800000: 0x00000000   0x00000000

Original:   4

Reconstituted:   4

Good!

0.75

Please enter a floating point number or 0 to quit testing:

The sign of 0.75 is +1 (should be either +1 or -1)

The exponent of 0.75 is 2^-1 (should be from -127 to +127)

The mantissa of 0.75 is 0x00C00000

       Your bits:   C library:

Sign +1: 0x0   0x0

Exponent -1: 0x7E   0x7E

Mantissa 0x00C00000: 0x00400000   0x00400000

Original:   0.75

Reconstituted:   0.75

Good!

3.14159

Please enter a floating point number or 0 to quit testing:

The sign of 3.14159 is +1 (should be either +1 or -1)

The exponent of 3.14159 is 2^1 (should be from -127 to +127)

The mantissa of 3.14159 is 0x00C90FD0

       Your bits:   C library:

Sign +1: 0x0   0x0

Exponent +1: 0x80   0x80

Mantissa 0x00C90FD0: 0x00490FD0   0x00490FD0

Original:   3.14159

Reconstituted:   3.14159

Good!

1.175494350e-38

Please enter a floating point number or 0 to quit testing:

The sign of 1.17549e-38 is +1 (should be either +1 or -1)

The exponent of 1.17549e-38 is 2^-126 (should be from -127 to +127)

The mantissa of 1.17549e-38 is 0x00800000

       Your bits:   C library:

Sign +1: 0x0   0x0

Exponent -126: 0x01   0x01

Mantissa 0x00800000: 0x00000000   0x00000000

Original:   1.17549e-38

Reconstituted:   1.17549e-38

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote