Forum: Mikrocontroller und Digitale Elektronik pow() Funktion ??


von Michael Walk (Gast)


Lesenswert?

Hallo

Ich möchte 10^x in C (für einen AVR-uC) realisieren. Wenn ich
"pow(10,2);" eingebe, kommt 100 heraus, was auch richtig ist.
Wenn ich jedoch folgendes schreibe:
int a = 2;
int erg = pow(10,a);
kommt 424 als Ergebnis heraus.

Hat jemand eine Erklärung dafür?

Über Antwort würde ich mich freuen. Bedanke mich schonmal.

Gruß Micha

von crazy horse (Gast)


Lesenswert?

int erg = pow(10,a);
geht das überhaupt so?
Habe sowas noch nie gemacht, versuch mal:

int erg;
erg= pow(10,a);

von Bert (Gast)


Lesenswert?

Deine Datentypen stimmen nicht.

Laut ANSI ist pow() wie folgt fefiniert:

double pow(double x, double y)

für dein Beispiel:
double a = 2;
double result;

result = pow(10,a);

B.

von Michael Glunz (Gast)


Lesenswert?

@bert

> double a = 2;

Wird a nicht automatisch in den Typ double gewandelt?

Gruß
Michi

von Bri (Gast)


Lesenswert?

Ja, wird automatisch gewandelt. Zeig mal den ganzen Code, speziell wie
du dir das Ergebnis anzeigen lässt. Machst du das mit printf()? Kommt
beim Compilieren irgend eine Warnung?

von Kalle Pohl (Gast)


Lesenswert?

versuch doch mal mit typecast:

double erg = pow(double(10), double(a));

oder

double erg = pow((double)10, (double)a);

vorteil ist klar: deine vars bleiben mit 4bytes deklariert, aber der
compiler interpretiert sie richtig (als double halt).


so long
kalle

von Kalle Pohl (Gast)


Lesenswert?

hab vergessen zu erwähnen, dass konstanten nicht gecastet werden müssen.
aber falsch ist es auch nicht. vars mit typen ungleich double müssen
definitiv gecastet werden.

so long
kalle

von Bri (Gast)


Lesenswert?

@Kalle
Was schreibst du denn hier für einen Quatsch? Schonmal was von
impliziter Typkonvertierung gehört? Wahrscheinlich nicht, oder? Lies
dir doch bitte erstmal den Standard durch, bevor du hier was falsches
erzählst.

von Qwerty (Gast)


Lesenswert?

Wollte ich auch gerade schreiben. "...the arguments are converted, as
if by assignment, to the types of the corresponding parameters of the
function's prototype." (K&R 2. Edition). Der Compiler wird eventuell
eine Warnung auswerfen (loss of precision o.ä.), aber funktionieren
sollte es schon.

von Kalle Pohl (Gast)


Lesenswert?

@Bri
nicht dass ich wüsste, aber kannst mir ja erzählen was daran ach so
falsch ist. freue mich schon auf die haarspalterei.


so long
kalle

von Karl H. (kbuchegg)


Lesenswert?

Nicht böse sein.
Aber eigentlich ist deine ganze Analyse der Situation
ziemlicher Unsinn.

Wenn der Rest vom Programm passt, dann muss der Code-
Ausschnitt ohne Probleme und vor allen Dingen ohne
explizites casten funktionieren. Anderfalls hat der
Compiler einen schweren Fehler.

> vars mit typen ungleich double müssen
> definitiv gecastet werden.

Das ist ja wohl der größte Unsinn von allen Bonmonts
in diesem Thread.

von Kalle Pohl (Gast)


Lesenswert?

moin,

böse bin ich net, lass mich gerne überzeugen (!). aber keinesfalls
dümmlich anquatschen. bei dem angeführten zitat habe ich mich wirklich
extrem unglücklich ausgedrückt - war nicht so gemeint wie man es
versteht. ich meinte eigentlich, dass es sinnvoll sein könnte für den
fall, dass der compiler es nicht automatisch macht. ich würde es immer
so machen, auch wenn ich weiss, dass der compiler automatisch
konvertiert. funktionieren tuts im avr studio trotzdem nicht. schade.
woran liegts?


so long
kalle

von Karl H. (kbuchegg)


Lesenswert?

Wenn math.h. includiert ist und der Compiler einen
entsprechenden Prototypen zu Gesicht bekommen hat,
dann muss er die Datentypen entsprechend anpassen.
Er hat keine andere Wahl, das sind die C-Regeln.
Tut er das nicht, dann hat der Compiler einen Fehler.


