2009-04-16 5 views
29

Ich verwende eine ziemlich neue Installation von Visual C++ 2008 Express.log2 nicht in meinem Math.h gefunden?

Ich versuche, ein Programm zu kompilieren, das die log2-Funktion verwendet, die durch die Verwendung von Eclipse auf einem Mac gefunden wurde, aber dieser Windows-Computer kann die Funktion nicht finden (Fehler C3861: 'log2': Bezeichner nicht gefunden).

Die Art, wie ich es verstanden habe, einschließlich Verzeichnisse sind spezifisch für die IDE, richtig? Math.h ist nicht in meinem Microsoft SDKs \ Windows \ v6.0A \ Include \ -Verzeichnis vorhanden, aber ich habe eine Math.h in diesem Verzeichnis gefunden: Microsoft Visual Studio 9.0 \ VC \ include. Es gibt auch einen cmath in diesem Verzeichnis ...

Wo ist log2?

+0

viel bessere Antworten [hier] (http://stackoverflow.com/questions/994593/how-to-do-an-integer-log2-in-c) – bobobobo

Antwort

56

Von here:

Vorbild: Doppel log2 (Doppel anumber);
Header-Datei: math.h (C) oder cmath (C++)

emulieren es alternativ wie here

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

Leider does not provide it Microsoft.

+2

'log (2)' Um zu vermeiden, dass sich der Compiler über einen mehrdeutigen Aufruf beschwert – jirkamat

+8

Sie sollten den Wert von log (2) wirklich als statisches Double oder als vorberechnete Konstante speichern (0. 30102999566398119521373889472449) so dass 'log()' nicht zweimal aufgerufen wird – bobobobo

+5

log (2) sollte von einem guten Optimierer in eine const static optimiert werden. Ich habe dies anhand eines Testfalls in vc2008 verifiziert und es ist besser, keine handgeschriebenen Konstanten zu verwenden. Dies stellt eine numerische Konsistenz mit anderen Laufzeitfunktionen sicher, nicht dass ein paar Dezimalstellen ein Problem wären, aber trotzdem. – Crog

9

log2() ist nur im C99-Standard definiert, nicht im C90-Standard. Microsoft Visual C++ ist nicht vollständig C99-kompatibel (heck, es gibt keinen einzigen vollständig C99-kompatiblen Compiler, glaube ich - nicht einmal GCC unterstützt es vollständig), so dass es nicht erforderlich ist, log2() bereitzustellen.

10

Wenn Sie versuchen, die log2 streng ganzen Zahlen zu finden, können einige bitweise nicht schaden:

#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

Natürlich wird das funktionieren, aber seine Leistung ist so viel schlechter als log2 (n). Log2 hat eine konstante Zeit und ist immer schneller. Diese Lösung ist O (log2n). Für eine große Anzahl ist log2 etwa 500% schneller. – ruralcoder

+0

Ja, es kann Leistung und Qualität beeinträchtigen. Mehr Code = mehr mögliche Fehlerquellen. –

+0

@ruralcoder Dies ist der effizienteste Weg, 'log (base2)' einer Ganzzahl zu finden. – 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; 
} 

Im Fall, wenn Sie Kompilierung Probleme mit log2 für Android haben, wie log2 scheint in Header verfügbar ist von android-18 starten :

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