2009-04-16 16 views
29

Estoy usando una instalación relativamente nueva de Visual C++ 2008 Express.log2 no encontrado en mi math.h?

Estoy tratando de compilar un programa que usa la función log2, que se encontró incluyendo el uso de Eclipse en una Mac, pero esta computadora con Windows no puede encontrar la función (error C3861: 'log2': identificador no encontrado)

De la forma en que lo entendí, los directorios son específicos del IDE, ¿no? math.h no está presente en mi directorio Microsoft SDKs \ Windows \ v6.0A \ Include \, pero encontré un math.h en este directorio: Microsoft Visual Studio 9.0 \ VC \ include. También hay un cmath en ese directorio ...

¿Dónde está log2?

+0

mucho mejores respuestas [aquí] (http://stackoverflow.com/questions/994593/how-to-do-an-integer-log2-in-c) – bobobobo

Respuesta

56

De here:

Prototipo: doble log2 (doble anumber);
del encabezado del archivo: math.h (C) o cmath (C++)

Alternativamente emularlo como here

#include <math.h> 
... 
// Calculates log2 of number. 
double Log2(double n) 
{ 
    // log(n)/log(2) is log2. 
    return log(n)/log(2); 
} 

Desafortunadamente Microsoft does not provide it.

+2

'log (2)' para evitar que el compilador se queje de la llamada ambigua – jirkamat

+8

Realmente debe almacenar el valor de log (2) como un doble estático o una constante precalculada (0. 30102999566398119521373889472449) de modo que 'log()' no se invoque dos veces cada vez que – bobobobo

+5

log (2) se optimice en una constante con un buen optimizador. Lo he verificado usando un caso de prueba en vc2008 y es mejor práctica no usar constantes escritas a mano. Esto garantiza la coherencia numérica con otras funciones de tiempo de ejecución, no es que algunos decimales sean un problema, pero de todos modos. – Crog

9

log2() solo se define en el estándar C99, no en el estándar C90. Microsoft Visual C++ no es totalmente compatible con C99 (diablos, no existe un único compilador totalmente compatible con C99, creo, ni siquiera GCC lo admite), por lo que no es necesario proporcionar log2().

10

Si usted está tratando de encontrar la log2 de números enteros estrictamente, algunos bit a bit no puede hacer daño:

#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)) ; 
} 
+2

Por supuesto, esto funcionará pero su rendimiento es mucho peor que log2 (n). Log2 tiene un tiempo constante y siempre es más rápido. Esta solución es O (log2n). Para un gran número, log2 es aproximadamente 500% más rápido. – ruralcoder

+0

Sí, puede perjudicar el rendimiento y la calidad. Más código = más fuentes posibles de errores. –

+0

@ruralcoder Esta es la forma más eficiente de encontrar 'log (base2)' de un entero. – bobobobo

0

log2 (x) = log (x) * log (e):

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

En caso si usted tiene problemas de compilación con log2 para Android, parece como log2 está disponible en las cabeceras a partir de android-18 :

#include <android/api-level.h> 
#if __ANDROID_API__ < 18 
static inline double log2(double n) 
{ 
    return log(n) * M_LOG2E; 
} 
#endif