Hello, I need some help with this assignment. I will post my code along side the
ID: 674549 • Letter: H
Question
Hello, I need some help with this assignment. I will post my code along side the assignment.
Last revised 2015 October 22
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 comparison.
Please copy and paste this:
Finish the following functions:
What each should do is given in its comment.
int isZero (float f)
int getSign (float f)
int getPowerOf2 (float f)
unsigned int getMantissa (float f)
unsigned char signToSignBit (int sign)
unsigned char pwrOf2ToExpBits (int powerOf2, unsigned int fullMantissa)
unsigned int mantissaField (int powerOf2, unsigned in mantissa)
float multiply(float f0, float f1)
You may only use integer functions and operations.
sign should just be signF0 * signF1
power should just be powerOf2F0 + powerOf2F1
mantissa should just be mantissaF0 * mantissaF1. We use 8-byte integer type unsigned long long to hold mantissa because it is big enough to hold the almost 48-bit result.
Then, mantissa and power must be adjusted. Mostly, this involves shifting mantissa to the right by 23 bits to get rid of the least significant bits. However, three other adjustments must be made:
We must ensure power is between SMALLEST_NORMALIZED_POWER_OF_2 and INFINITE_POWER_OF_2. Do this with a loop:
While power is less than SMALLEST_NORMALIZED_POWER_OF_2, power should be incremented. This multiplies our number by 2, and we should compensate for it by shifting mantissa to the right by 1.
If the number is denormalized then before shifting mantissa to the right by 23 we should save as much mantissa as we can. While mantissa is less than the position of where the hidden bit should be in the product (POST_MULTIPLY_MANTISSA_HIDDEN_BIT) and power is greater than SMALLEST_NORMALIZED_POWER_OF_2 we should shift mantissato the left by 1. This multiplies mantissa by two, and we should compensate for that by two by decrementing power.
Now shift mantissa by 23 bits to the right.
If mantissa is too big (extends beyond the hidden bit) then an overflow has occurred. The mantissa should be shifted one more bit to the right (for a total of 24 bits). To compensate for this effective division-by-two, power should be incremented.
HINT: Use MANTISSA_OVERFLOW_MASK
How functions work together:
Example output:
When you run the program there are two phases.
The first phase lets you test whether or not your getSign(), getPowerOf2(), getMantissa(), signToSignBit(), pwrOf2ToExpBits()and mantissaField() work.
It takes a floating point number apart and puts it back together again.
The second phase lets you test your multiplication algorithm.
Enter two numbers to compare what you say the product is with what the system's floating point multiplier says the product is.
Below is my code. Can someone help? I have been getting irregular answers when multiplying some of the numbers in the test. Thanks!
#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 SMALLEST_NORMALIZED_POWER_OF_2 -126
//-- 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 the mask to use to detect mantissa bits too high.
#define MANTISSA_OVERFLOW_MASK ~(MANTISSA_MASK | MANTISSA_HIDDEN_BIT)
// 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
// PURPOSE: To tell the mantissa to use for '+infinity' and '-infinity'.
#define INFINITY_MANTISSA 0x000000
// PURPOSE: To tell the position of the hidden bit after a multiplication
#define POST_MULTIPLY_MANTISSA_HIDDEN_BIT (0x800000ull << 23)
//-- 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;
if ((u == 0.0) || (u == -0.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;
if ((u & SIGN_MASK) == 0)
{
return 1;
} else{
return -1;
}
}
// PURPOSE: To return the exponent (the X of 2^X) of the floating point
// 'f' from 'SMALLEST_NORMALIZED_POWER_OF_2' to 'INFINITE_POWER_OF_2'.
// (Does _not_ return the bit pattern.)
int getPowerOf2 (float f)
{
unsigned int u = *(unsigned int*)&f;
int i = ((u & EXPONENT_MASK) >> EXPONENT_SHIFT) - EXPONENT_BIAS;
// HINT: Use EXPONENT_MASK and EXPONENT_SHIFT
if (i <= SMALLEST_NORMALIZED_POWER_OF_2)
{
return SMALLEST_NORMALIZED_POWER_OF_2;
} else {
return i;
}
}
// 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;
int exp = 0; /* Perhaps change this */
// HINT: Use EXPONENT_MASK and EXPONENT_SHIFT
if((mantissa & EXPONENT_MASK) == 0) {
mantissa = mantissa & MANTISSA_MASK;
} else {
mantissa = mantissa & MANTISSA_MASK;
mantissa = mantissa | MANTISSA_HIDDEN_BIT;
}
return mantissa;
}
// PURPOSE: To return the 0x0 when given +1, or 0x1 when given -1.
unsigned char signToSignBit (int sign)
{
if(sign == 1)
{
return 0x0;
}else{
return 0x1;
}
}
// PURPOSE: To return the exponent field's bit pattern for power of 2
// 'powerOf2'.
// (1) If 'powerOf2' is greater or equal to 'INFINITE_POWER_OF_2'
// then it returns 'EXPONENT_INFINITE_BIT_PATTERN'.
// (2) If 'powerOf2' is less than or equal to
// 'SMALLEST_NORMALIZED_POWER_OF_2' *and* if
// the hidden bit is off in 'fullMantissa'
// then it returns 'EXPONENT_DENORMALIZED_BIT_PATTERN'.
// (3) Otherwise it returns the corresponding bit pattern for
// 'powerOf2' plus 'EXPONENT_BIAS'.
unsigned char pwrOf2ToExpBits (int powerOf2,
unsigned int fullMantissa
)
{
if (powerOf2 >= INFINITE_POWER_OF_2){
printf("number1! ");
return EXPONENT_INFINITE_BIT_PATTERN;
} else if ((powerOf2 <= SMALLEST_NORMALIZED_POWER_OF_2) && ((fullMantissa && MANTISSA_HIDDEN_BIT) == 0)){
printf("number2! ");
return EXPONENT_DENORMALIZED_BIT_PATTERN;
} else {
printf("else! ");
return powerOf2 + EXPONENT_BIAS;
}
}
// PURPOSE: To return the mantissa field of 'mantissa' with its hidden
// bit turned off.
// (1) if 'powerOf2' is greater than or equal to 'INFINITE_POWER_OF_2'
// then it returns 'INFINITY_MANTISSA'.
// (2) otherwise it returns 'mantissa' with its hidden bit turned off.
unsigned int mantissaField (int powerOf2,
unsigned int mantissa
)
{
if (powerOf2 >= INFINITE_POWER_OF_2){
return INFINITY_MANTISSA;
} else {
unsigned int u = ~MANTISSA_HIDDEN_BIT;
mantissa = mantissa & u;
return(mantissa);
}
}
// PURPOSE: To return the floating point number constructed from sign
// 'sign', exponent 'exp', and mantissa 'mantissa'.
float buildFloat (int sign,
int exp,
unsigned int mantissa
)
{
unsigned int u = (signToSignBit(sign) << SIGN_SHIFT) |
(pwrOf2ToExpBits(exp,mantissa) << EXPONENT_SHIFT) |
(mantissaField(exp,mantissa) << MANTISSA_SHIFT);
float f = *(float*)&u;
return(f);
}
// PURPOSE: To return 'f0' times 'f1'.
float multiply (float f0,
float f1
)
{
// I. Handle when they are both either '+0.0' or '-0.0':
if (isZero(f0) || isZero(f1))
return(0.0);
// II. Do multiplication:
// II.A. Get sign, exponent and mantissa of 'f0' and 'f1':
int signF0 = getSign(f0);
int signF1 = getSign(f1);
int powerOf2F0 = getPowerOf2(f0);
int powerOf2F1 = getPowerOf2(f1);
unsigned long long mantissaF0 = getMantissa(f0);
unsigned long long mantissaF1 = getMantissa(f1);
// II.B. Do raw calculations (as integers):
int sign = signF0 * signF1; // Change that 0!
int power = powerOf2F0 + powerOf2F1; // Change that 0!
unsigned long long mantissa = mantissaF0 * mantissaF1; // Change that 0!
// II.C. Adjust 'mantissa' and 'power' to account
// for denormalization and overflow:
while (power < SMALLEST_NORMALIZED_POWER_OF_2)
{
power++;
mantissa = mantissa >> 1;
}
while ((mantissa < POST_MULTIPLY_MANTISSA_HIDDEN_BIT) && (power > SMALLEST_NORMALIZED_POWER_OF_2))
{
power--;
mantissa = mantissa << 1;
}
mantissa = mantissa >> 23;
if (mantissa > MANTISSA_OVERFLOW_MASK)
{
power++;
mantissa = mantissa >> 1;
}
// III. Finished:
return(buildFloat(sign,power,(unsigned int)mantissa));
}
// PURPOSE: To first test your 'getSign()', 'getPowerOf2()' and
// 'getMantissa()' functions, and then your 'multiply()' function.
// Ignores arguments from OS. Returns 'EXIT_SUCCESS' to OS.
int main ()
{
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 ",f,getSign(f));
printf("The exponent of %g is 2^%d ",f,getPowerOf2(f));
printf("The mantissa of %g is 0x%06X ",f,getMantissa(f));
printf("The sign, exponent and mantissa reconsitute to form float %g ",
buildFloat(getSign(f),getPowerOf2(f),getMantissa(f))
);
}
while ( !isZero(f) );
printf(" ");
while (1)
{
printf("Please enter the 1st floating point number to multiply: ");
fgets(text,TEXT_LEN,stdin);
f = atof(text);
printf("Please enter the 2nd floating point number to multiply: ");
fgets(text,TEXT_LEN,stdin);
g = atof(text);
float p = f * g;
printf(" You say %g * %g == %g ", f,g,multiply(f,g));
printf("The hardware says %g * %g == %g ",f,g,p);
}
return(EXIT_SUCCESS);
}
Explanation / Answer
class Comparison { const MIN_NORMAL = 1.17549435E-38; //from Java Specs // from http://floating-point-gui.de/errors/comparison/ public function nearlyEqual($a, $b, $epsilon = 0.000001) { $absA = abs($a); $absB = abs($b); $diff = abs($a - $b); if ($a == $b) { return true; } else { if ($a == 0 || $b == 0 || $diffRelated Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.