我已经使用 Newton-Raphson 方法(在汇编中)基于找到平方根的倒数实现了 32 位 IEEE-754 浮点平方根。
我正在使用舍入到最接近的舍入方法。
我的平方根方法只接受归一化值和零,但不接受非归一化值或特殊值(NaN、Inf 等)
我想知道如何实现正确的舍入(使用类似指令的汇编),以便我的结果对于所有输入都是正确的(符合 IEEE-754)?
基本上,我知道如何测试我的结果是否正确,但我想调整下面的算法,以便获得正确的舍入结果。我应该向算法添加哪些指令?
参见:Determining Floating Point Square Root
了解更多信息
谢谢!
最佳答案
为什么不对结果求平方,如果它不等于输入,加或减(取决于差的符号)一个最低有效位,平方,然后检查是否会给出更好的结果?
这里更好可能意味着绝对差异更小。这可能变得棘手的唯一情况是当尾数“交叉”√2 时,但这可以一劳永逸地检查。
编辑
我意识到上述答案是不够的。简单地在 32 位 FP 中平方并与输入进行比较并不能为您提供足够的信息。假设 y = your_sqrt(x)。您将 y2 与 x 进行比较,发现 y2>x,从 y 中减去 1 LSB 得到 z(在您的评论中为 y1),然后将 z2 与 x 进行比较,发现不仅 z2
根据您的评论,我怀疑您使用的是严格的 32 位硬件,但让我假设您有一个 32 位乘以 32 位整数乘法和 64 位结果可用(如果没有,则可以构造它)。如果你把y的尾数的23位作为一个整数,在前面加一个1,然后再乘以它自己,你就得到了一个数,除了可能额外移位1之外,你可以直接与y的尾数进行比较x 处理方式相同。通过这种方式,您可以使用所有 48 位进行比较,并且无需任何近似值就可以决定是否 abs(y2-x)≷abs(z2-x)。
如果您不确定与最终结果在一个 LSB 之内(但您肯定不会比这更远),您应该重复上述操作,直到 y2-x 更改符号或达到 0。不过要注意边缘情况,这基本上应该是指数被调整的情况,因为尾数与 2 的幂相交。
记住正浮点数可以作为整数正确比较也是有帮助的,至少在那些 1.0F 是 0x3f800000 的机器上是这样。
关于c - 浮点平方根倒数法修正四舍五入,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17708770/