Code in C++ (AVR-GCC compiled): int fadeDelay = abs(analogRead(fadeSpeedPotPin)); int wait = abs(fadeDelay / 25); int hold = abs(fadeDelay * 300); Serial.println("fadeDelay"); Serial.println(fadeDelay); Serial.println("wait"); Serial.println(wait); Serial.println("hold"); Serial.println(hold); Ausgabe: fadeDelay 1023 wait 40.00 hold -20780.00 WTF?! ;)
Falk Brunner schrieb: > Integer Overflow? Deswegen hatte ich testweise nen double draus gemacht. Mit gleichem Ergebnis. Aber 306900 passt definitiv in ein double?!
Again: int fadeDelay = abs(analogRead(fadeSpeedPotPin)); double wait2 = abs(fadeDelay / 25); double hold2 = abs(fadeDelay * 300); Serial.println("fadeDelay"); Serial.println(fadeDelay); Serial.println("wait"); Serial.println(wait2); Serial.println("hold"); Serial.println(hold2); Ausgabe: fadeDelay 1023 wait 40.00 hold -20780.00 ---- Aktueller Code ist definitiv auch auf dem uC übertragen.
> int fadeDelay = abs(analogRead(fadeSpeedPotPin)); ^^^^^^^^^^^^^ > int wait = abs(fadeDelay / 25); > int hold = abs(fadeDelay * 300); ^^^^^^^^^ ^^^ Wie schon geschrubt wurde läuft hier die Integermultiplikation über.
overflow bei 16bit signed integer (1023*300 mod 2^(16)) - 2^(16) = -20780
dev schrieb: > int fadeDelay = abs(analogRead(fadeSpeedPotPin)); Wenn du fadeDelay als int deklarierst, darfst du dich nicht wundern, dass
1 | fadeDelay * 300 |
einen integerüberlauf produziert
Genauer gesagt: In der double-Variante ist es auch ein Integer-Overflow, da durch die C-Rechenregeln erst das (overgeflowte) Endergebnis in double gewandelt wird. Lösung: int32_t für alle(!) beteiligten Variablen verwenden, oder wenn double gewünscht wird, durch 25.0 teilen und mal 300.0, dann wird nämlich schon das Zwischenergebnis in Flieskomma berechnet.
g457 schrieb: > Wie schon geschrubt wurde läuft hier die Integermultiplikation über. Danke, jetzt hab ichs verstanden. Mir war nicht klar, dass der Zwischenwert also das Rechenergebnis genauso typsiert ist, wie die Operationsvariable und nicht wie die Ergebnisvariable. Ist aber klar, da die Zuweisungsoperation ja erst nachgelagert geschieht. Also frei gesprochen: 1. Multiplikaton: int fadeDelay * 300 ergibt Overflow-Wert von int 2. Zuweisung: double hold2 = Overflow-Wert So klappt es dann: double fadeDelay = abs(analogRead(fadeSpeedPotPin)); wait = fadeDelay / 25; hold = fadeDelay * 300; Serial.println("fadeDelay"); Serial.println(fadeDelay); Serial.println("wait"); Serial.println(wait); Serial.println("hold"); Serial.println(hold); Randnotiz: Komme aus der dynamisch typisierten Welt :-)
Appendix: wait und hold sind bei mir im äußeren Scope bereits als double deklariert.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.