我正在尝试实现一个浮点算术库,但我在理解减法浮点数的算法时遇到了困难。我已经成功地实现了加法,我认为减法只是它的一个特例,但似乎我在某个地方犯了一个错误。我在这里添加代码只是为了参考,它有许多自解释的功能,但我不希望有人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;
}发布于 2009-02-26 16:17:55
如果你的加法代码是正确的,而你的减法代码是错的,那么问题大概出在两个人的补码和加法上。
有必要做两个人的加法和补码,而不是减法吗?
如果这不是问题所在,我对你的算法有问题。我已经有一段时间没有做这样的事情了。你能提供一些细节吗?更具体地说,隐藏的部分是什么?
在我看来,隐藏位的处理对于加法来说是合适的,但对于减法来说是不合适的。是否应该在f1尾数而不是f2中设置它?或者否定f1尾数而不是f2?
不知道你得到了什么和你期望的是什么,以及你使用的算法的更多细节,这是我所能做的最好的事情。
编辑:好的,我看了你评论中的引用。在提供的代码中,您没有做到的一件事就是规范化。加法时,要么隐藏位溢出(尾数向左移位,增量指数),要么不溢出。减法时,尾数的任意部分可以为零。在十进制中,考虑添加0.5E1和0.50001E1;您将得到1.00001E1,如果要进行标准化,则将得到0.10001E2。从0.50001E1中减去0.5E1,得到0.00001E1。然后,你需要将尾数向左移动,并尽可能多地减少指数,以获得0.1E-4。
发布于 2009-02-26 15:56:19
a-b == a+(-b),而一元减是微不足道的,所以我甚至不会费心使用二进制减。
https://stackoverflow.com/questions/591046
复制相似问题