2009-04-16 12 views
29

Używam całkiem nowej instalacji programu Visual C++ 2008 Express.log2 nie znaleziono w moim math.h?

Próbuję skompilować program, który używa funkcji log2, która została znaleziona poprzez włączenie Eclipse na komputerze Mac, ale ten komputer Windows nie może znaleźć funkcji (błąd C3861: "log2": nie znaleziono identyfikatora).

Sposób, w jaki to zrozumiałem, obejmuje katalogi specyficzne dla IDE, prawda? math.h nie ma w moim katalogu Microsoft SDK \ Windows \ v6.0A \ Include \, ale znalazłem w tym katalogu math.h: Microsoft Visual Studio 9.0 \ VC \ include. W tym katalogu znajduje się również cmath ...

Gdzie jest log2?

+0

Znacznie lepsze odpowiedzi [tutaj] (http://stackoverflow.com/questions/994593/how-to-do-an-integer-log2-in-c) – bobobobo

Odpowiedz

56

Z here:

Prototyp: podwójne log2 (podwójne anumber);
nagłówka pliku: math.h (C) lub cmath (C++)

Alternatywnie naśladować go jak here

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

Niestety Microsoft does not provide it.

+2

'log (2)' aby uniknąć kompilatora narzekającego na niejednoznaczne wywołanie – jirkamat

+8

Naprawdę powinieneś zapamiętać wartość log (2) jako statyczną podwójną lub wstępnie obliczoną stałą (0. 30102999566398119521373889472449), aby 'log()' nie był wywoływany dwa razy za każdym razem, gdy – bobobobo

+5

log (2) powinien zostać zoptymalizowany do statycznej stałej przez dobry optymalizator. Zweryfikowałem to za pomocą przypadku testowego w v2008 i lepiej jest nie używać ręcznie pisanych stałych. Zapewnia to zgodność numeryczną z innymi funkcjami wykonawczymi, a nie, że kilka miejsc dziesiętnych stanowiłoby problem, ale i tak. – Crog

9

log2() jest zdefiniowany tylko w standardzie C99, a nie w standardzie C90. Microsoft Visual C++ nie jest w pełni zgodny z C99 (heck, nie ma jednego, w pełni kompatybilnego kompilatora C99, jak sądzę - nawet GCC w pełni go nie obsługuje), więc nie jest wymagane dostarczanie log2().

10

Jeśli próbujesz znaleźć log2 ściśle liczb, niektóre bitowe nie zaszkodzi:

#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

Oczywiście to zadziała, ale jego wydajność jest znacznie gorsza niż log2 (n). Log2 ma stały czas i jest zawsze szybszy. To rozwiązanie to O (log2n). Dla dużej liczby log2 jest około 500% szybszy. – ruralcoder

+0

Tak, może to zaszkodzić wydajności i jakości. Więcej kodu = więcej możliwych źródeł błędów. –

+0

@ruralcoder Jest to najbardziej efektywny sposób na znalezienie 'log (base2)' liczby całkowitej. – 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; 
} 

W przypadku, jeśli masz problemy kompilacji z log2 dla Android, wydaje się log2 jest dostępny w nagłówkach począwszy od android-18 :

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