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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren