Differenz im Integer-Zahlenraum

#3275830
Lesenswert?

Guten Morgen,
es ist Sonntagmorgen und meine Liebste schläft quasi auf meinem C-Buch. 
Wenn ich zwei Integer-Zahlen, meinetwegen int8_t a,b , habe, haben diese 
in ihrem zyklischen Zahlenraum mehrere Abstände, nämlichb z.B.:

diff1 = b-a;
diff2 = b-256*a;
usw.

Das wird immer dann interessant, wenn eine Variable überträgt, bei mir 
konkret im folgenden Fall:
1
int8_t this,last,delta;
2
this = zaehleraehnliche_funktion();
3

4
while(1) {
5
  last = this;
6
  this = zaehleraehnliche_funktion();
7
  delta = this-last;
8

9
  ...
10
}
Im Moment des Übertrags steht in this=-128 und in last = 127, was vom 
normalen Differenzoperator völlig richtig als -255 interpretiert wird - 
aber der Abstand, den ich wirklich suche ist ja 1. Bei der umgekehrten 
Richtung entsteht das gleiche Problem.
Wie geht es am effizientesten, den kürzesten gerichteten Abstand im 
Zahlenraum auf einem AVR zu berechnen?

Viele Grüße
Nicolas
Moderator #3275832
Lesenswert?

Mach die Variablen this, last und delta alle vom Typ uint8_t. Dann 
bekommst du immer eine positive Differenz heraus, auch beim Überlauf. 
Außerdem ist das Ergebnis von Additionen und Subtraktionen bei 
Überläufen im C-Standard nur für Unsigned-, nicht aber für Signed-Werte 
spezifiziert.
#3275835
Lesenswert?

Guten Morgen Yalu,
stimmt, die Undefiniertheit beim Überlauf habe ich schon wieder 
verdrängt, weils beim AVR-GCC immer funktioniert.

diff muß signed bleiben: Ich brauche das Vorzeichen der Differenz - 
zaehleraehnliche_funktion() zählt vorwärts und rückwärts. Und das 
Problem des Abstandes bleibt dabei gleich.

Vermutlich komme ich um den Vergleich des Betrags von "delta" mit 127 
nicht herum. Aber ich bin trotzdem noch gespannt.
#3275836
Lesenswert?

OK, das war meine Dummheit am Sonntagmorgen: Das Problem tritt gar nicht 
auf, wenn man es richtig macht. In meinem ursprünglichen Programm habe 
ich dieses Konstrukt verwendet:
1
int16_t counter = 0;
2
int8_t this,last,delta;
3
this = zaehleraehnliche_funktion();
4

5
while(1) {
6
  last = this;
7
  this = zaehleraehnliche_funktion();
8
  counter += this-last;
9

10
  ...
11
}
Damit wird der "this-last" in einen int16 gecastet und damit kann der 
große Übertrag erst auftauchen. Bei
1
int18_t counter = 0;
2
int8_t this,last,delta;
3
this = zaehleraehnliche_funktion();
4

5
while(1) {
6
  last = this;
7
  this = zaehleraehnliche_funktion();
8
  delta = this-last
9
  counter += delta;
10

11
  ...
12
}
tritt das Problem gar nicht auf.

Danke für die Diskussion! Ansonsten wäre mir die 
signed-Überlauf-Problematik nicht bewußt gewesen.
(Firma: Schweigstill IT) Persönliche Seite #3286648
Lesenswert?

Und selbst in Sprachen, in denen "this" kein reserviertes Schlüsselwort 
ist, gibt es trotzdem die Konvention, es ausschließlich für eine 
Referenz bzw. einen Zeiger auf das aktuelle Objekt zu verwenden.

Eine ähnliche Konvention gibt es für "self", z.B. in Python:

http://stackoverflow.com/questions/1079983/why-do-pythonistas-call-the-current-reference-self-and-not-this

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren