Forum: Compiler & IDEs Potenzfunktion mit beliebigem Exponenten in C


von A. R. (redegle)


Lesenswert?

Hallo,

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

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

von Niklas G. (erlkoenig) Benutzerseite


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)):
1
#define PRECISION (10e-17)
2
3
double power_n (double x, unsigned int n) {
4
  double mul = 1;
5
  while (n > 1) {
6
    if (n % 2 == 1) {
7
      n = (n - 1) / 2;
8
      mul *= x;
9
      x *= x;
10
    } else {
11
      n /= 2;
12
      x *= x;
13
    }
14
  }
15
  return x * mul;
16
}
17
18
double logarithm (double x) {
19
  unsigned int k;
20
  const double m = (x - 1) / (x + 1);
21
  double a = m, sum = 0;
22
  for (k = 0; a > PRECISION || a < -PRECISION; k++) {
23
    sum += a * (((double) 1) / ((double) (2 * k + 1)));
24
    
25
    a *= m * m;
26
  }
27
  return 2*sum;
28
}
29
30
double expo (double x) {
31
  unsigned int k = 0;
32
  double sum = 0, add = 1;
33
  for (;add > PRECISION || add < -PRECISION; k++) {
34
    sum += add;
35
    
36
    add = add * x / (k + 1);
37
  }
38
  return sum;
39
}
40
41
double power (double x, double y) {
42
  return expo (y * logarithm (x));
43
}

von Klaus W. (mfgkw)


Lesenswert?

1
POW(3)                         Linux Programmer’s Manual                         POW(3)
2
3
NAME
4
       pow, powf, powl - power functions
5
6
SYNOPSIS
7
       #include <math.h>
8
9
       double pow(double x, double y);
10
       float powf(float x, float y);
11
       long double powl(long double x, long double y);
12
13
       Link with -lm.
14
15
DESCRIPTION
16
       The pow() function returns the value of x raised to the power of y.
17
18
ERRORS
19
       EDOM   The  argument  x  is negative and y is not an integral value.  This would
20
              result in a complex number.
21
22
CONFORMING TO
23
       SVr4, 4.3BSD, C89.  The float and long double variants are C99 requirements.
24
25
SEE ALSO
26
       cbrt(3), cpow(3), sqrt(3)
27
28
COLOPHON
29
       This page is part of release 3.05 of the Linux man-pages project.  A description
30
       of  the  project,  and  information  about  reporting  bugs,  can  be  found  at
31
       http://www.kernel.org/doc/man-pages/.

von A. R. (redegle)


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.

von Karl H. (kbuchegg)


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
1
DESCRIPTION
2
       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.

von A. R. (redegle)


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!

von Huch (Gast)


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.

von mh (Gast)


Lesenswert?

Du brauchst also "die" komplexe Wurzel? Dann sag das doch gleich...

von A. R. (redegle)


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!
1
int _tmain(int argc, _TCHAR* argv[])
2
{
3
  double x = 5;
4
  double y = 7.2;
5
  double Ergebniss = pow(x,y);
6
  printf("%f",Ergebniss);
7
  system("pause");
8
  return 0;
9
}
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.

von Niklas G. (erlkoenig) Benutzerseite


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...

von Johann L. (gjlayde) Benutzerseite


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.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

sachich ja, hab nie behauptet dass das genau ist :)

von Johann L. (gjlayde) Benutzerseite


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#Berechnung_des_Logarithmus

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.