Differenz im Integer-Zahlenraum

OP #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.
OP #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.
OP #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

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.