Rechnenfrage

Hallo zusammen,
bevor ich loslege, die Bitte, mich ncht zu erschlagen !!!! Es ist mir schon peinlich genug die Frage überhaupt stellen zu müssen.

Ich habe folgendes Problem:
unsigned long timerA; // Globale Variable (wird für millis benutzt)

timerA = (((5 * 10) + (6)) * 1); // Ergebnis: 56 (OK)
timerA = (((5 * 10) + (6)) * 10); // Ergebnis: 560 (OK)
timerA = (((5 * 10) + (6)) * 100); // Ergebnis: 5600 (OK)
timerA = (((5 * 10) + (6)) * 1000); // Ergebnis: 4294957760 (NICHT OK)

Laut meinem Rechnenverständnis sollte beim letzten Beispiel das Ergebnis doch 56000 sein oder ? ? ? ?

An dem Variablentypen kann es auch nicht liegen, da er Werte bis 4.294.967.295 annehmen kann.
Wo mache ich da den Denkfehler?

LG Jörg

An dem Variablentypen kann es auch nicht liegen, da er Werte bis 4.294.967.295 annehmen kann.
Wo mache ich da den Denkfehler?

Genau hier!
Der Type der Variablen ist ok.
Aber nicht der Type der Integer Literale.

Merksatz:

Der Weg in die Hölle ist mit falschen Annahmen gepflastert.
Hier, die unterschwellige Annahme, der Type der Zielvariablen hätte einen Einfluss auf den Rechenvorgang.
Hat er nicht.

Bei einem ESP oder ARM würde es trotz falscher Annahme funktionieren.
Bei einem AVR führt die Annahme ins Versagen.

Beweis:

timerA = (((5UL * 10UL) + (6UL)) * 1000UL);

Hallo,

wenn nicht anderes dabei steht werden zwischen Rechnungen als int durchgeführt.

Du solltest dich nch mal mit der Klammerregel vertraut mchen, auch hier gilt, Punkt vor Strich, was sollen die ganzen Klamern

Heinz

unsigned long timerA;
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

  timerA = 5 * 10UL + 6 * 1000UL;  // meint (5*10)+(6*1000)

  Serial.println(timerA);

  timerA = (5 * 10UL + 6) * 1000UL; // meint  56*1000

  Serial.println(timerA);
}

void loop() {
  // put your main code here, to run repeatedly:

}

(deleted)

Hallo,

mach mal folgendes

In der IDE alle Compilerwarnungen einschalten.
Datei > Voreinstellungen >

  • Ausführliche Ausgabe während > beide Haken rein
  • Compilerwarnungen > "ALLE"

Zeilennummern und Codefaltung sind auch hilfreich.

Dann komplieren und die Warnungen lesen.

Danach machste aus unsigned long mal nur long schaust dir die Ergebnisse an.
Danach machste aus long mal int schaust dir die Ergebnisse an und staunst. :wink:

Der Grund ist das der AVR intern in int rechnet wenn keine der beteiligten Variablen einen größeren Datentyp hat.
Deswegen muss man das machen wie combie korrigiert hat.

oder anderweitig den größeren Datentyp aufzwingen

void setup(void) {
  Serial.begin(250000);
  Serial.println("\nStart");

  unsigned long timerA;  
  const unsigned long zehn = 10;
  
  timerA = (((5 * zehn) + 6) * 1);            // Ergebnis: 56   (OK)
  Serial.println(timerA);
  timerA = (((5 * zehn) + 6) * 10);          // Ergebnis: 560   (OK)
  Serial.println(timerA);
  timerA = (((5 * zehn) + 6) * 100);        // Ergebnis: 5600   (OK)
  Serial.println(timerA);
  timerA = (((5 * zehn) + 6) * 1000);      // Ergebnis: 
  Serial.println(timerA);
}

void loop(void) {

}

Peter-CAD-HST:
C:\Users\ich\Documents\Arduino\sketch_feb12a\sketch_feb12a.ino:11:28: warning: integer overflow in expression [-Woverflow]

timerA = (((5 * 10) + (6)) * 1000);

meiner sagt mir noch mehr :wink:

Ausgabe
sketch_feb12a.ino:16:30: warning: integer overflow in expression of type 'int' results in '-9536' [-Woverflow]
16 | timerA = (((5 * 10) + (6)) * 1000); // Ergebnis: 4294957760 (NICHT OK)
| ~~~~~~~~~~^~

(deleted)

Offtopic. Soviel zum Thema neue Compiler/Toolchains wären sinnfrei. Der Querschläger musste jetzt einfach raus. :smiling_imp: