Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C/C++ fastest cmath log operation

I'm trying to calculate logab (and get a floating point back, not an integer). I was planning to do this as log(b)/log(a). Mathematically speaking, I can use any of the cmath log functions (base 2, e, or 10) to do this calculation; however, I will be running this calculation a lot during my program, so I was wondering if one of them is significantly faster than the others (or better yet, if there is a faster, but still simple, way to do this). If it matters, both a and b are integers.

like image 370
Nick Avatar asked Jul 11 '11 20:07

Nick


People also ask

What is log2 in C?

The log2 function in C computes the base-2 logarithm of x . A domain error occurs if the argument is less than zero. A pole error may occur if the argument is zero. The x is the argument that is passed into the log2(). It is declared in math.

How do you type log base 2?

The log base 2 can be written as log2N=k l o g 2 N = k , which can be further written in exponential form as 2k = N.

How do you approximate logs?

log(1+x)≈x. ⁡ In general, if x is smaller than 0.1 our approximation is practical. This occurs because for small x , the area under the curve (which is what log is a measurement of) is approximately that of a rectangle of height 1 and width x .


3 Answers

First, precalculate 1.0/log(a) and multiply each log(b) by that expression instead.

Edit: I originally said that the natural logarithm (base e) would be fastest, but others state that base 2 is supported directly by the processor and would be fastest. I have no reason to doubt it.

Edit 2: I originally assumed that a was a constant, but in re-reading the question that is never stated. If so then there would be no benefit to precalculating. If it is however, you can maintain readability with an appropriate choice of variable names:

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

Strangely enough Microsoft doesn't supply a base 2 log function, which explains why I was unfamiliar with it. Also the x86 instruction for calculating logs includes a multiplication automatically, and the constants required for the different bases are also available via an optimized instruction, so I'd expect the 3 different log functions to have identical timing (even base 2 would have to multiply by 1).

like image 157
Mark Ransom Avatar answered Nov 05 '22 18:11

Mark Ransom


Since b and a are integers, you can use all the glory of bit twiddling to find their logs to the base 2. Here are some:

  • Find the log base 2 of an integer with the MSB N set in O(N) operations (the obvious way)
  • Find the integer log base 2 of an integer with an 64-bit IEEE float
  • Find the log base 2 of an integer with a lookup table
  • Find the log base 2 of an N-bit integer in O(lg(N)) operations
  • Find the log base 2 of an N-bit integer in O(lg(N)) operations with multiply and lookup

I'll leave it to you to choose the best "fast-log" function for your needs.

like image 27
Jacob Avatar answered Nov 05 '22 16:11

Jacob


On the platforms for which I have data, log2 is very slightly faster than the others, in line with my expectations. Note however, that the difference is extremely slight (only a couple percent). This is really not worth worrying about.

Write an implementation that is clear. Then measure the performance.

like image 4
Stephen Canon Avatar answered Nov 05 '22 17:11

Stephen Canon