Guten Morgen,
Ich habe in meinem aktuellen Projekt alle (betroffenen) Variablen als
uint8_t deklariert. In diesen Variablen halte ich Tage, Stunden, Minuten
und Sekunden einer Uhr. Diese Werte bewegen sich zwischen 0 und maximal
59.
Bei Einstellen der Uhr tritt u.U. der Fall auf, dass z.B. die Minuten
per Default auf "00" stehen, die Aktuelle Zeit aber "50" Minuten ist.
Beim Stellen müsste nun 50x auf den "Minuten+"-Taster gedrückt werden um
die korrekte Zeit zu stellen. Einfacher wäre es doch den
"Minuten-"-Taster 10x zu drücken.
Beim ersten Schleifendurchlauf (Minuten auf "00") würde der Druck auf
"Minuten-" eine negative Zahl produzieren. Da meine Variablen aber als
"uint8_t" und damit "unsigned" deklariert sind, ändert sich der Wert auf
255, was in diesem Fall korret ist.
Im Moment habe ich als "Hack" eine Abfrage erstellt, die prüft ob der
Wert der Minuten-uint8_t-Variable >200 ist. In diesem Fall setze ich die
Variable auf 59.
Ist das Euerer Meinung nach, im Sinne eines guten, lesbaren
Programmierstils Ok oder würdet Ihr wegen dieser "Kleinigkeit" das
gesamte Programm überarbeiten und von uint8_t weggehen auf int8_t. Was
diverse andere Probleme (casts etc.) mit sich bringen würde ???
Gebt mir bitte mal Euere Meinung ...
Gruß
Andreas
Da die Arithmetik von vorzeichenlosen Typen in C erstens erstens ohne
Overflow-Trap und zweitens als Modulo-Arithmetik definiert ist, gibt es
damit m.E. keine Probleme. Bei Typen mit Vorzeichen ist so etwas
hingegen undefiniert.
Eleganter wär's allerdings, du würdest auf 0 testen, bevor du
runterzählst.
Guter Programmierstil ist es, alle Benutzereingaben auf gültige Werte zu
überprüfen, und auf sinnvollen Werte zu begrenzen.
Also gehören da Abfragen rein, die den Übergang von 59 auf 0, und
ungekehrt behandeln.
Oliver
Die Abfrage ob = 0 kann man sich doch sparen, wenn man die Variable nach
dem Inkrementieren/Dekrementieren mit "% 60" behandelt.
Dadurch wird der Zahlenbereich auf Zahlen zwischen 0 und 59 begrenzt.
Da eine unsigned Variable benutzt wird, kommmt es zu einem Überlauf beim
Übergang von 0 auf -1 (bzw. 255). Wenn man dann 255 % 60 rechnet sollte
59 herauskommen (kann aber auch sein, dass da was anderes bei
rauskommt...).
Ob eine Abfrage nicht schneller wäre, sei dahingestellt...
Hi
keine gute Idee da 255 % 60 = 15
Wenn der Tastendruck "Minuten-" kommt einfach die Variable auf 0 prüfen
und falls der Vergleich wahr ist Minuten auf 59 setzen sonst eben
Minuten--. Für "Minuten+" dann analog und fertig.
Matthias
Hi,
ich versuche immer so einfach wie möglich das Thema abzuhandeln. Der
entscheidende Tipp kam von Oliver - vielen Dank dafür!
Ich habe es wie folgt gelöst:
@Simon:
Eine Divisionsroutine verwenden, nur um den Bereich einer
Minuten/Sekunden-Variable einzugrenzen? Finde ich etwas Overkill, zumal
% 60 ja nicht mit Bitmaskiererei/-schieberei realisiert werden kann...
Philipp Burch wrote:
> @Simon:>> Eine Divisionsroutine verwenden, nur um den Bereich einer> Minuten/Sekunden-Variable einzugrenzen? Finde ich etwas Overkill, zumal> % 60 ja nicht mit Bitmaskiererei/-schieberei realisiert werden kann...
Hey! Ich kam nicht auf die Idee ;) ;)
was bei unsigned Byte 255 wäre. Entweder auf < 0 oder > 59 nach dem
Dekremetieren überprüfen und falls es zutrifft +60 draufrechnen. So
kannst du auch mit zb. 10 dekrementieren.
Gruß Hagen
Hagen Re wrote:
> was bei unsigned Byte 255 wäre.
Bei den meisten Implementierungen. ;-)
Im Ernst: die Portabilität ist nicht garantiert.
> ... auf < 0 ... nach dem> Dekremetieren überprüfen
"Warning: comparision is always false due to limited data range."
Tu's nicht. Auf > 59 prüfen geht sicher, aber ist ein Hack. Wenn
man negative Zahlen erhalten kann, sollte man die Zahlen bitteschön
auch als vorzeichenbehaftet betrachten, warum ist das denn so
schlimm?
Wie man einen Unsigned Datentyp auf kleiner 0 testen
kann ist mir unbekannt.
Teste daher immer vorher:
Beim Rückwärtszählen auf 0,
Beim Vorwärtszählen auf 59.
Zahlen > 59 bedeuten FEHLER, is klar.
>Tu's nicht. Auf > 59 prüfen geht sicher, aber ist ein Hack. Wenn>man negative Zahlen erhalten kann, sollte man die Zahlen bitteschön>auch als vorzeichenbehaftet betrachten, warum ist das denn so>schlimm?
Das bezog sich natürlich darauf das man entweder unsigned oder signed
benutzt. Ich denke da exakt wie du, warum nicht int8_t benutzen dafür
ist er da. Bei allem anderen würde ich meine Lehrlinge als Saboteure
beschimpfen ;)
Mit zwei zugedrückten Augen würde ich vielleicht noch einen Typcast nach
signed tolerieren, aber auch da wäre es besser gleich den richtigen
Datentypen zu wählen.
Gruß Hagen
>Wie man einen Unsigned Datentyp auf kleiner 0 testen>kann ist mir unbekannt.
indem man diesen hart casted nach signed. Die CPU selber kennt keinen
signed oder unsigned Datentypen, für sie sind es binäre und
komplementäre Zahlen, also sowohl unsigned wie auch signed. Erst die
nachfolgenden Opcodes bei einem Vergleich, also die Auswertung der
Flags, entscheidet ob man die vorherige Operation ->
Subtraktion/Addition usw. als signed oder unsigned betrachtet. Aber in
den Datentypen selber gibts diesen Unterschied nicht (vorrausgesetzt wie
reden hier von generischen Datentypen die die CPU von Hause aus versteht
und nicht von selbstgestrickten Datentypen).
Gruß Hagen
Dann habe ich mich wohl etwas ungeschickt ausgedrückt.
Wenn ein unsigned Typ verwendet wird, dann
gibt es keine negativen Zahlen.
Natürlich kann man hintenrum sowas doch hinbekommen,
ist aber nicht die feine Art.
Ciao.