Writing a floating point multiplication function in C

In my Computer Science course, I was assigned to write a function that takes two floating point arguments and returns the result of multiplying them in C

float multiply(float foo, float bar);

      

I am not allowed to use any libraries or any floating point operations other than the assignment operator =

I understand how floating point numbers are represented in C, and I have isolated exponents and fractions by doing the following:

union sp_item { float frep; unsigned irep; };
union sp_item num;
num.frep = foo;
int exponent = ((num.irep >> 23) - 0x7f);
int frac = (num.irep << 9);

      

I understand that I need to add exponents (simple enough) and multiply the two fractions. The thing is, I have no idea where to start multiplying fractions. I was thinking about converting the fraction to hexadecimal representation as a string (ex: 0.5 would be "80000000") and writing an algorithm to multiply the bits that way, but since I cannot use any of the C libraries I have I don't know how I will do this. Can anyone point me in the right direction?

Change: . It seemed to me that floats might not appear the same on all systems. In this course, we will assume the first bit is the sign, the next 8 bits are the exponent, and the last 23 bits are the fraction.

Edit: This is what I got so far. When I try and multiply two integers, I just get zero unless I enter (long long)((long long)xRep * (long long)yRep)

in the debugger watch list

#include <stdio.h>
union sp_item
{
  float frep;
  unsigned irep;
};

int main() {
float x = 0.25;
float y = 0.5;
union sp_item xUnion;
union sp_item yUnion;
xUnion.frep = x; yUnion.frep = y;

unsigned xExp = (xUnion.irep >> 23) - 0x7f;
unsigned yExp = (yUnion.irep >> 23) - 0x7f;

unsigned xRep = (xUnion.irep << 9);
unsigned yRep = (yUnion.irep << 9);


xRep = (xRep >> 1) | 0x80000000;
yRep = (yRep >> 1) | 0x80000000;

long long final = (long long)((long long)xRep * (long long)yRep);

printf("iRep: %x * 2^%d\n", xRep, xExp);
printf("iRep: %x * 2^%d\n", yRep, yExp);
printf("%01611x\n", final);
}

      

+3


source to share


3 answers


Why not just multiply the fractions (extracted into their int representation) using the integer multiplication operator *

,?



+1


source


24 + 24 <64, so you can use multiplication long long

. Long debts are guaranteed to be large enough to hold numbers from - (2 ^ 63-1) to (2 ^ 63-1)

Or you can split the number in two (low order 16 bits + 8 high order bits) and use 32 bit multiplication (note that it is unsigned long

guaranteed to provide at least 32 bits).



Take care of the normalization of the result correctly.

0


source


http://en.wikipedia.org/wiki/Floating_point might be useful to read. The mantissa can only have a specific range and you will need to adjust the exponent to account for this.

0


source







All Articles