log2 not found in my math.h?

2019-01-09 05:47发布

问题:

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?

回答1:

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.



回答2:

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().



回答3:

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 ) ) ;
}


回答4:

With Visual Studio 2013, log2() was added. See C99 library support in Visual Studio 2013.



回答5:

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