在C中编写浮点乘法函数

时间:2012-03-15 17:16:24

标签: c floating-point

在我的计算机科学课程中,我被分配编写一个函数,该函数接受两个浮点参数并在C语言中返回它们的乘法结果

float multiply(float foo, float bar);

除了赋值运算符=

之外,我不允许使用任何库或任何浮点运算

我理解浮点数是如何在C中表示的,我通过这样做提取了指数和分数:

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);

我知道我需要添加指数(足够简单),并将两个分数相乘。事情是我不知道从哪里开始增加分数。我正在考虑将分数转换为十六进制表示为一个字符串(例如:0.5将是“80000000”),并编写一个算法来乘以那些方式,但由于我不能使用任何C库,我有不知道我会怎么做。有人能指出我正确的方向吗?

编辑:我发现浮动可能不会在所有系统上以相同的方式表示。在本课程中,我们假设第一位是符号,接下来的8位是指数,最后23位是分数。

编辑:这是我到目前为止所得到的。当我尝试将两个整数相乘时,除非我将(long long)((long long)xRep * (long long)yRep)输入调试器监视列表,否则我只会得零;

#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 个答案:

答案 0 :(得分:1)

为什么不使用整数乘法运算符*将这些分数(提取到它们的int表示)相乘?

答案 1 :(得分:0)

24 + 24&lt; 64,所以你可以使用long long乘法。保证长多头足以容纳数字 - (2 ^ 63-1)到(2 ^ 63-1)

或者您可以将数字分成两部分(低位16位+高位8位)并使用32位乘法(注意unsigned long保证至少提供32位)。

事后正确处理正确的结果。

答案 2 :(得分:0)

http://en.wikipedia.org/wiki/Floating_point可能对您有用。尾数只能有一定的范围,你需要调整指数才能考虑到这一点