mikrocontroller.net

Forum: Compiler & IDEs Potenzfunktion mit beliebigem Exponenten in C


Autor: A. R. (redegle)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

kennt jemand eine Headerdatei mit einer Potenzfunktion, welche mit 
beliebigen Zahlen umgehen kann.

Z.B.: 3,23^5,76

Autor: Niklas Gürtler (erlkoenig)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du wirst nicht nur die Headerdatei brauchen ;)
Aus Spass hier mal ein Code den ich noch bei mir rumfliegen hatte der 
direkt nach der Definition der Exponentialfunktion vorgeht, garantiert 
unoptimiert und unexakt (aufzurufen mit power (x, y)):
#define PRECISION (10e-17)

double power_n (double x, unsigned int n) {
  double mul = 1;
  while (n > 1) {
    if (n % 2 == 1) {
      n = (n - 1) / 2;
      mul *= x;
      x *= x;
    } else {
      n /= 2;
      x *= x;
    }
  }
  return x * mul;
}

double logarithm (double x) {
  unsigned int k;
  const double m = (x - 1) / (x + 1);
  double a = m, sum = 0;
  for (k = 0; a > PRECISION || a < -PRECISION; k++) {
    sum += a * (((double) 1) / ((double) (2 * k + 1)));
    
    a *= m * m;
  }
  return 2*sum;
}

double expo (double x) {
  unsigned int k = 0;
  double sum = 0, add = 1;
  for (;add > PRECISION || add < -PRECISION; k++) {
    sum += add;
    
    add = add * x / (k + 1);
  }
  return sum;
}

double power (double x, double y) {
  return expo (y * logarithm (x));
}

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
POW(3)                         Linux Programmer’s Manual                         POW(3)

NAME
       pow, powf, powl - power functions

SYNOPSIS
       #include <math.h>

       double pow(double x, double y);
       float powf(float x, float y);
       long double powl(long double x, long double y);

       Link with -lm.

DESCRIPTION
       The pow() function returns the value of x raised to the power of y.

ERRORS
       EDOM   The  argument  x  is negative and y is not an integral value.  This would
              result in a complex number.

CONFORMING TO
       SVr4, 4.3BSD, C89.  The float and long double variants are C99 requirements.

SEE ALSO
       cbrt(3), cpow(3), sqrt(3)

COLOPHON
       This page is part of release 3.05 of the Linux man-pages project.  A description
       of  the  project,  and  information  about  reporting  bugs,  can  be  found  at
       http://www.kernel.org/doc/man-pages/.

Autor: A. R. (redegle)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Niklas Gürtler

Vielen Dank für den Code.
Steckt viel Arbeit da hinter, vermute deshalb auch, dass es soetwas noch 
nicht vorgefertigt in einer Headerdatei gab.
Muss mir das mal in Ruhe anschauen.
Aber der Ansatz scheint folgender zu sein:

2^7 = 10^(2*log(7))

@Klaus Wachtler

Was möchtest du mir damit sagen?
Den Header math.h kannte ich bereits.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
A. R. schrieb:
> @ Niklas Gürtler
>
> Vielen Dank für den Code.
> Steckt viel Arbeit da hinter, vermute deshalb auch, dass es soetwas noch
> nicht vorgefertigt in einer Headerdatei gab.

Du beliebst zu scherzen

> Was möchtest du mir damit sagen?
> Den Header math.h kannte ich bereits.

Und?
Warum hast du dann nicht hineingeschaut?
Was sagt dir die Funktion pow  wie 'power'?

Zitat vom Klaus-Zitat
DESCRIPTION
       The pow() function returns the value of x raised to the power of y.
mit anderen Worten:

   x^y  <==> pow( x, y )

(wobei ^ der Potenzoperator ist und nicht das C-spezifische XOR)

AUsserdem: was verwendest du denn für ein Schmalspur-C-Buch, wenn da 
drinnen die Funktion pow() bei der Besprechung der Funktionen aus math.h 
nicht vorkommt?
Schmeiss es weg und kauf dir ein Vernünftiges.

Autor: A. R. (redegle)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Karl heinz Buchegger

>Du beliebst zu scherzen

Könntest du das bitte etwas genauer erläutern? Das war ernst gemeint. 
Ironie oder einen Scherz hätte ich markiert.

>AUsserdem: was verwendest du denn für ein Schmalspur-C-Buch, wenn da
>drinnen die Funktion pow() bei der Besprechung der Funktionen aus math.h
>nicht vorkommt?
>Schmeiss es weg und kauf dir ein Vernünftiges.

Diesen Kommentar würde ich gerne an den Absender zurückgeben!

>double pow(double x, double y)  xy.
>Ein Argumentfehler liegt vor bei x=0 >und y<0, oder bei x<0 und y ist nicht 
>ganzzahlig.

Mit anderen Worten:
Der Exponent muss eine Ganzzahl sein.

