C++ 作为乘法和LUT的除法?/快速浮除倒数

C++ 作为乘法和LUT的除法?/快速浮除倒数,c++,c,optimization,fpu,C++,C,Optimization,Fpu,有可能在形式上做一个浮点除法的倒数吗 查找表的类型(如1/f->1*inv[f])?如何做到这一点? 我认为应该应用一些遮罩和移位来进行浮动 它是索引的一种形式吗?如何执行?如果最小步长类似于0.01,则可以从表中支持逆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 elem

有可能在形式上做一个浮点除法的倒数吗 查找表的类型(如1/f->1*inv[f])?如何做到这一点? 我认为应该应用一些遮罩和移位来进行浮动
它是索引的一种形式吗?如何执行?

如果最小步长类似于0.01,则可以从表中支持逆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)
如果你想要更好的精度,你需要更多的内存

另一个例子:

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
另一个例子:

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
一种方法是:

  • 从输入中提取符号、指数和尾数
  • 使用一些最重要的尾数位在表中查找其倒数
  • 对指数求反,并根据尾数比例的变化进行调整
  • 重新组合符号、指数和尾数以形成输出
  • 在步骤2中,您需要选择要使用的位数,在精度和表大小之间进行交易。通过使用低有效位在表项之间插值,可以获得更高的精度

    在步骤3中,调整是必要的,因为输入尾数在范围(0.5,1.0)内,因此其倒数在范围[1.0,2.0]内,需要重新规范化以给出输出尾数

    我不会尝试为此编写代码,因为我可能会错过一些稍微复杂的边缘案例


    你还应该研究涉及数值计算的方法,如果内存访问速度慢,可能会得到更好的结果;在现代PC体系结构中,缓存未命中可能与几十次算术运算一样昂贵。这看起来是一个很好的起点。当然,无论你做什么,都要测量它,以确保它实际上比其他运算更快一种FPU除法运算。

    你可以猜一个近似的倒数,如下所示:

    int x = bit_cast<int>(f);
    x = 0x7EEEEEEE - x;
    float inv = bit_cast<float>(x);
    
    你想迭代多久就迭代多久。2到3次迭代会得到很好的结果

    更好的初始近似 要最小化相对误差,请执行以下操作:

    • 0x7EF311C2(无细化)
    • 0x7EF311C3(1个优化)
    • 0x7EF312AC(2次改进)
    • 0x7EEBB3(3次改进)
    为了最大限度地减小1到2之间输入的绝对误差(在该范围外,它们工作得足够好,但可能不是最好的):

    • 0x7EF504F3(无细化)
    • 0x7EF40D2F(1个优化)
    • 0x7EF39252(2次改进)

    对于三个细化步骤,初始近似几乎不影响最大相对误差。0x7eee工作得很好,我找不到更好的方法。

    您是否意识到这要么会损失很多精度,要么会导致一个巨大的查找表?即使您将自己限制在
    [0.0,1.0)
    @up我只需要倒数-比如说10位精度(查找表中有1024个浮点数)-我不知道它是更快还是更快slower@H2CO3不,我需要除法,不是倒正方形root@grungefightr(面部手掌截断)我知道,我的意思是,你想用位级操作实现快速除法,还是特别想使用查找表?这有点帮助,但我不想将浮点转换为整数。我需要一个查找表,由移位和屏蔽的浮点索引。你是对的,移位可能比乘法快。但你不能告诉我们e一个用于索引原语的浮点。你知道,我想我只需要映射浮点的一些二进制部分(其中包含最重要的位)并使用这些位(比如10位)要将其用作查找表中的索引-不需要有序索引、转换和计算-我知道我应该以浮点格式查找规范:>@Grungfightr:是的,这是第2阶段的工作,但您还需要计算新的指数。该死的指数,它需要位,耶-忘记了:(将重新考虑它(如果没有人同时给出一些有用的代码示例,那么就接受答案l8er):/至少我可以尝试在特定的除法情况下使用它,在这种情况下,我知道我用……细分的浮点的范围。:/Will tryit@grungefightr在我的电脑上工作;)但是,更严重的是,它的工作原理是否定指数,以及它对尾数(或有意义的)所做的事情我真的不明白。但不知怎么的,它工作得很好。很有趣,你能为那个类型附加一个完整的工作示例吗?你不应该使用带有
    reinterpret\u cast
    ?@user2485710
    *reinterpret\u cast(&f)的指针吗
    然后呢?@harold是的,我知道,我对你的一个具体例子很感兴趣,你能不能提供一个工作示例来进一步扩展一下?