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
Matthias Weißer wrote:
> keine gute Idee da 255 % 60 = 15
Ist doch unwichtig.
1 | SekundenHoch() |
2 | {
|
3 | sekunden = (sekunden + 1) % 60; |
4 | }
|
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:
1 | if (time->hour<23) time->hour++; else time->hour=0; |
2 | if (time->hour>0) time->hour--; else time->hour=23; |
Gruß und Danke Andreas
@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 ;) ;)
Warum nimmst du nicht int8_t? Dein gewünschter Wertebereich passt ja da noch ordentlich hinein, und du kannst danach ganz legal auf -1 testen.
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.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.