用于高性能加法和乘法的常量形式

ggg*_*ggg 5 c c++ optimization underflow

我需要在循环中有效地将一些常量添加或乘以double类型的结果以防止下溢.例如,如果我们有int,则乘以2的幂会很快,因为编译器将使用位移.有效的double加法和乘法是否有一种常量形式?

编辑:似乎没有多少人理解我的问题,为我的邋iness道歉.我会添加一些代码.如果a是int,则(乘以2的幂)将更有效

int a = 1;
for(...)
    for(...)
        a *= somefunction() * 1024;
Run Code Online (Sandbox Code Playgroud)

比1024更换为1023时,如果我们想要添加到int,不确定什么是最好的,但这不是我感兴趣的.我对a双重情况感兴趣.什么是常量的形式(例如2的幂),我们可以有效地补充繁衍双?常量是任意的,只需要足够大以防止下溢.

这可能不仅限于C和C++,但我不知道更合适的标签.

Eri*_*hil 4

在大多数现代处理器上,简单地乘以 2 的幂(例如,x *= 0x1p10;乘以 2 10x *= 0x1p-10;除以 2 10)将是快速且无错误的(除非结果大到足以溢出或小到足以下溢)。

\n\n

对于某些浮点运算,有些处理器的 \xe2\x80\x9c 早期会输出\xe2\x80\x9d。也就是说,当某些位为零或满足其他标准时,它们会更快地完成指令。然而,浮点加法、减法和乘法通常在大约四个 CPU 周期内执行,因此即使没有提前输出,它们也相当快。此外,大多数现代处理器一次执行多条指令,因此在进行乘法时会继续执行其他工作,并且它们是流水线式的,因此通常可以在每个 CPU 周期中开始(并完成)一个乘法。(有时更多。)

\n\n

乘以 2 的幂没有舍入误差,因为有效数(值的小数部分)不会改变,因此新的有效数可以精确表示。(除此之外,乘以小于 1 的值时,尾数位可能会被推至低于浮点类型的限制,从而导致下溢。对于常见的 IEEE 754 双精度格式,只有当值小于0x1p-1022。)

\n\n

不要使用除法进行缩放(或反转先前缩放的效果)。相反,乘以倒数。(要删除之前的 0x1p57 缩放,请乘以 0x1p-57。)这是因为除法指令在大多数现代处理器上都很慢。例如,30 个周期并不罕见。

\n