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
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.
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?
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
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
@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.
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.
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.
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
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.
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.
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;}
@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
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.
> 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.
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