浮点平方根倒数法正确舍入

时间:2013-07-17 19:38:43

标签: c algorithm math floating-point computer-science

基于找到平方根的倒数,我使用Newton-Raphson方法(在汇编中)实现了32位IEEE-754浮点平方根。 我正在使用舍入到最近的舍入方法。 我的平方根方法只接受标准化值和零,但没有非规范化值或特殊值(NaN,Inf等)

我想知道如何才能实现正确的舍入(使用汇编语句),以便我的结果对于所有输入都是正确的(对于IEEE-754)? 基本上,我知道如何测试我的结果是否正确,但我想调整下面的算法,以便我获得正确的舍入结果。我应该在算法中添加哪些指令?

请参阅:Determining Floating Point Square Root 了解更多信息

谢谢!

2 个答案:

答案 0 :(得分:2)

只有大约20亿float s符合您的描述。全部尝试,与C库中的sqrtf进行比较,并检查所有差异。如果您担心,可以使用C库中的sqrtsqrtl获得更高精度的平方根。 sqrtsqrtfsqrtl由典型的C库正确舍入,因此直接比较应该有效。

答案 1 :(得分:1)

为什么不对结果进行平方,如果它不等于输入,则加或减(取决于差异的符号)最低有效位,平方,并检查是否会产生更好的结果?

这里更好的意思是绝对差别越小。唯一可能变得棘手的情况是当与尾数“交叉”√2时,可以一次性检查这一点。

修改

我意识到上述答案是不够的。简单地在32位FP中进行平方并与输入进行比较并不能提供足够的信息。假设y = your_sqrt(x)。你将y 2 与x进行比较,发现y 2 &gt; x,从y中减去1 LSB得到z(你的评论中为y1),然后比较z 2 到x并且发现不仅z 2 &lt; x,而且,在可用位中,y 2 -x == xz 2 < / sup> - 你如何在y和z之间做出选择?您应该使用所有位(我猜这是您正在寻找的),或者至少有更多位(我猜这是njuffa建议的)。

根据您的评论,我怀疑您使用的是严格的32位硬件,但我想假设您有一个32位乘32位整数乘法,并且可以获得64位结果(如果没有,可以构造它) )。如果你把y的尾数的23位作为一个整数,在前面放一个1,然后将它自己乘以,你有一个数字,除了可能的额外移位1,你可以直接比较尾数x以同样的方式对待。通过这种方式,您可以将所有48位用于比较,并且无需任何近似即可决定是否abs(y 2 -x)≷abs(z 2 -x)。 / p>

如果你不确定是否在最终结果的一个LSB​​范围内(但你肯定不会比这更远),你应该重复上述步骤直到y 2 -x改变符号或者命中0.注意边缘情况,这应该基本上是调整指数的情况,因为尾数超过2的幂。

记住正浮点数可以正确地比较为整数也是有帮助的,至少在1.0F为0x3f800000的那些机器上是这样。