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);
}
source to share
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.
source to share
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.
source to share