Forum: Compiler & IDEs GCC 4.1.1 vergleich zweier longs klappt nicht


von marc (Gast)


Lesenswert?

Hallo,
hab folgendes Problem vergleiche zwei unsigned long Werte :

unsigned long dimmpunkt,dimmdauer;

dimmpunkt = (uint32_t)(rtc_getTimeInSecond() - starttimesec);
dimmdauer = (uint32_t)(dimmStore.dimmMinuten*60);

rprintf("Dimm Now: %d \r\n",dimmpunkt);
rprintf("Dimmdauer: %d \r\n",dimmdauer);

if(dimmpunkt <= dimmdauer)
  Es wird nie hierhin gesprungen egal ob dimmpunkt <= dimmdauer!!!


Wenn ich es mit unsigned int mache klappt es einwandfrei... brauche nur 
für den Wertebereich unsigned long...

Kann es mir nicht erklären?!?!
Hat jemand einen Typ?

- GCC 4.1.1
- ATMega128

LG
marc

von A.K. (Gast)


Lesenswert?

rprintf("Dimm Now: %lu \r\n",dimmpunkt);
rprintf("Dimmdauer: %lu \r\n",dimmdauer);

von marc (Gast)


Lesenswert?

Das nicht klappen war eher auf das

if(dimmpunkt <= dimmdauer)

bezogen. Es wird nie "in" das if verzweigt. Die Ausgabe gibt korrekte 
Werte wieder trotzdem wird nicht ins If verzweigt wenn dimmpunkt <= 
dimmdauer???

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Woran stellst du das fest?

von marc (Gast)


Lesenswert?

Da keine weiteren Debug Meldungen mehr ausgegeben werden, die Ausgabe 
##Aufdimmen####### müsste ausgegeben werden wenn dimmpunkt <= dimmdauer, 
das passiert aber nicht. Ich kann es mir auch nicht erklären! Sobald ich 
dimmpunkt & dimmdauer zum Test mal als unsigned int def. klappt es 
einwandfrei, natürlich nur solange es nicht zum Überlauf kommt.

if(dimmpunkt <= dimmdauer)
{   // ist Aufdimmzyklus

  dimmwert = dimmerGetLevel(dimmer,dimmpunkt,1);
#ifdef DEBUG
  rprintf("##Aufdimmen#######\r\n");
#endif
}

von A.K. (Gast)


Lesenswert?

> Die Ausgabe gibt korrekte Werte wieder

Woher weisst du das, wo du nur 16 von 32 Bits anzeigst?

von Walter (Gast)


Lesenswert?

wird zwar nicht der Fehler sein, aber warum definierst du die Variablen 
anders als du sie castest?

Wie sind denn die anderen Variablen bzw. Funktionen definiert?

der cast nach der Berechnung ist auch etwas sinnfrei ...

ich vermute mal das du in der Berechnung einen Überlauf hast.

von marc (Gast)


Lesenswert?

Das casten it überbleibsel von diversen Test...Nach einigen rumprobieren 
komm ich der Sache auf die Schliche... was passiert wenn man eine float 
Value zB.

0.166 * (uint_32)10 malnimmt. Bei mir kommt nur Blödsinn raus... Kann 
man keine uint_32 mit einer Float multiplizieren? Gibts da irgendwo 
einen Überlauf. Hab mich tot gesucht und nix gefunden, wahrscheinlich 
bin ich zu blöd ... Vermute mal das das auch bei vergleich von 2 uint_32 
passiert. Wie gesagt verwendet man uint_16 klappt multiplikation mit 
Float und Vergleich per IF...

marc

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

marc wrote:

> 0.166 * (uint_32)10 malnimmt. Bei mir kommt nur Blödsinn
> raus... Kann man keine uint_32 mit einer Float multiplizieren?

Doch, man kann, ist aber bissel sinnfrei.  Die 10 wird ja (egal ob
int, uint16_t oder uint32_t) als Allererstes in eine 10.0 umgewandelt.

> ... Vermute mal das das auch bei vergleich von 2 uint_32 passiert.

Du sprichst immer noch Vermutungen aus, ohne irgendwas zu belegen.

Das, was du beschreibst, sollte alles funktionieren.  Du wirst also
wohl irgendwas anderes vergurkt haben, aber wirfst uns hier nur die
fürs Problem nicht relevanten Codeschnipsel hin.

von A.K. (Gast)


Lesenswert?

Sorry, aber deine Info ist zu knapp. Ohne den Datentyp jeder Variablen 
und Funktion zu kennen, bleibt alles im Dunkel.

Wenn beispielweise in (dimmStore.dimmMinuten*60) der Typ von dimmMinuten 
16bittig ist, ist es das Ergebnis auch, egal in was du das dann castest.

Und wenn (rtc_getTimeInSecond() - starttimesec) negativ werden kann, 
dann wird es auch interessant.

Dass if(dimmpunkt <= dimmdauer) nicht korrekt funktioniert, glaube ich 
erst, wenn die beide Werte gesehen habe. Was mit %d printf nicht der 
Fall ist, denn %d passt nun einmal nicht zu den Datentypen.

Und (0.166 * (uint_32)10) dürfte mit oder ohne cast funktionieren, nur 
ist das Ergebnis vom Type "double" und nicht uint_32. Der Rest hängt 
davon ab, was du damit machst.

von marc (Gast)


Lesenswert?

Problem gefunden!!! War ein Pointer Fehler an einer ganz anderen Stelle, 
dadurch wurde die uint32_t Var zerschossen. Asche über mein Haupt das 
ich zweifeln konnte :)

marc

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.