I'm using a fairly new install of Visual C++ 2008 Express.
I'm trying to compile a program that uses the log2 function, which was found by including using Eclipse on a Mac, but this Windows computer can't find the function (error C3861: 'log2': identifier not found).
The way I understood it, include directories are specific to the IDE, right? math.h is not present in my Microsoft SDKs\Windows\v6.0A\Include\ directory, but I did find a math.h in this directory: Microsoft Visual Studio 9.0\VC\include. There is also a cmath in that directory...
Where is log2?
From here:
Prototype: double log2(double anumber);
Header File: math.h (C) or cmath (C++)
Alternatively emulate it like here
#include <math.h>
...
// Calculates log2 of number.
double Log2( double n )
{
// log(n)/log(2) is log2.
return log( n ) / log( 2 );
}
Unfortunately Microsoft does not provide it.
log2()
is only defined in the C99 standard, not the C90 standard. Microsoft Visual C++ is not fully C99 compliant (heck, there isn't a single fully C99 compliant compiler in existence, I believe -- not even GCC fully supports it), so it's not required to provide log2()
.
If you're trying to find the log2
of strictly integers, some bitwise can't hurt:
#include <stdio.h>
unsigned int log2( unsigned int x )
{
unsigned int ans = 0 ;
while( x>>=1 ) ans++;
return ans ;
}
int main()
{
// log(7) = 2 here, log(8)=3.
//for( int i = 0 ; i < 32 ; i++ )
// printf( "log_2( %d ) = %d\n", i, log2( i ) ) ;
for( unsigned int i = 1 ; i <= (1<<30) ; i <<= 1 )
printf( "log_2( %d ) = %d\n", i, log2( i ) ) ;
}
With Visual Studio 2013, log2()
was added. See C99 library support in Visual Studio 2013.
Note that:
log2(x) = log(x) * log(e)
where log(e) is a constant. math.h
defines M_LOG2E
to the value of log(e)
if you define _USE_MATH_DEFINES
before inclusion of math.h
:
#define _USE_MATH_DEFINES // needed to have definition of M_LOG2E
#include <math.h>
static inline double log2(double n)
{
return log(n) * M_LOG2E;
}
Even though usual approach is to do log(n)/log(2)
, I would advise to use multiplication instead as division is always slower especially for floats and more so on mobile CPUs. For example, on modern Intel CPUs the difference in generated code in just one instruction mulsd vs divsd and according to Intel manuals we could expect the division to be 5-10 times slower. On mobile ARM cpus I would expect floating point division to be somewhere 10-100 slower than multiplication.
Also, in case if you have compilation issues with log2
for Android, seems like log2 is available in headers starting from android-18:
#include <android/api-level.h>
#if __ANDROID_API__ < 18
static inline double log2(double n)
{
return log(n) * M_LOG2E;
}
#endif