Der Titel des Threads hätte schon darauf hindeuten müssen, dass mir die 
Funktion "double pow(double x, double y)" nicht weiterhilft!

Autor: Huch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>>Diesen Kommentar würde ich gerne an den Absender zurückgeben!

>double pow(double x, double y)  xy.
>Ein Argumentfehler liegt vor bei x=0 >und y<0, oder bei x<0 und y ist nicht
>ganzzahlig.


Kommentare an K. H. Buchegger zurückzugeben beinhaltet das Risiko sich 
ein wenig zu blamieren und über die Bedeutung des Wortes "und" belehrt 
zu werden. Nochmal lesen, tief durchatmen und nochmal lesen. Dann erst 
denken.

Autor: mh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du brauchst also "die" komplexe Wurzel? Dann sag das doch gleich...

Autor: A. R. (redegle)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Kommentare an K. H. Buchegger zurückzugeben beinhaltet das Risiko sich
>ein wenig zu blamieren

Das Risiko muss man manchmal eingehen.

>Nochmal lesen, tief durchatmen und nochmal lesen.

Das hilft manchmal!
Hatte im Kopf, dass man mit pow nur Ganzzahlen als Exponent verwenden 
darf.
Dann hat sich das Problem erledigt. Danke für den Hinweis.
Hiermit möchte ich mit bei Karl heinz Buchegger entschulden und mich für 
die Hilfe bedanken!
int _tmain(int argc, _TCHAR* argv[])
{
  double x = 5;
  double y = 7.2;
  double Ergebniss = pow(x,y);
  printf("%f",Ergebniss);
  system("pause");
  return 0;
}
Das Programm klappt wunderbar.

>Du brauchst also "die" komplexe Wurzel? Dann sag das doch gleich...
Nein
Mit (-5)^(7,2) wäre ich etwas überfordert.

Autor: Niklas Gürtler (erlkoenig)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> A. R. schrieb:
>> @ Niklas Gürtler
>>
>> Vielen Dank für den Code.
>> Steckt viel Arbeit da hinter, vermute deshalb auch, dass es soetwas noch
>> nicht vorgefertigt in einer Headerdatei gab.
>
> Du beliebst zu scherzen
Das setzt einfach nur die mathematische Definition von dem, was eine 
Potenz ist, um. und ist deswegen total simpel und wahrscheinlich 
fürchterlich ungenau und langsam. Wenn man die Formeln vorgegeben hat 
(was ich hatte, als ich das geschrieben hab) geht das ganz fix zu 
programmiern...
Die Idee dahinter:
Definition der Exponentialfunktion:
Definition der Logarithmusfunktion als Umkehrfunktion der 
Exponentialfunktion:
Definition der Potenz über die Exponentialfunktion:
Die Reihendarstellung die ich da für den Logarithmus verwendet habe weiß 
ich grad leider nicht auswendig...

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Niklas Gürtler schrieb:

> Die Idee dahinter:
> Definition der Exponentialfunktion:
>

Vorsicht, diese Definition der Exponentialfunktion ist zwar ganz nett, 
aber für den praktischen Einsatz nicht ohne weiteres empfehlenswert. 
Versuch zum Beispiel mal, damit
auszurechnen. Die dabei auftretenden Summanden sind betragsmässig irre 
groß, aber ihre Summe ist ≈0. Die bei den Additionen auftretenden 
Rundungsfehler der alternierewnden Summanden machen das Ergebnis zu 
einem Märchenwert.

> Die Reihendarstellung die ich da für den Logarithmus verwendet habe weiß
> ich grad leider nicht auswendig...

Es ist i.w. die Reihenentwicklung des Areacotangenshyperbolicus :-)

Ohne Skalierung liegen die Werte m in der Reihenentwicklung u.U. am 
Rande des Konvergenzkreises → Die Konvergenz ist Theorie, in der Praxis 
gibt's Märchenwerte, weil die Rundungsfehler bei weitem dominieren.

Autor: Niklas Gürtler (erlkoenig)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sachich ja, hab nie behauptet dass das genau ist :)

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Niklas Gürtler schrieb:
> sachich ja, hab nie behauptet dass das genau ist :)

Naja, wenn man was ausrechnet (bzw. ausrechnen lässt) will man ja auch 
das gewünschte Ergebnis bekommen und nicht irgendwas mehr oder weniger 
zufälliges.

Ein "klassisches" Beispiel ist die Leibnitz-Reihe
Die Rundungsfehler und die langsame Konvergenz machen die Reihe für 
einen praktischen Einsatz unbrauchbar — auch wenn die Formel selbst ganz 
einfach und hübsch ist.

Was die Exponentialfunktion angeht, so hilft

Und für den Logarithmus ist Artanh ok (nicht wie ich oben schrieb 
Arcoth), sofern man die Eingangswerte so normiert, daß sie nicht an den 
Rand des Konvergenzkreises zu liegen kommen:

http://de.wikipedia.org/wiki/Logarithmus#Berechnun...

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.