Forum: Compiler & IDEs pow() mit ATmega32 ; Problem bei berrechnung


von Andreas (Gast)


Lesenswert?

double SDD = 0.0;
double SDDpow = 0.0;
double SDDx = 10.0;
double SDDy = 0.5;


double SDD_fkt (void)
{
  SDDpow = pow(SDDx, SDDy);
  return  SDD = 6.1078 * SDDpow;
}


//***************************

Kann mir jemand erklären warum ich bei den Werten SDDx = 10 und SDDy = 
0.5 den Wert für "2" SDDpow bekomme? was läuft da schief? eigentlich 
müßte doch 3.16227.. herauskommen.

Wenn ich die Werte SDDx = 10 und SDDy = 2 einsetze, bekomme ich für 
SDDpow "64".  was läuft da schief? eigentlich müßte doch 100 
herauskommen.

Was läuft bei mir schief? oder kann man keine Flieskomma zahlen mit 
pow(); berechnen???

Meine Berechnung die ich machen wollte liegt so im bereich von
 SDDpow = 10^(0,0310)  bis  SDDpow = 10^(0,787).  Oder kann man das noch 
anderst ausrechnen?


Gruß Andreas

von eProfi (Gast)


Lesenswert?

welche Umgebung, welcher Prozessor?
hast Du
#include <math.h>
gemacht?

evtl. Umweg über Multiplikation der Logarithmen

von Michael G. (linuxgeek) Benutzerseite


Lesenswert?

Poste mal den kompletten Code... koennte ein Fliesskommaproblem sein. 
Was genau willst Du denn alles berechnen? Kannst Du die Parameter 
eingrenzen? Dann gibt es vielleicht alternative Moeglichkeiten, z.B. 
eine Reihenentwicklung.

Michael

von 2923 (Gast)


Lesenswert?

So'n Problem kann man doch im Simulator Singlesteppen....

von Andreas (Gast)


Lesenswert?

ich will einen ATmega32 mit dem AVRStudio und dem GCC-Complier 
programmieren. Als Emulator habe ich den AVR-Dragon.

Gruß Andreas

von Andreas (Gast)


Lesenswert?

Ich hab jetzt alles als Funktion geschrieben,  die Berrechnung 
funktioniert auch in einem kleinen Testprofjekt, nur wenn ich die 
Funktion dann in das eigentliche Projekt einfüge, eght die berrechnung 
irgendwie schief. Mal schauen, vielleicht finde ich das Problem noch in 
dem Projekt.

Gruß Andreas

von Michael G. (linuxgeek) Benutzerseite


Lesenswert?

Naja gut wenn Du keinen Code posten willst kann ich Dir nicht helfen. 
Dann noch viel Erfolg.

Michael

von Andreas (Gast)


Lesenswert?

OK, hab den fehler gefunden. In der ISR der Analogmessung ging wohl 
irgendetwas schif.

Aber trotzdem Danke für eure Schnellen Antworten.

Gruß Andreas

von Michael G. (linuxgeek) Benutzerseite


Lesenswert?

Dann verstehe ich aber den Zusammenhang ueberhaupt nicht... aber wie 
auch, ohne Code. Das naechste mal, wenn Du postest, sei mal bitte 
ausfuehrlich genug, dass man helfen kann.

von Andreas (Gast)


Lesenswert?

Hallo zusammen, das Problem ist noch nicht ganz weg.

Wenn ich im Programm diese Zeile aktiviere geht die Berrechnung wieder 
schief:
gemesseneSpannungFeucht = FeuchtigkeitADwert;

Die Daten Typen sind (float = int):
float gemesseneSpannungFeucht = 0;
int   FeuchtigkeitADwert      = 0;

Muß ich da ein Type-Cast machen oder?
gemesseneSpannungFeucht = (float)FeuchtigkeitADwert;

aber mit dieser Zeile funtioniert es auch nicht. Was mach ich da falsch?

Gruß Andreas

von Hauke R. (lafkaschar) Benutzerseite


Lesenswert?

CODE ... ohne geht nix -.-

