Reputation: 435
In my Computer Science course I have been assigned to write a function which takes in two floating point arguments and returns the result of their multiplication in the C language
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 points are represented in C and I have extracted the exponents and fractions by doing this:
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 the exponents (simple enough), and multiply the two fractions. The thing is I have no idea where to get started to multiply the fractions. I was thinking of converting the fraction into its hexadecimal representation as a string (ex: 0.5 would be "80000000"), and writing an algorithm to multiply the bits that way, but since I can't use any of the C libraries I have no idea how I would go about doing that. Could someone point me in the right direction?
Edit: It occured to me that floats might not be represented the same way on all systems. In this course we 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 have gotten so far. When I try and multiply the two integers, I just get zero unless I enter (long long)((long long)xRep * (long long)yRep)
into my debuggers 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);
}
Upvotes: 3
Views: 5268
Reputation: 57006
24 + 24 < 64, so you can use long long
multiplication. Long longs are guaranteed to be big enough to hold numbers from -(2^63-1) to (2^63-1)
Or you can split the number in two part (low order 16 bits + high order 8 bits) and use 32-bit multiplication (note that unsigned long
is guaranteed to provide at least 32 bits).
Take care of normalizing the result correctly afterwards.
Upvotes: 0
Reputation: 60037
http://en.wikipedia.org/wiki/Floating_point might be useful reading. The mantissa can only have a certain range and you will need to adjust the exponent to take this into account
Upvotes: 0
Reputation: 60721
Why not just multiply the fractions (extracted to their int representation) using the integer multiplication operator, *
?
Upvotes: 1