Potenzfunktion mit reellem Exponent



  • Ich bin gerade dabei, meine eigene mathematische Bibliothek aufzustocken (ich will also kein math.h einbinden) und stehe ziemlich ratlos vor dem Problem, wie ich denn eine Potenz mit nicht ganzzahligem Exponenten berechnen kann.

    double _potenz_double(double base , double exponent)
    {	double Puffer;
    	if( exponent == 0 )
    		return(1);
    	if( base == 0 )
    		return(0);
    	if( exponent < 0)
    	{	exponent *= -1;
    		Puffer = 1 / _potenz_lu(base , (unsigned long)exponent );
    		exponent -= (unsigned long)exponent;
    		exponent *= -1;
    	}
    	if( exponent > 0)
    	{	Puffer = _potenz_lu(base , (unsigned long)exponent );
    		exponent -= (unsigned long)exponent;
    	}
       //hier habe ich also noch übrig: Puffer * base^x, wobei x aus (0;1) stammt
    	return(Puffer);
    }
    

    So sieht meine bisherige Funktion aus, die _potenz_lu berechnet natürlich Potenzen mit ganzzahligem positivem Exponenten.
    Meine Potenz wird im Laufe dieser Funktion verringert, bis sie sich im Bereich 0 bis 1 befindet (das hoffe ich zumindest), allerdings weiß ich nicht, wie ich dann weiterkomme. Kennt jemand den entsprechenden Algorithmus (vielleicht gibt es ja auch wesentlich effizientere Methoden als meine)?

    Falls jemand das testen möchte, hänge ich meine _potenz_lu auch noch an:

    double _potenz_lu(double base , unsigned long exponent)
    {	double c = base;
    	if( exponent == 0 )
    		return(1);
    	if( base == 0 )
    		return(0);
    	if( exponent%2 == 0)
    		return(c = _potenz_lu(base * base , exponent / 2));
    	else
    		return(c = base * _potenz_lu(base * base , (exponent - 1) / 2));
    	return(c);
    }
    

    Anlass dazu war es übrigens, eine Exponentialfunktion zu erstellen, allerdings habe ich bei Verwendung der Reihendarstellung dieser Funktion sehr große Ungenauigkeiten gehabt, weil einfach die Wertebereiche von long und double zu klein waren.



  • ^^für exp() und log() gibts algorithmen, die mit ein paar konstanten auskommen und die für double ausreichend genau sind (einfach mal googlen: exp filetype:c). dann machste einfach: #define pow(a,b) exp(log(a)(b))* a muss positiv sein, sonst verweigert log() die arbeit.
    🙂



  • Du schlägst also vor, dass ich nicht die Exponentialfunktion als Potenzfunktion, sondern die Potenzfunktion als Exponentialfunktion behandle?

    Dann werfe ich mal Google an...



  • Stiefel2000 schrieb:

    Du schlägst also vor, dass ich nicht die Exponentialfunktion als Potenzfunktion, sondern die Potenzfunktion als Exponentialfunktion behandle?

    würde ich mal sagen, dann haste auch gleich sqrt() u.ä. wenn du noch 'nen code für sin() findest (gibt's auch welche, die nur mit ein paar konstanten rumrechnen), hast du auch gleich cos() und tan(). und dann haste schon die wichtigsten funktionen zusammen, die die normale C mathelibrary auch hat.
    🙂



  • Ich schaue mir gerade http://www.opensource.apple.com/source/ksh/ksh-13/ksh/src/lib/libast/uwin/exp.c an, kann dem Code allerdings nicht ganz folgen. Mal abgesehen davon, dass das nicht sehr minimalistisch aussieht, scheint die Funktion nebenbei den ln zu benötigen, den ich allerdings noch nicht habe.



  • diese werden gebraucht:

    * Required system supported functions:
     *	scalb(x,n)	
     *	copysign(x,y)	
     *	finite(x)
    

    aber wenn du den code doof findest, einfach weitersuchen.
    🙂



  • Ich habe gesehen, dass es da Voraussetzungen gibt, schon allein das stört mich. Es werden scheinbar selbst erstellte Pakete eingebunden, es gibt sehr viele Makros,...

    Am liebsten wäre mir ja eine ausführliche Beschreibung, wie man die Exponentialfunktion gut annähern kann - dann könnte ich den ollen Code vergessen und selbst was schreiben. (Übrigens habe ich bisher noch keinen weiteren Code gefunden, der exp definiert.)

    Wie komme ich eigentlich vom exp zum Sinux? Mit komplexen Zahlen kann mein Programm nämlich nicht rechnen...



  • Stiefel2000 schrieb:

    Ich habe gesehen, dass es da Voraussetzungen gibt, schon allein das stört mich. Es werden scheinbar selbst erstellte Pakete eingebunden, es gibt sehr viele Makros,...

    ach, das ist doch nur kleinkram, den du dir leicht zusammensuchen kannst.

    Stiefel2000 schrieb:

    Am liebsten wäre mir ja eine ausführliche Beschreibung, wie man die Exponentialfunktion gut annähern kann - dann könnte ich den ollen Code vergessen und selbst was schreiben.

    such mal nach dem buch 'hacker's delight', da ist sowas drin. ansonsten google: 'fast exp approximation' und ähnliche suchbegriffe kombinieren. und vergiss gleich sowas wie reihenentwicklung. das ist übelst langsam und ungenau.

    Stiefel2000 schrieb:

    (Übrigens habe ich bisher noch keinen weiteren Code gefunden, der exp definiert.)

    du hast nur nicht richtig gesucht. solchen kram findet man ohne ende im internet.

    Stiefel2000 schrieb:

    Wie komme ich eigentlich vom exp zum Sinux? Mit komplexen Zahlen kann mein Programm nämlich nicht rechnen...

    ich glaub das geht nur in der komplexen ebene (such mal nach einheitskreis, eulersche identität und sowas). aber ich kann mich täuschen, frag doch mal im matheforum.
    🙂



  • Matheforum ist nichts für mich - ich kann zwar nicht von mir behaupten, dass ich Mathematik studiert hätte, aber es fehlt nich viel dazu ;). Ich weiß also sehr gut, wovon du sprichst und habe auch schon überlegt, wie ich die komplexen Zahlen in die e-Funktion bringe, allerdings ist mir nichts eingefallen. Aber das muss ja auch erst später folgen.

    Wenn ich nach "exp filetype:c" oder "exponential implement" oder Ähnlichem suche, finde ich sehr wenige sinnvolle Dinge. Ich probier gleich mal deine Vorschläge aus.





  • Spar dir dein 🙄, "fast" habe ich nirgendwo verwendet.

    Der wiki-Link zeigt mir auch nur die Reihendarstellung (ist ja bereits ausgeschieden) und die Möglichkeit, die auch die bisher von mir gefundenen Quelltexte liefern. Allerdings führt das wieder dazu, dass ich eine Potenzfunktion mit reellem Exponenten versehen müsste, was mir bisher nicht gelungen ist.



  • rüdiger schrieb:

    http://de.wikipedia.org/wiki/Exponentialfunktion#Numerische_Berechnungsm.C3.B6glichkeiten

    dafür braucht er pow() und log(), die er noch nicht hat.
    aber es gibt ja auch noch die 'taschenrechner-methode': http://en.wikipedia.org/wiki/Cordic
    🙂



  • Na das sieht ziemlich lustig aus :). Wenn das wirklich das ist, was mein Taschenrechner macht, dann kann die Methode eigentlich nur gut sein. Mal schauen, was sich daraus machen lässt...



  • Dieser Beitrag wurde gelöscht!

Anmelden zum Antworten