von Andreas (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

hier hab den Code auf das wesentliche Problem reduziert, ich hoffe es 
kann mir jemand helfen.

Gruß Andreas

von Andreas (Gast)


Lesenswert?

kann das Problem jemand nachvollziehen?

von Karl H. (kbuchegg)


Lesenswert?

Habs mal duchgesteppt.

SDD = pow(SDDx, SDDy);

SDDX ist 10
SDDY ist 0.583045646

Das Ergebnis von pow ergibt sich zu 1.0005536

Laut Taschenrechner sollte es aber 3.828549 rauskommen.

Hmmm....

von Andreas (Gast)


Lesenswert?

Komentier mal diese Zeile aus:

// return gemesseneSpannung = (double) TemperaturADwertxx / 5;

dann müßte das Richtige Ergebniss raus kommen.


Hab ich da ei Problem mit den Daten-Typen?

Gruß

von Karl H. (kbuchegg)


Lesenswert?

Andreas wrote:
> Komentier mal diese Zeile aus:
>
> // return gemesseneSpannung = (double) TemperaturADwertxx / 5;
>
> dann müßte das Richtige Ergebniss raus kommen.
>
>
> Hab ich da ei Problem mit den Daten-Typen?

Nein.
Das interessante ist, dass diese Funktion noch nicht mal
aufgerufen werden muss. Die blose Anwesenheit dieser
Funktion genügt.
Sieht tatsächlich nach einem Compilerfehler aus.

von Andreas (Gast)


Lesenswert?

Hallo, hat jemand eine Idee wie man das Problem lösen kann?

Gruß Andreas

von Karl H. (kbuchegg)


Lesenswert?

Ich hab das jetzt nicht weiter untersucht, was die genaue
Ursache dafür ist.

Aber hast du schon versucht, dir selbst eine pow() Funktion
zu schreiben?

  pow(x,y) = exp( log(x) * log(y) )

von Uwe N. (ulegan)


Lesenswert?

Du musst die libm dazulinken!
Unter Program - Configuration Options - Libraries die libm.a auswählen, 
dann klappts auch mit der power...

von Falk B. (falk)


Lesenswert?

@ Uwe Nagel (ulegan)

>Du musst die libm dazulinken!
>Unter Program - Configuration Options - Libraries die libm.a auswählen,
>dann klappts auch mit der power...

OK, aber was landet denn OHNE das Linken der libm in den Funktionen? 
Eigentlich dürfte der Linker doch gar nicht durchlaufen, weil die 
Funktionen fehlen? Oder stecken in den "Standardroutinen" mieserable, 
buggy Gerüste drin, damit es wenigstens fehlerfrei gelinkt wird? Das 
wäre ziemlich link :-(

MFG
Falk

von Uwe N. (ulegan)


Lesenswert?

Dsa sollte uns mal einer der C-Gurus erklären...
Lass mal ein Listfile erzeugen. Dann siehst du, dass sehr wohl auch ohne 
libm die Fliesskomma-Funktionen eingebunden werden. Allerdings eine 
andere, sogar größere, Version. Die pow() Funktion ist allerdings auf 
den ersten Blick identisch und macht fast dass, was Karl heinz Buchegger 
vorschlägt:
pow(x,y) = exp( log(x) * y )

Mit der auskommentierten Zeile geht es dann schief, wenn die übergebene 
Variable verwendet wird. Ein einfaches
return (double) gemesseneSpannung;
erzeugt den Fehler nicht!
Es wird aber bis dahin identischer Code erzeugt????

Gruß
Uwe

von Karl H. (kbuchegg)


Lesenswert?

Uwe Nagel wrote:
> Du musst die libm dazulinken!
> Unter Program - Configuration Options - Libraries die libm.a auswählen,
> dann klappts auch mit der power...

Nein. Hab ich definitiv probiert bzw. ich hatte die libm definitiv
drinnen.
Der Fehler ist eigenartig. Die Funktion mit der vorgeschlagenen
Auskommentierung muss noch nicht mal aufgerufen werden um den
Fehler zu erhalten.
Normalerweise würde ich mal auf Stackoverflow oder sowas tippen.
Aber der Mega32 ist ja mit dem Testprogramm praktisch leer.

von Uwe N. (ulegan)


Lesenswert?

Ich kann den Effekt nur ohne libm nachvollziehen. Mit libm geht es mit 
und ohne Auskommentierung. Mit Auskommentierung wird der Typecast 
(double) in der Funktion TemperaturBerechnung nicht verwendet. Das ist 
die einzige Verwendungsstelle des Typecasts im ganzen Programm. Im 
erzeugtem Code  steht dann komischerweise die Funktion <__floatsisf> 
(das ist der Typecast) an anderer Stelle in den Fliesskomma-Funktionen 
und sieht auch anders aus. Seltsam...
Mit libm gehts (jedenfalls in meinem Simulator) immer, die 
Fliesskomma-Bibliothek sieht ganz anders und vorallem viel kürzer aus.
Es hat schon seinen Grund, dass in den Standard Makefiles von Win-AVR 
die libm immer eingebunden wird.
Ich verwende WinAVR-20070525 und AVR-Studio 4.13Build 557.

von Andreas (Gast)


Lesenswert?

Danke für die Hilfe.

Für was stehen die Libaries "libc.a" und "libm.a"?
Ist "libm.a" für Mathematik Funktionen?
Muß ich die "libc.a" auch einbinden?

Gruß Andreas

von Andreas (Gast)


Lesenswert?

???

von Frank (Gast)


Lesenswert?

hat jemand eine Antwort auf die Frage?

von Karl H. (kbuchegg)


Lesenswert?

AFAIK ist die libc.a die Standard-C Library, die sowieso
immer mit eingebunden wird.
Die libm.a enthält die Mathematischen Funktionen. Grob gesagt:
alles was in math.h drinnen ist. Darüber hinaus ist es immer
gut, die libm.a anzugeben, wenn floating pointer verwendet wird.

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.