3

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

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

有关详细信息,请参阅:确定浮点平方根

谢谢!

4

2 回答 2

2

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

于 2013-07-17T20:10:38.603 回答
1

为什么不将结果平方,如果它不等于输入,添加或减去(取决于差异的符号)最低有效位,平方,并检查是否会给出更好的结果?

这里更好可能意味着绝对差异较小。这可能会变得棘手的唯一情况是当与尾数“交叉”√2时,但这可以一劳永逸地检查。

编辑

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

根据您的评论,我怀疑您使用的是严格的 32 位硬件,但让我假设您有一个 32 位乘 32 位整数乘法和 64 位结果可用(如果没有,它可以构造)。如果将 y 的尾数的 23 位作为整数,将 1 放在前面,然后将其乘以它自己,则得到一个数,除了可能额外移位 1 外,您可以直接与尾数比较x 以同样的方式处理。这样,您就可以使用所有 48 位进行比较,并且可以在没有任何近似值的情况下决定是否为 abs(y 2 -x)≷abs(z 2 -x)。

如果您不确定与最终结果的距离在一个 LSB 以内(但您肯定不会比这更远),您应该重复上述操作,直到 y 2 -x 改变符号或达到 0。注意边缘情况,但是,这基本上应该是调整指数的情况,因为尾数超过了 2 的幂。

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

于 2013-07-17T21:32:56.593 回答