Logarithmus einer Zahl x zur Basis b
-
Hey Leuts,
habe da ein "anfänger" Problem:
Ich würde gerne den Logarithmus einer Zahl x zur Basis b berechnen, dabei wird b von mir gesetzt:Ergebnis = logb(x)
Habe schon die math.h lib durchgeschaut aber leider nichts gefunden wie ich b selber bestimmen kann. Habe ich die funktion dabei übersehen oder muss das ich dabei ganz anders vorgehen?
-
logb(x) gibts nicht in der standard-bibliothek.
nimm einfach log(x) / log(b) wobei log hier der natürliche logarithmus ist, den es im header <cmath> von der standard-bibliothek gibt.
-
Bei log(x) / log(b) ist es egal welcher Logarithmus genutzt wird, hauptsache es ist derselbe. Ich meine die Standardbibliothek hat den natürlichen und den 10er-Logarithmus zur Verfügung gestellt.
-
Es gibt ein logb, ab C++11 (und auch log2). Bloß macht der was anderes, als du anscheinend denkst (Dokumentation lesen?). Woher soll denn der Wert der Basis b kommen, wenn du das so wie bei dir aufrufst? Du denkst doch nicht, dass
int b = 5; logb(5);
funktionieren würde?
-
Naja, man könnte ja sowas machen:
double result = logb(1024, 2); // => 10
Aber du hast Recht, logb im Standard macht was anderes.
-
Skym0sh0 schrieb:
Naja, man könnte ja sowas machen:
Könnte man, wäre auch nicht so unsinnvoll. Meine Antwort richtete sich eher an den TE, der ja wohl anscheinend logb irgendwie gefunden, aber nicht verstanden hat.
-
Ok, ich sehe schon, dass die Bezeichnung unglücklich ist. Mir ist schon klar, dass die Funktion logb() etwas komplett anderes macht als das was ich brauche.
Deshalb drücke ich mich anders aus: Ich würde gerne den Logarithmus einer Zahl x zur Basis y berechnen, dabei wird y von mir gesetzt. So in der Art:
logy(x)
y möchte ich dabei selber bestimmen.
math.h bietet mir nur log(), log2() und log10() an. Aber nirgends kann ich die Basis selber angeben.
Mathematisch kann ich das folgend berechnen:
logy(x)=((log10(x))/(log10(y)))
Aber gib es das als Funktion?
-
Alter, das ist ein Einzeiler, wenn Du dich anstrengst, kannst Du das vielleicht auch zwischend zwei Zeilen implementieren.
-
Aggro schrieb:
Alter, das ist ein Einzeiler, wenn Du dich anstrengst, kannst Du das vielleicht auch zwischend zwei Zeilen implementieren.
Klar ist es das. Doch wenn die Rechnung diese Operation mehrmals und vor allem noch weitere Operationen erfordert, würde eine Funktion nicht nur die Arbeit erleichtern sondern den Code auch übersichtlicher machen.
Danke für den informativen Beitrag.
-
Ich meinte schon, dass du das als Funktion implementieren solltest...
-
spleen schrieb:
Danke für den informativen Beitrag.
Das ist aber die Lösung, ob es dir gefällt oder nicht. Und da gibt es auch technische Gründe für in der Art, wie Logarithmen berechnet werden. Eine allgemeine Funktion, die für jede Basis funktioniert ist nicht gut zu machen, außer sie nutzt die genannte Relation.
Und da es so trivial ist und so selten benötigt wird (wann braucht man jemals einen log_b im großen Stil?) ist das kein Teil der Standardbibliothek. So eine Funktion kann sich jeder schnell selber schreiben, wenn man das mal mehr als einmal pro Programm benötigt.
-
spleen schrieb:
Doch wenn die Rechnung diese Operation mehrmals und vor allem noch weitere Operationen erfordert, würde eine Funktion nicht nur die Arbeit erleichtern sondern den Code auch übersichtlicher machen..
Nein - es gibt keine solche Funktion in <cmath> (ehemals math.h)
wenn es nur um Übersicht geht, so kannst Du Dir natürlich eine eigene schreiben. Besser als Template, so gilt das fürdouble
undfloat
gleichermaßen.template< typename T > T logy( T x, T base ) { return std::log(x) / std::log(base); // erfordert #include <cmath> } // ... oder spezifisch, falls z.B. base=2 öfter vorkommt template< typename T > T log2( T x ) { static const T log2_inv = T(1) / std::log(T(2)); return std::log(x) * log2_inv; }
-
.. das wäre auch noch eine Möglichkeit (für ganzzahlige Basen):
template< unsigned Base, typename T > T lg( T x ) { static const T lg_inv = T(1) / std::log(T(Base)); return std::log(x) * lg_inv; }
aufzurufen z.B. so:
cout << "log(" << x << ") zur Basis 2=" << lg<2>(x) << endl;
setzt selbstverständlich voraus, dass die Basis zur Compilezeit bekannt ist.