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

C code Floating point numbers Below is the ifloat .h file Instructions are bold

ID: 3743126 • Letter: C

Question

C code Floating point numbers

Below is the ifloat.h file

Instructions are bold

Code to be completed is bold after the .h file

#ifndef __IFLOAT_H__
#define __IFLOAT_H__

/*
* iFloat.h - header for simple floating point functions.
*

/** @file iFloat.h
* @brief Defines interface of iFloat.c functions (do not modify)
* @details This file defines the interface to a C file iFloat.c that
* you will complete. You will learn how to do floating point arithmetic
* without using any float variables. Rather you will
* perform the operations by using the sign, exponent, and digit fields
* as defined in the
* IEEE Floating
* Point Standard.
*


* Everything in a computer is stored as a series of 0/1's. When you use an
* int to type a value, you are telling the compiler (and
* ultimately the CPU) to treat the 0/1's as a two's complement number. When
* you use float, the 0/1's represent a floating point number.
* When an addition is performed, the computer knows whether to use the
* integer or floating point add instruction. The two instructions do different
* things to the 0/1's.

In this assignment, you are doing floating point
* operations without using floating point instructions. You are
* directly doing the bit manipulations necessary to complete the add. Since
* iFloat_t is an integral type, the compiler will generate integer
* instructions. The iFloat_t is to remind you (the programmer),
* that although the computer is going to treat all values as integers, you
* know it is really 3 values (sign, exponent, mantissa) packed into a single
* integer number. Your responsibility is to unpack the three pieces, do the
* operations necessary to complete the operation, then put the three pieces
* back together.
*/

#ifdef HALF
typedef short iFloat_t;

#define BITS 16
#define BITS_EXP 5
#define BITS_MANT 10
#define EXP_BIAS 15

#else
typedef int iFloat_t;

#define BITS 32
#define BITS_EXP 8
#define BITS_MANT 23
#define EXP_BIAS 127

#endif

/** Extract the sign of the argument.
* @param x the integer containing an IEEE floating point value
* @return 0 if the value is 0 or positive, 1 if it is negative
*/
iFloat_t floatGetSign (iFloat_t x);

/** Extract the exponent of the argument.
* @param x the integer containing an IEEE floating point value
* @return the biased exponent of the argument
*/
iFloat_t floatGetExp (iFloat_t x);

/** Extract the value of the argument. The value is the mantissa with the
* implicit 1 made explicit and adjusted for the sign of the argument. Please
* refer to the floating point addition example (step 1) in the instructions for
* an example on how the value is extracted. Basically, you'll have to do three
* things: 1) extract the mantissa; 2) set the implicit 1 in the extracted
* mantissa; 3) if the sign of the argument is negative, return the 2's complement
* of the mantissa from step (2). Otherwise, return it as-is. You may want to use
* the getField function from R3.
* @param x the integer containing an IEEE floating point value
* @return the bits representing the value. If x represents 0.0, you should still
* set the implicit 1 in the extracted mantissa.
*/
iFloat_t floatGetVal (iFloat_t x);

/** Get the sign, exponent, and value in a single call.
* @param x the integer containing an IEEE floating point value
* @param sign pointer to location where the sign will be stored
* @param exp pointer to location where the exponent will be stored
* @param val pointer to location where the value will be stored
*/
void floatGetAll(iFloat_t x, iFloat_t* sign, iFloat_t*exp, iFloat_t* val);

/** Obtain the position of the leftmost 1 in the argument's bits.
* @param bits the integer
* @return -1 if the value is 0, otherwise the position (0 to 15) of the
* leftmost 1 bit. In a binary number, the positions are numbered from right to
* left with the rightmost position being 0.
*/
iFloat_t floatLeftMost1 (iFloat_t bits);

/** Absolute value of the argument. This can be done with a simple bit
* manipulation operation. No conditionals are required.
* @param x the integer containing an IEEE floating point value
* @return the absolute value of the parameter
*/
iFloat_t floatAbs (iFloat_t x);

/** Negate the argument. This can be done with a simple bit manipulation
* function. No conditionals are required. This is NOT the bitwise negation
* of the argument. As an example, if the argument represents 2.25, this function
* should return the IEEE bit pattern for -2.25.
* @param x the integer containing an IEEE floating point value
* @return the negation of the value. Note that the negation of 0.0 is 0.0 (not
* -0.0).
*/
iFloat_t floatNegate (iFloat_t x);

/** Add two floating point values.
* @param x an integer containing an IEEE floating point value
* @param y an integer containing an IEEE floating point value
* @return x + y. Your code needs to account for a value of 0.0, but no other
* special cases (e.g. infinities).
*/
iFloat_t floatAdd (iFloat_t x, iFloat_t y);

/** Subtract two floating point values.
* @param x an integer containing an IEEE floating point value
* @param y an integer containing an IEEE floating point value
* @return x - y. Your code needs to account for a value of 0.0, but no other
* special cases (e.g. infinities).
*/
iFloat_t floatSub (iFloat_t x, iFloat_t y);

#endif

--------------------------------------------------------------

--------------------------------------------------------------

--------------------------------------------------------------

--------------------------------------------------------------

Below is the iFloat.c file


#include "iFloat.h"

/** @file iFloat.c
* @brief You will modify this file and implement nine functions
* @details Your implementation of the functions defined in iFloat.h.
* You may add other function if you find it helpful. Added function
* should be declared static to indicate they are only used
* within this file.
*


* @author Your name goes here
*/

