1023 * 300 = -20780.00!

Gast #3221817
Lesenswert?
• ▲
▼
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?!

;)
Gast #3221823
Lesenswert?
• ▲
▼
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.
Gast #3221825
Lesenswert?
• ▲
▼
> 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.
Gast #3221837
Lesenswert?
• ▲
▼
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.
Gast #3221839
Lesenswert?
• ▲
▼
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 :-)

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.