是否可以在形式上进行浮动除法的倒数 查找表(如1 / f - > 1 * inv [f])?怎么做? 我认为应该将一些和掩盖和移位应用于浮动 它是一种索引形式?怎么会这样呢?
答案 0 :(得分:6)
你可以猜出这样的近似逆:
int x = reinterpret_cast<int>(f);
x = 0x7EEEEEEE - x;
float inv = reinterpret_cast<float>(x);
在我的测试中,0x7EF19D07略好一些(测试了包含2个Newton-Raphson改进的效果)。
然后您可以使用Newton-Raphson进行改进:
inv = inv * (2 - inv * f);
根据需要随时迭代。 2或3次迭代可以得到很好的结果。
最小化相对误差:
最小化1到2之间输入的绝对误差(它们在该范围之外运行良好,但它们可能不是最好的):
对于三个细化步骤,初始近似几乎不影响最大相对误差。 0x7EEEEEEE运行良好,我找不到更好的东西。
答案 1 :(得分:3)
一种方法是:
在第2步中,您需要选择要使用的位数,在准确度和表格大小之间进行交易。通过使用较低有效位在表条目之间进行插值,可以获得更高的精度。
在步骤3中,调整是必要的,因为输入尾数在范围(0.5,1.0)内,因此其倒数在[1.0,2.0]范围内,需要重新正规化以给出输出尾数。
我不会尝试为此编写代码,因为我可能会错过一些稍微偏僻的边缘情况。
您还应该研究涉及数值计算的方法,如果内存访问速度慢,可能会产生更好的结果;在现代PC架构中,缓存未命中可能与几十个算术运算一样昂贵。 Wikipedia看起来是一个很好的起点。当然,无论你做什么,都要测量它以确保它实际上比FPU除法操作更快。
答案 2 :(得分:0)
如果你的最小步长是0.01,那么你可以从表中支持inverse-f。每个索引都乘以100,因此您可以
table[1]----->1.0/0.01
table[3]----->1.0/0.03
table[105]--->1.0/1.05
...
table[10000]->1.0/100.0
10000 elements for a range of (0.00,100.00)
如果你想要更高的精度,你需要更多的ram。
另一个例子:
range................: 0.000 - 1000.000
minimum increments ..: 0.001
total element number.: 1 million
something like this: table[2343]=1.0/2.343
另一个例子:
range................: 0.000000 - 1.000000
minimum increments ..: 0.000001
total element number.: 1 million
something like this: table[999999]=1.0/0.999999