web-dev-qa-db-fra.com

log2 introuvable dans mon math.h?

J'utilise une installation assez récente de Visual C++ 2008 Express.

J'essaie de compiler un programme qui utilise la fonction log2, qui a été trouvée en incluant Eclipse sur un Mac, mais cet ordinateur Windows ne peut pas trouver la fonction (erreur C3861: 'log2': identifiant introuvable).

D'après ce que j'ai compris, les répertoires sont spécifiques à l'IDE, non? math.h n'est pas présent dans mon répertoire Microsoft SDKs\Windows\v6.0A\Include \, mais j'ai trouvé un math.h dans ce répertoire: Microsoft Visual Studio 9.0\VC\include. Il y a aussi un cmath dans ce répertoire ...

Où est log2?

31
Tony R

De ici :

Prototype: double log2 (double numéro);
Fichier d'en-tête: math.h (C) ou cmath (C++)

Vous pouvez également l'émuler comme ici

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

Malheureusement Microsoft ne le fournit pas .

59
lothar

log2() n'est définie que dans la norme C99, pas dans la norme C90. Microsoft Visual C++ n'est pas entièrement conforme à C99 (diable, il n'y a pas un seul compilateur entièrement conforme à C99, je crois - même GCC ne le prend pas entièrement en charge), il n'est donc pas nécessaire de fournir log2().

10
Adam Rosenfield

Si vous essayez de trouver le log2 de nombres strictement entiers, certains au niveau du bit ne peuvent pas faire de mal:

#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 ) ) ;
}
10
bobobobo

Notez que:

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

où log (e) est une constante. math.h Définit M_LOG2E À la valeur de log(e) si vous définissez _USE_MATH_DEFINES Avant d'inclure 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;
}

Même si l'approche habituelle consiste à faire log(n)/log(2), je conseillerais d'utiliser la multiplication à la place car la division est toujours plus lente, en particulier pour les flottants et plus encore sur les processeurs mobiles. Par exemple, sur les processeurs Intel modernes la différence de code généré en une seule instruction mulsd vs divsd et selon les manuels Intel, nous pourrions nous attendre à la division être 5 à 10 fois plus lent. Sur mobile ARM cpus, je m'attendrais à ce que la division en virgule flottante soit quelque part 10-100 plus lente que la multiplication.

De plus, si vous rencontrez des problèmes de compilation avec log2 Pour Android, il semble que log2 soit disponible dans les en-têtes à partir d'Android-18:

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

Avec Visual Studio 2013, log2() a été ajouté. Voir Prise en charge de la bibliothèque C99 dans Visual Studio 201 .

3
Daniel Rose