Frage:
Einen vorzeichenlosen Long Int versichern?
bluesmoke
2014-11-14 04:23:41 UTC
view on stackexchange narkive permalink

Grundlegende Frage: Wie weit muss ich gehen, um sicherzustellen, dass die Ganzzahlmathematik korrekt ausgeführt wird? Zum Beispiel ist dies wahrscheinlich übertrieben:

  unsigned long burnTime = 0UL; unsigned long curBurnTime = 0UL; // Machen Sie einige Dinge, die die obigen Variablen zu verschiedenen Zeiten auf millis () setzen // Später on ... unsigned long adjustedBurnTime = (unsigned long) ((burnTime + curBurnTime) / 1000UL);  

Würde die Mathematik korrekt durchgeführt, wenn ich zu einer minimaleren letzten Anweisung gehen würde (seit Alle Elemente der Gleichung sind vorzeichenlose Longs. So:

  unsigned long adjustedBurnTime = ((burnTime + curBurnTime) / 1000UL);  

Oder sogar:

  unsigned long adjustedBurnTime = ((burnTime + curBurnTime) / 1000);  
Nur ein Weg, um es wirklich herauszufinden! Kompilieren Sie beide und zerlegen Sie sie.
@IgnacioVazquez-Abrams entweder das oder den GCC-Compiler-Code durchlesen. :) Das Drucken der Ausgabe auf seriell ist natürlich am einfachsten!
Wenn das Argument der mathematischen Operation nicht vorzeichenlos ist, sollte es mit langer Genauigkeit berechnet und bei Zuweisung möglicherweise verkürzt werden. Der zweite Fall sollte in Ordnung sein. Das doppelte Einchecken in der Baugruppe ist jedoch die beste Wahl, um Zeit zu sparen, wenn seltsame Ergebnisse erzielt werden.
Dieses Problem ist zeitlich sehr relevant. Schauen Sie sich http://playground.arduino.cc/Code/TimingRollover an, um das gleiche Problem zu beschreiben. Wo ich TMA zustimmen würde, wird es nicht benötigt, da alle gleich gegossen sind. Ich gehe jedoch immer auf Nummer sicher. Falls das Casting geändert wurde.
Danke für die Gedanken. Ich bin nicht geschickt genug, um den Assembler-Code zu überprüfen, also werde ich die serielle Ausgaberoute ausprobieren. @mpflaga, Ich stimme besser sicher als leid zu. Ich hatte nur gehofft, in meinem Code (sicher) etwas weniger redundant zu sein, aber warum sollte ich das Risiko eingehen? Da ich Laufzeiten verfolge, wird es ein Problem sein.
Ich habe alle drei obigen Beispiele zusammengestellt und das Ergebnis waren drei identische Hex-Dateien. Sofern mir nichts fehlt, habe ich anscheinend meine Frage beantwortet. ... Vermisse ich etwas?
Nein, bist du nicht; Die Hex-Datei repräsentiert genau Ihren Code (plus einige Anweisungen zum Laden). Wenn zwei Hex-Dateien identisch sind und demselben Loader angezeigt werden, müssen die Ergebnisse (die Speicherladevorgänge) identisch sein.
Einer antworten:
JRobert
2014-11-15 03:58:46 UTC
view on stackexchange narkive permalink

In jedem guten C-Handbuch wird der Ergebnistyp für jede grundlegende mathematische Operation für bestimmte Typen angegeben. Kurz gesagt, die grundlegenden mathematischen Operatoren geben ein Ergebnis zurück, das so breit ist wie der breiteste Operand, wobei der engere Operand erweitert wird, um dem breiteren zu entsprechen, wenn sie sich unterscheiden. Das Gleiche gilt für die Zuweisung: Das Zuweisen eines Ergebnisses eines bestimmten Typs zu einer Variablen desselben Typs erfordert keine Konvertierung.

tl; dr: Nein, Sie vermissen nichts. In Ihrem Beispiel benötigen Sie keine Casts.

PS: Eine Sache, die Sie beachten müssen, ist, ob eines Ihrer Zwischenergebnisse den von Ihnen verwendeten arithmetischen Typ überläuft. Beispielsweise darf das Endergebnis eine lange Zeit ohne Vorzeichen nicht überschreiten, aber die Ausdrücke (burnTime + curBurnTime) dürfen diese auch nicht überschreiten. Dies ist natürlich ein größeres Problem bei kleineren Datentypen.

PPS: Gut, dass Sie sich mit Festkomma-Arithmetik befassen, anstatt nur nach der Gleitkomma-Bibliothek zu greifen!

Danke, das ist eine großartige Antwort, denn sie erklärt nicht nur, ob, sondern warum. Meine uninformierte Vermutung wäre das Gegenteil gewesen. Auch sehr dankbar für die Warnung vor Zwischenergebnissen; Es wäre nur eine Frage der Zeit gewesen, bis mich das gebissen hätte.


Diese Fragen und Antworten wurden automatisch aus der englischen Sprache übersetzt.Der ursprüngliche Inhalt ist auf stackexchange verfügbar. Wir danken ihm für die cc by-sa 3.0-Lizenz, unter der er vertrieben wird.
Loading...