C/C++最快的cmath日志操作

Nic*_*ick 20 c c++ logarithm math.h cmath

我正在尝试计算log a b(并获得一个浮点,而不是一个整数).我打算这样做log(b)/log(a).从数学上讲,我可以使用任何cmath日志函数(基数2,e或10)来进行此计算; 但是,我会在我的程序中运行这个计算很多,所以我想知道其中一个是否比其他程序快得多(或者更好的是,如果有更快,但仍然很简单的方法).如果重要,a和b都是整数.

Mar*_*som 15

首先,通过该表达式预先计算1.0/log(a)并乘以每个log(b)表达式.

编辑:我原先说自然对数(基数e)会最快,但其他人说处理器直接支持基数2并且速度最快.我没有理由怀疑它.

编辑2:我原先认为这a是一个常数,但在重新阅读从未说过的问题.如果是这样,那么预先计算将没有任何好处.但是,如果是,您可以通过适当选择变量名来保持可读性:

const double base_a = 1.0 / log(a);
for (int b = 0; b < bazillions; ++b)
    double result = log(b) * base_a;
Run Code Online (Sandbox Code Playgroud)

奇怪的是,微软没有提供基本2日志功能,这解释了为什么我不熟悉它.用于计算日志x86指令包括自动乘法,并且通过优化指令也可以获得不同基数所需的常数,因此我希望3个不同的对数函数具有相同的时序(即使基数2也必须乘以1).

  • @Mark:完全正确.除非设置了像"fast-math"这样的标志,否则编译器不能用倒数乘法替换除法(不仅因为它改变了舍入,而且因为它可能导致虚假溢出和NaN).是的,除了大多数*比大多数当前处理器上的乘法慢. (3认同)
  • 现代编译器不太可能使用日志指令,因为它们不准确(相对于您在软件中可以执行的操作),并且仅在已弃用的 x87 指令集中可用。 (2认同)

Jac*_*cob 11

由于ba是整数,则可以使用所有的荣耀位摆弄找到其日志基地2.这里有一些:

  • 找到一个整数的log 2,其中MSB N设置为O(N)运算(显而易见的方式)
  • 查找具有64位IEEE float的整数的整数对数基数2
  • 使用查找表查找整数的日志库2
  • 在O(lg(N))运算中找到N位整数的对数库2
  • 使用乘法和查找在O(lg(N))运算中查找N位整数的对数库2

我会留给您选择最适合您需求的"快速日志"功能.

  • 酷链接.我想知道这些方法中的任何一种方法是否比现代处理器上的直接方法更快? (4认同)