【问题标题】:Implementing floating point subtraction实现浮点减法
【发布时间】:2009-02-26 15:35:16
【问题描述】:

我正在尝试实现一个浮点算术库,但我无法理解减去浮点数的算法。我已经成功地实现了加法,我认为减法只是它的一个特例,但似乎我在某处犯了错误。 我在这里添加代码仅供参考,它有很多不言自明的功能,但我不希望有人能 100% 理解它。我想要帮助的是算法。我们遵循与添加浮点数相同的方法,除了当我们添加尾数时,我们将负数(我们减去的那个)转换为二进制补码然后添加它们?

这就是我正在做的,但结果不正确。虽然它非常接近......但不一样。有人有什么想法吗?提前致谢!

我很确定我做事的方式是有效的,因为我实现了一个几乎相同的算法来添加浮点数,它就像一个魅力。

_float subFloat(_float f1,_float f2)
{
unsigned char diff;
_float result;

//first see whose exponent is greater
if(f1.float_parts.exponent > f2.float_parts.exponent)
{
    diff = f1.float_parts.exponent - f2.float_parts.exponent;

    //now shift f2's mantissa by the difference of their exponent to the right
    //adding the hidden bit
    f2.float_parts.mantissa = ((f2.float_parts.mantissa)>>1) | (0x01<<22);
    f2.float_parts.mantissa >>= (int)(diff);//was (diff-1)

    //also increase its exponent by the difference shifted
    f2.float_parts.exponent = f2.float_parts.exponent + diff;
}
else if(f1.float_parts.exponent < f2.float_parts.exponent)
{
    diff = f2.float_parts.exponent - f1.float_parts.exponent;
    result = f1;
    f1 = f2;        //swap them
    f2 = result;

    //now shift f2's mantissa by the difference of their exponent to the right
    //adding the hidden bit
    f2.float_parts.mantissa = ((f2.float_parts.mantissa)>>1) | (0x01<<22);
    f2.float_parts.mantissa >>= (int)(diff);

    //also increase its exponent by the difference shifted
    f2.float_parts.exponent = f2.float_parts.exponent + diff;
}
else//if the exponents were equal
  f2.float_parts.mantissa = ((f2.float_parts.mantissa)>>1) | (0x01<<22); //bring out the hidden bit




//getting two's complement of f2 mantissa
f2.float_parts.mantissa ^= 0x7FFFFF;
f2.float_parts.mantissa += 0x01;



result.float_parts.exponent = f1.float_parts.exponent;
result.float_parts.mantissa = (f1.float_parts.mantissa +f2.float_parts.mantissa)>>1;
                                                //gotta shift right by overflow bits

//normalization
if(manBitSet(result,1))
    result.float_parts.mantissa <<= 1;  //hide the hidden bit
else
    result.float_parts.exponent +=1;

return result;

}

【问题讨论】:

    标签: floating-point subtraction


    【解决方案1】:

    a-b == a+(-b),而一元减号是微不足道的,所以我什至不会为二元减号而烦恼。

    【讨论】:

    • 谢谢你的回答,但我不明白你的意思。
    • 4 - 2 == 4 + (-2)。只需翻转符号位。
    • MSalters 建议您通过否定加数之一然后正常添加来执行减法。从您在原始帖子中的“减法只是一个特例”中判断,我想您已经知道了......
    • 不,我想你误会了。我不能只更改符号位并添加。当我说我的添加有效时,我的意思是添加相同的符号浮动有效。减法是添加不同的有符号浮点数。这就是上面代码的用途,但它没有给出预期的结果。
    【解决方案2】:

    如果您的加法代码正确,而您的减法错误,则问题可能出在二进制补码和加法上。

    是不是需要做补码和加法,而不是减法?

    如果这不是问题,我的算法有问题。我已经有一段时间没有做这样的事情了。你能提供一些细节吗?更具体地说,隐藏位是什么?

    在我看来,隐藏位的处理适用于加法但不适用于减法。难道你应该将它设置在 f1 尾数而不是 f2 中?或者否定 f1 尾数而不是 f2?

    不知道你得到了什么和你期望什么,以及你正在使用的算法的更多细节,这是我能做的最好的。

    编辑:好的,我查看了您评论中的参考资料。您在提供的代码中没有做的一件事是规范化。添加时,隐藏位溢出(尾数左移,指数递增),或者它们不溢出。减法时,尾数的任意部分可以为零。十进制,考虑加0.5E1和0.50001E1;你会得到 1.00001E1,如果你要标准化,你会得到 0.10001E2。当从 0.50001E1 中减去 0.5E1 时,得到 0.00001E1。然后你需要将尾数向左移动,并尽可能减少指数,得到 0.1E-4。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-22
    • 2012-01-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多