Multiplikation fuer Anfaenger

Hallo,
Kann mir mal jemand verraten warum:

long SPD; // Seconds Per Day
SPD = 60 * 60 * 24;
Serial.print(SPD);

20864 ergibt, statt der erwarteten 86400?

Aber:
long SPD =1; // Seconds Per Day
SPD = SPD * 60 * 60 * 24;
Serial.print(SPD);

ergibt 86400.

Was mache ich falsch?
Danke
Jürgen

Das kann ich dir sagen!

Du glaubst mit long zu rechnen nutzt aber int.
Vermutlich hast du hast das Kapitel über Literale und Datentypen, in deinem C++ Buch, nicht aufmerksam genug gelesen.

Richtige Lösung:

const unsigned long SPD = 60UL * 60 * 24;  // Seconds Per Day
// alternativen:
SPD = 60.0 * 60.0 * 24.0;
SPD = float(60) * 60 * 24;
SPD = 60.0f * 60 * 24;
SPD = 60.0d * 60 * 24;

(deleted)

Warum float? das war doch garnicht gefragt.

Hallo Jürgen,
Standardmäßig werden alle Berechnungen erstmal als int ausgeführt, solange nicht explizit was anderes angegeben ist. Deshalb wird auch

60*60*24

als int berechnet. Und da auf den ARV'rs int nur 16 Bit lang ist, ergibt das einen Überlauf. In deinem 2. Beispiel ist der erste Operand als long definiert. Deshalb wird die Berchnung als long ausgeführt, und es gibt keinen Überlauf. Du könntest auch

60L*60*24

schreiben. Dann weis der Compiler auch, dass es eine long Berechnung werden soll.

Edit: Peter war schneller :wink:

Danke an Alle!
Wieder was dazu gelernt.

Gruss
Jürgen.

unsigned long SPD = 86400; // geht übrigens, auch ohne das [b]L[/b]

Aber dass du das passende Kapitel in einem dicken Buch nicht rechtzeitig gelesen hast, musst du dir nicht als Vorwurf anziehen. In diese Falle sind alle schonmal getappt, die mit diesen kleinen 8bit Controllern und ihrem kleinen 16bit int als Standard-Zahlenbereich angefangen haben.

Man kann es übrigens auch als Geburtsfehler von C ansehen oder zumindest drüber nachdenken, wo doch jeder weiß, dass int16_t*int16_t ein Ergebnis im Wertebereich int32_t liefert.

(deleted)

Warum float? das war doch garnicht gefragt.

Erstens:
Es liefert ebenso korrekte Ergebnisse.

Zweitens:
Es ist damit eine Alternative.

Drittens:
Es zeigt dem TO, oder auch anderen, dass die Welt an dem Ende größer ist, als sie evtl. vermuten.


Bei mir sieht sowas mittlerweile eher so aus:

Millis zeitMerker = 1_dy;

//oder auch:

Millis zeitMerker = 14.5_hr + 22_ms;

Aber das war ja auch nicht gefragt.


musst du dir nicht als Vorwurf anziehen.

Vorwurf?

Es ist die Aufforderung dieses Kapitel aufmerksam zu lesen.
Inc. der Stichworte um es zu finden.

Vorwürfe werden gerne ausgeblendet.
Vorwürfe erzeugen innere Widerstände.
Wer diese Aufforderung als Vorwurf versteht, hat diese inneren Widerstände schon und unterwirft sich diesen.

michael_x:
Man kann es übrigens auch als Geburtsfehler von C ansehen oder zumindest drüber nachdenken, wo doch jeder weiß, dass int16_t*int16_t ein Ergebnis im Wertebereich int32_t liefert.

Wenn man die Warnungen einschaltet, bekommt man zumindest einen Hinweis auf das Problem. Die ‘Standard’ Warnungen reichen da schon.

combie:
Erstens:
Es liefert ebenso korrekte Ergebnisse.

Zweitens:
Es ist damit eine Alternative.

Ich bin allerdings der Meinung, dass man auf den kleinen Arduinos nicht ohne Not float einsetzen sollte. Auch wenn im konkreten Fall der Compiler erkennt, dass die float-Berechnung nur zur Compilezeit benötigt wird, würde ich grundsätzlich hier keine float-Konstanten oder Variable nutzen, wenn dies nicht zwingend notwendig ist.

Auch wenn im konkreten Fall der Compiler erkennt, dass die float-Berechnung nur zur Compilezeit benötigt wird,

Gerade in einem solchen Fall, wo die Berechnung zur Kompilezeit erfolgt, spielt die Einschränkung "kleine Arduinos" nun wirklich keine Rolle.

Bei Berechnungen zur Laufzeit, gebe ich dir vollständig recht.

Aber ansonsten darf das jeder so bewerten, wie er/sie/es es mag.
Wer sich selbst (unnötige) Beschränkungen auferlegen möchte, darf das natürlich gerne tun.

Auch habe ich den Float Alternativen die "richtige Lösung" vorangestellt und als solche gegenzeichnet.
Jeder mag sich aus dem Angebot das herausnehmen was ihm schmeckt und den Rest gerne im Regal liegen lassen.

combie:
Gerade in einem solchen Fall, wo die Berechnung zur Kompilezeit erfolgt, spielt die Einschränkung "kleine Arduinos" nun wirklich keine Rolle.

Dieser Unterschied dürfte nicht jedem Anfänger bewusst sein ( auch wenn er es möglichst schnell lernen sollte ).

combie:
Auch habe ich den Float Alternativen die "richtige Lösung" vorangestellt und als solche gegenzeichnet.

Wie ich meinen Post geschrieben hatte, stand es noch nicht da :wink: . Alles gut - 'richtig' liegt ja oftmals im Auge des Betrachters 8)

Wie ich meinen Post geschrieben hatte, stand es noch nicht da

Das kann durchaus sein..
Da ist anfangs beim Posten des getesteten Codes was schief gegangen.

Alles gut - 'richtig' liegt ja oftmals im Auge des Betrachters 8)

Yes!

combie:
------------Vorwurf?

Es ist die Aufforderung dieses Kapitel aufmerksam zu lesen.
Inc. der Stichworte um es zu finden.

Vorwürfe werden gerne ausgeblendet.
Vorwürfe erzeugen innere Widerstände.

Ich sehe keinen Imperativ. Nur eine Aussage, was der TO gemacht oder nicht gemacht haben soll. Also ein Vorwurf, abgeschwächt durch ein "vielleicht".

Die zweite Aussage stimmt allerdings!