Logarithmus implementieren?



  • Leider findet man dazu im Internet keine brauchbaren Ideen.

    Will mit einer bignumber-Klasse Logarithmusberechnugnen durchführen, die hat jedoch keine log-Funktion.

    Jetzt bräuchte ich zumindest einen Logarithmus (am besten den der am leichtesten zu kriegen ist (wahrscheinlich log10 oder log2)).

    Ich hab Zugriff auf jede Stelle der Zahl.

    Wie den Logarithmus berechnen? Eine große Tabelle erstellen und dann grob schätzen? Wie ist der zB Logarithmus in der C++-Standard-Library implementiert?

    MfG SideWinder



  • SideWinder schrieb:

    Wie den Logarithmus berechnen?

    Vielleicht mit Hilfe einer Reihenentwicklung?! 🙂



  • Öhm, ich lass mich hier mal als Mathematik-DAU abstempeln und hoffe auf eine etwas präzisere Erklärung *g*

    Google werd ich dazu auch mal bemühen.

    Verzeihung aber von Reihenentwicklung hat man hier in der *in deutsche einheit umrechne* 10. Klasse keine Ahnung, geometrische Reihe hat wohl auch nur rein zufällig einen ähnlichen Namen 😃

    Bitte etwas genauer für Dumme 🙄

    MfG SideWinder



  • du könntest ja ne intervallschachtelung versuchen *lol*
    ansonsten müßtest du schon eine reihe nehmen.



  • Hmm, also die e-Funktion hat laut allwissendem Google folgende Reihe:

    e = 1 + 1/1! + 1/2! + 1/3! + 1/4! ...
    

    Daraus den log zu bekommen sollte dann hoffentlich nicht mehr so schwer sein.

    Aber wie genau soll ich da werden um ca. 20 Dezimalzahlen genau zu sein?

    MfG SideWinder



  • das ist so nicht fair.
    gebt sidewinder doch wenigstens gescheite schlüssel für google.

    @sidewinder:
    du bist erst in der 10. klasse? uff! also programmiertechnisch hätte ich dich eigentlich ins späte studium eingestuft.

    evtl fehlen dir dann zu viele begriffe, um "reihen" sauber einzuführen. kennste schon differenzieren? dann hift dir "taylor-reihe" weiter. kannste es noch nicht, aber es fix lernen? dann auch.



  • Danke fürs Lob 😉 Und trotzdem trau ich mich schon an GUI-Programmierung 😮:p:)

    Ich werd mir das Differenzieren Beibringen versuchen 🙂

    MfG SideWinder



  • Hallo

    EDIT: Sehe grad dein letztes Post. Ich dachte 10 Klasse Österreich == 13. Klasse Deutschland. Und trotzdem nocht keine Analysis gehabt ? Naja vielleicht ist folgendes trotzdem nützlich.

    SideWinder schrieb:

    Verzeihung aber von Reihenentwicklung hat man hier in der *in deutsche einheit umrechne* 10. Klasse keine Ahnung, geometrische Reihe hat wohl auch nur rein zufällig einen ähnlichen Namen 😃

    Geometrische Reihe reicht schonmal aus und mit Integration und Differentiation dürftest du wohl auch schon vertraut sein. Das reicht vielleicht aus um das folgende nachvollziehen zu können. (Und meiner Meinung nach ist es besser eine Herleitung mal gesehen zu haben als stur Formeln anzuwenden)

    Es soll eine Reihe für ln(1+x) hergeleitet werden wobei ln der natürliche Logarithmus ist und die Reihe für alle x mit -1<x<1 konvergiert. Das reicht aus um die Logarithmen in bel. Basen und bel. Werte zu berechnen.

    Nun gut. Für die Ableitung von ln(1+x) ergibt sich:
    ln(1+x)=11+x=11(x)=k=0(x)k=k=0(1)kxkln'(1+x) = \frac{1}{1+x} = \frac{1}{1-(-x)} = \sum_{k=0}^{\infty} (-x)^k = \sum_{k=0}^{\infty} (-1)^k x^k
    Im vorletzten Schritt wurde einfach verwendet, dass für die unendliche geometrische Reihe gilt
    k=0ak=11a\sum_{k=0}^{\infty} a^k = \frac{1}{1-a}
    und zwar für alle a mit -1<a<1.

    Diese Reihe ist eine sog. Potenzreihe die gliedweise differenziert und integriert werden dürfen. D.h. wir können die "Summanden" der Reihe einzeln integrieren und erhalten:
    ln(1+x)=k=0(1)kxk+1k+1ln(1+x) = \sum_{k=0}^{\infty} (-1)^k \frac{x^{k+1}}{k+1}
    für |x|<1

    Jetzt kannst du den ln einer Zahl näherungsweise berechnen.
    Andere Basen erreichst du natürlich mit:
    logb(x)=ln(x)ln(b)log_b(x) = \frac{ln(x)}{ln(b)}

    Für größere Zahlen ist folgende Umrechnung nützlich:
    Sei
    ϕ:=log2(x)\phi := \lfloor log_2(x) \rfloor
    Dann ist
    ln(x)=ϕln(2)+ln(x2ϕ)ln(x) = \phi \cdot ln(2) + ln(\frac{x}{2^{\phi}})$
    für alle x>0.

    Beweis: Einsetzen und ausrechnen 😉

    Warum ist das hilfreich ?
    Ganz einfach:
    ϕ:=log2(x)\phi := \lfloor log_2(x) \rfloor
    ist eine natürliche Zahl und kann durch wiederholtes Teilen durch 2 errechnet werden,
    ln(2)ln(2)
    ist eine Konstante und für
    ln(x2ϕ)ln(\frac{x}{2^{\phi}})
    kannst du obige Reihe verwenden.

    Soviel dazu.

    Es ist einfach zu implementieren. Ob es dir genau genug ist musst du selbst wissen. Dass es effizientere Verfahren gibt ist ziemlich sicher....kennen tue ich aber keins davon 🙂

    Gruß, space



  • Nein ich meine damit die 10. Klasse bei euch == 6. Klasse in österreichischen Schulen == 2. Klasse HTL.

    Steht doch sogar drin, dass ich bereits umgerechnet habe 🙄

    Werde mir deinen Weg morgen ansehen, jetzt ist es mir zu spät um mich mit solch hoher Mathematik auseinanderzusetzen 🤡

    MfG SideWinder



  • SideWinder schrieb:

    Steht doch sogar drin, dass ich bereits umgerechnet habe 🙄

    Ich seh's.
    Sorry, liegt am Bier 😃



  • hier noch ein link zum thema
    http://www.mathematik.ch/anwendungenmath/logarithmen/

    bin grad in ähnlichem am lernen..





  • Falls Du nur eine Ganzzahl-Abschätzung für den Zweierlogarithmus brauchst, genügt folgende Funktion:

    int ldapprox(BIGINT zahl)
    {
    	int log2 = 0;
    	BIGINT potenz = 1;
    	while(zahl <= potenz)
    	{
    		potenz << 1; /* oder potenz *= 2 (langsamer?) */
    		++log2;
    	}
    	return log2 - 1;
    }
    


  • potenz *= 2 ist langsamer als potenz << 1, allerdings ist es irrelevant, was man schreibt, da das sowieso umoptimiert wird.



  • Also den Compiler würde ich schlagen, der mir "*= 2" in "<< 1" umoptimiert :p .



  • Kleiner Flüchtigkeitsfehler:

    potenz <<= 1;
    

    Hoffentlich ist der Operator <<= auch für BIGINT implementiert!


Anmelden zum Antworten