#include <math.h>

int main()
{
  int Result;
  int a = 2;

  Result = pow( 10, 2 );
}

funktioniert einwandfrei. Das heist, nachdem ich in den
Linkeroptionen die libm.a angegeben habe :-)
AVR Studio macht das nicht standardmaessig, was eigentlich
eine Schande ist und ein ständiges Ärgernis bereitet wenn
man irgendwas aus math.h benutzt.

von Karl H. (kbuchegg)


Lesenswert?

Besser wäre natürlich eine zusätzliche
Rundungskorrektur

  Result = pow( 10, 2 ) + 0.5;

da es ziemlich unwahrscheinlich ist, dass bei der
ganzen Rechnerei exakt 100.0 rauskommt.
Aber das ist eine andere Geschichte.

von Profi (Gast)


Lesenswert?

Wenn es nur ganzzahlige Argumente (und b>=0) gibt, empfiehlt sich
sowieso, das ganze ohne die pow-Funktion  in integer zu berechnen:

r=1;
for(i=0;i<b;i++){r*=a;}

von Michael Glunz (Gast)


Lesenswert?

@Karl Heinz Buchegger

Hallo, ein paar Fragen dazu

- Was mach denn die "libm.a"
- Worin besteht der Unterschid, enn man sie nicht benutzt
- Was steht im Ergebnis nach

#include <math.h>

int main()
{
  int Result;
  int a = 2;

  Result = pow( 10, 2 );
}

Wird nur dur die Zahl, ohne Nachkommastellen angezeigt?

Gruß
Michi

von Ronny (Gast)


Lesenswert?

Zu libm.a:

Einige Compiler (z.B CodeComposer) beschweren sich nicht,wenn eine
Funktion nicht definiert ist und nehmen dann stillschweigend an sie sei
extern.frei nach dem Motto irgend ein anderes C-File (oder Objektfile)
wird sie schon definiert haben.

Wenn der Linker dann alles zusammenfügt,gibt es bei einigen einen
Fehler a la "Undefined function referenced",bei manchen aber auch
nicht.Und bei denen wirds dann unangenehm weil beim Aufruf garnix
passiert (falls der Linker den Call auf ein RET umleited),Rückgabewert
ist dann der Wert der zufällig gerade im Register steht,welches zur
Rückgabe verwendet wird.

von Karl heinz B. (kbucheg)


Lesenswert?

> Was mach denn die "libm.a"

das 'm' steht für math
D.h da sind alle Funktionen drinnen, die in math.h
deklariert wurden. Ob zusätzlich noch double Funktionen
(für Multiplikation, Division, etc) drinnen sind, weiss
ich nicht. Aus irgendeinem Grund haben die Macher vom GCC
damals entschieden, die Mathe-Funktionen in eine eigene
Library auszulagern und nicht in die Standard-C Library zu
legen. Wahrscheinlich waren die Linker damals noch nicht soweit
und man hatte Angst jedesmal die komplette Floating Point
Library einzubinden, auch wenn nichts davon benutzt wird.

> Worin besteht der Unterschid, enn man sie nicht benutzt

Dann kriegst du die Funktion nicht. Da muss jetzt Jörg etwas
aushelfen, da mir selbst auch nicht ganz klar ist, warum da
nicht eigentlich kein Linker-Fehler entsteht. Aber ich denke
mal ein Übervorsichtiger hat eine Dummy-Implementierung dieser
Funktionen in die C-Standardlibrary eingefügt, die nicht
operabel ist, aber den Linker zufriedenstellt. Wenn das
wirklich so war (Jörg hilf mir mal), dann halte ich das für
keine so gute Idee. Eine Funktion die fehlt sollte vom Linker
auch angemäkelt werden und nicht durch einen nicht funktionierenden
Dummy befriedigt werden. (Meine Meinung)

> Wird nur dur die Zahl, ohne Nachkommastellen angezeigt

Na ja.
Result ist vom Typ int.
Und ein int ist nun mal eine ganze Zahl ohne Nachkommastellen.
Wenn du also Result orgendwohin ausgibst, dann kriegst du das
was in Result steht. Und das ist: eine ganze Zahl.

von Kalle Pohl (Gast)


Lesenswert?

achso, das ist ja alles andere als elegant. danke für den interessanten
tip! als neuling in AVR hätte ich mir in zukunft an diesem problem den
kopf zerbrochen  ?:-/ .

so long
kalle

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.