Forum: Compiler & IDEs Werte Konvertierung schlägt fehlt!?


von Andreas B. (dashin)


Lesenswert?

Hallo Leute,
ich arbeite noch nicht lange mit C und dem GCC. Momentan verwende ich 
das AVR-Studio und WIN AVR. Mein Problem sieht sehr simpel aus und die 
Lösung ist es vermutlich auch, aber ich komme nicht drauf ;)

Schonmal Vielen Dank im Voraus.

Problem ist folgendes:


foo(uint32_t i) verwendet das Argument i als Zähler um i-mal eine andere 
Funktion auszuführen.

rufe ich die Funktion mit fixen Werten im Quelltext auf wie z.B.

foo(32000) wird die Funktion auch 32000mal ausgeführt (while(i--))

Sobald ich allerdings eine Variable oder zu berechnende Werte wie
(2*16000)  oder  uint32_t help = x*y  als Argument gebe, schlägt es 
fehl.

casts haben mich auch nicht weitergebracht:  foo((uint32_t)(x*y));
Egal was ich mache, wenn der Wert nicht fertig im Quelltext steht wird 
die while-Schleife nicht korrekt durchlaufen. Ich nehme an dies liegt an 
der Arbeitsweise vom Compiler? Könnte es was bringen Binärdarstellungen 
in eine 32bit Integer zu shiften?


foo(uint32_t i)
{
  while(i--)
   doIt();

}


Grüße

dashin

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Kommt vermutlich aus dem Kontext. Poste mal den kompletten Code.

von Andreas B. (dashin)


Lesenswert?

void repeat(uint16_t val, uint32_t i)
{

  while (i--)

  send(val);

}


void doIt(uint16_t a0, uint16_t b0, uint16_t a1, uint16_t b1, uint16_t 
val)
{

    uint32_t temp = (uint32_t)  ((a1-a0+1)*(b1-b0+1));
    repeat(val,temp);

}


Rechne ich  ((a1-a0+1)*(b1-b0+1)) von Hand aus und schreibe das Ergebnis 
klar      uint32_t temp = 10000;

funktioniert alles.

Ergänzung:  Bei kleinen Werten für temp funktioniert auch mit Variablen 
alles. Bsp. temp = x*y  und x = 10 und y = 123

von Karl H. (kbuchegg)


Lesenswert?

Irgendwelche Warnungen vom Compiler?

von Klaus W. (mfgkw)


Lesenswert?

Karl Heinz Buchegger schrieb im Beitrag #2685151:
> 32565

32767

von willy (Gast)


Lesenswert?

Andreas B. schrieb:
> uint32_t temp = (uint32_t)  ((a1-a0+1)*(b1-b0+1));

Du darfst nicht erst das Ergebnis zu 32Bit casten sondern einen der 
Operanden.

Sonst findet die Rechnung mit 16 Bit statt. Du erhälst einen Überlauf 
und erst dieser (übergelaufene) Wert wird nach 32 Bit gecastet.

von Andreas B. (dashin)


Lesenswert?

Ja! Ich danke Euch von ganzem Herzen! Toll wie schnell man hier 
Unterstützung findet. Ich hoff ich kann das später auch mal zurückgeben 
:)

uint32_t temp =  (((uint32_t) (a1-a0+1))*(b1-b0+1));

funktioniert einwandfrei.

von Karl H. (kbuchegg)


Lesenswert?

Andreas B. schrieb:
> Ja! Ich danke Euch von ganzem Herzen! Toll wie schnell man hier
> Unterstützung findet. Ich hoff ich kann das später auch mal zurückgeben
> :)
>
> uint32_t temp =  (((uint32_t) (a1-a0+1))*(b1-b0+1));
>
> funktioniert einwandfrei.

Dann kann da aber was nicht stimmen.
Wenn dir beim händischen Rechnen 10000 (Zehntausend) rauskommt, bist du 
selbst mit 16 Bit Rechnerei auf der sicheren Seite.

von Andreas B. (dashin)


Lesenswert?

> Dann kann da aber was nicht stimmen.
> Wenn dir beim händischen Rechnen 10000 (Zehntausend) rauskommt, bist du
> selbst mit 16 Bit Rechnerei auf der sicheren Seite.

ah, ich merks grad :/ hab das Beispiel von Zehntausend total falsch 
gewählt. Der Fehler tritt wie zu erwarten, erst bei Werten über 2^16 
auf.

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.