/* declaration for useful function contained in testFloat.c */
const char* getBinary (iFloat_t value);

/** @todo Implement based on documentation contained in iFloat.h */
iFloat_t floatGetSign (iFloat_t x) {
return 0; /* implement this */
}

/** @todo Implement based on documentation contained in iFloat.h */
iFloat_t floatGetExp (iFloat_t x) {
return 0; /* implement this */
}

/** @todo Implement based on documentation contained in iFloat.h */
iFloat_t floatGetVal (iFloat_t x) {
return 0;
}

/** @todo Implement based on documentation contained in iFloat.h */
void floatGetAll(iFloat_t x, iFloat_t* sign, iFloat_t*exp, iFloat_t* val) {
}

/** @todo Implement based on documentation contained in iFloat.h */
iFloat_t floatLeftMost1 (iFloat_t bits) {
return -1;
}

/** @todo Implement based on documentation contained in iFloat.h */
iFloat_t floatAbs (iFloat_t x) {
return 0;
}

/** @todo Implement based on documentation contained in iFloat.h */
iFloat_t floatNegate (iFloat_t x) {
return 0;
}

/** @todo Implement based on documentation contained in iFloat.h */
iFloat_t floatAdd (iFloat_t x, iFloat_t y) {
debug("%s: bits of x (IEEE 754)", getBinary(x)); // example only
debug("%s: bits of y (IEEE 754)", getBinary(y)); // example only
return 0;
}

/** @todo Implement based on documentation contained in iFloat.h */
iFloat_t floatSub (iFloat_t x, iFloat_t y) {
return 0;
}

Explanation / Answer

iFloat.c

#include "iFloat.h"


/* declaration for useful function contained in testFloat.c */
const char* getBinary (iFloat_t value);

/** @todo Implement based on documentation contained in iFloat.h */
//DONE
iFloat_t floatGetSign (iFloat_t x) {
return ((x & 0x8000) >> 15);
}

/** @todo Implement based on documentation contained in iFloat.h */
//DONE
iFloat_t floatGetExp (iFloat_t x) {
return ((x & 0x7C00) >> 10);
}

/** @todo Implement based on documentation contained in iFloat.h */
//DONE
iFloat_t floatGetVal (iFloat_t x) {
int odd = floatGetSign(x);
int mantissa = ((x | 0x0400) & 0x07FF);
if(!odd){
   return mantissa;
}
return (~mantissa + 1);
}

/** @todo Implement based on documentation contained in iFloat.h */
//DONE
void floatGetAll(iFloat_t x, iFloat_t* sign, iFloat_t*exp, iFloat_t* val) {
   *sign = floatGetSign(x);
   *exp = floatGetExp(x);
   *val = floatGetVal(x);
}

/** @todo Implement based on documentation contained in iFloat.h */
//DONE
iFloat_t floatLeftMost1 (iFloat_t bits) {
for(int i = 15; i > 0; i--){
   int bitValue = (bits & (1 << i)) != 0;
   if(bitValue == 1){
       return i;
   }
}
return -1;
}

/** @todo Implement based on documentation contained in iFloat.h */
//DONE
iFloat_t floatAbs (iFloat_t x) {
return (x & 0x7FFF);
}

/** @todo Implement based on documentation contained in iFloat.h */
//DONE
iFloat_t floatNegate (iFloat_t x) {
if(x > 0 || x < 0){
   return x ^ 0x8000;
}else{
   return x;
}
}

/** @todo Implement based on documentation contained in iFloat.h */
iFloat_t floatAdd (iFloat_t x, iFloat_t y) {

   //check for 0's
   if(x == 0 || y == 0){
       if(x != 0){
           return x;
       }
       if(y != 0){
           return y;
       }
       else{
           return 0;
       }
   }

iFloat_t signX = -1, expX = -1, valX = -1;
iFloat_t signY = -1, expY = -1, valY = -1;

floatGetAll(x, &signX, &expX, &valX);
floatGetAll(y, &signY, &expY, &valY);

//Normalize exponents so they equal eachother
if(expX > expY){
   int diff = expX - expY;
   expY += diff;
   valY = valY >> diff;
}

else if(expX < expY){
   int diff = expY - expX;
   expX += diff;
   valX = valX >> diff;
}

iFloat_t expResult = expY;
iFloat_t valResult = valX + valY;
iFloat_t signResult = floatGetSign(valResult);

//Make sure val of result is positive
iFloat_t magResult = valResult;
if(signResult == 1){//negative number
   magResult = ~valResult + 1;
}


//Make sure only one bit to the left of decimal point
if(floatLeftMost1(magResult) < 10){
   int pointDiff = 10 - floatLeftMost1(magResult);
   magResult = magResult << pointDiff;
   expResult -= pointDiff;    
}

if(floatLeftMost1(magResult) > 10){
   int pointDiff = floatLeftMost1(magResult) - 10;
   magResult = magResult >> pointDiff;
   expResult += pointDiff;
}

magResult = magResult ^ 0x0400;//get rid of explicit 1
iFloat_t ans = (signResult << 15) | (expResult << 10) | (magResult);

return ans;
}

/** @todo Implement based on documentation contained in iFloat.h */
iFloat_t floatSub (iFloat_t x, iFloat_t y) {
return floatAdd(x, floatNegate(y));
}