Forum: Compiler & IDEs unsigned - unsigned = signed?!


von mC (Gast)


Lesenswert?

Servus Forum,

ich steh grad bissl aufm Schlauch. Folgender Ausschnitt aus meinem 
C-Code:
1
uint8_t i;
2
uint8_t j;
3
int8_t k;
4
5
...
6
7
k = i - j;
i ist nicht zwangshalber größer als j, wird mein k trotzdem richtig 
berechnet? ich steh bissl aufm Schlauch. eigenlich wird ja mein Ergebnis 
erst unsigned berechnet und dann erst in einen signed integer 
umgewandelt, was mir Fehler bei i<j liefern sollte oder nicht?
Oder wird mir k in einem Wertebereich von -128 bis 127 immer korrekt 
ausgerechnet?


PS: ich hab die suche verwendet, aber ich weiß nciht so genau nach 
welchen stichworten ich suchen soll und so ist meine suche recht 
erfolglos geblieben

von Benedikt K. (benedikt)


Lesenswert?

mC schrieb:
> i ist nicht zwangshalber größer als j, wird mein k trotzdem richtig
> berechnet?

Ja, dank Zweierkomplement.

> eigenlich wird ja mein Ergebnis
> erst unsigned berechnet und dann erst in einen signed integer
> umgewandelt,

Ja.
Warum es aber dennoch funktioniert liegt wie oben schon geschrieben am 
Zweierkomplement: 5 - 10 = -5, oder wenn bei 8bit unsigned Zahlen 
bleibt: 5-10+256=251

251 im Zweierkomplement betrachtet (was die signed Zahlen machen), 
entspricht -5. Das Ergebnis passt also.

Daher ist es bei Addition und Subtraktion egal, ob man erst rechnet oder 
umwandelt wenn das Zweierkomplement verwendet wird, nur bei 
Multiplikation und Division muss man aufpassen.

von Thomas B. (yahp) Benutzerseite


Lesenswert?

> Daher ist es bei Addition und Subtraktion egal...

Halt! Natürlich ist es hier nicht egal. Aufgrund des unterschiedlichen 
Wertebereiches kann es hier schon zu Bereichsüberläufen kommen.

Bsp: i=255, j=1, k=???

von (prx) A. K. (prx)


Lesenswert?

Thomas B. schrieb:

> Halt! Natürlich ist es hier nicht egal. Aufgrund des unterschiedlichen
> Wertebereiches kann es hier schon zu Bereichsüberläufen kommen.

Es muss tatsächlich nicht immer das gleiche wie bei vorzeichenbehafteter 
Rechnung rauskommen, weil das Verhalten von vorzeichenbehafteter 
Rechnung bei Überlauf undefiniert ist.

Solange man aber vorzeichenlos rechnet und die Maschine mit 
Zweierkomplement arbeitet wird da nichts anbrennen. Andersrum kann das 
aber in die Hose gehen, vor allem bei der Multiplikation, weil da zwar 
das Produkt (dessen in C einzig relevante untere Hälfte) neutral ist, 
aber der Compiler bei vorzeichenbehafteter Rechnung Abkürzungen nehmen 
darf, die zu einem bei Überlauf nicht mehr korrekten Ergebnis führen 
können. Bei Add/Sub ist das weniger wahrscheinlich.

von Benedikt K. (benedikt)


Lesenswert?

Thomas B. schrieb:
>> Daher ist es bei Addition und Subtraktion egal...
>
> Halt! Natürlich ist es hier nicht egal. Aufgrund des unterschiedlichen
> Wertebereiches kann es hier schon zu Bereichsüberläufen kommen.
>
> Bsp: i=255, j=1, k=???

Nur funktioniert dieses Beispiel genausowenig mit 8bit signed Zahlen...

von der mechatroniker (Gast)


Lesenswert?

Allerdings sagt der C-Standard meines Wissens weder, dass mit 
Zweierkomplement gerechnet wird, noch dass dann mit Zweierkomplement 
gerechnet wird, wenn die Zielplattform das nativ tut (mal vom Sinn 
abweichender Implementierungen abgesehen).

von (prx) A. K. (prx)


Lesenswert?

der mechatroniker schrieb:

> Allerdings sagt der C-Standard meines Wissens weder, dass mit
> Zweierkomplement gerechnet wird

Da liegt du zwar richtig, aber Seymour Cray ist längst tot und sein 
geliebtes Einerkomplement starb in ganzzahliger Rechnung schon vorher 
(*). Insofern muss man an dieser Front wohl nicht päbstlicher sein als 
der Pabst.

Von der TCP/IP-Checksum mal abgesehen.

von Benedikt K. (benedikt)


Lesenswert?

der mechatroniker schrieb:
> Allerdings sagt der C-Standard meines Wissens weder,

Stimmt auch wieder. Wenn man den Code also wirklich universell schreibt, 
sollte man dies beachten. Allerdings ist mir nur noch ein Compiler 
untergekommen, der nicht mit Zweierkomplement gerechnet hätte.

von Thomas B. (yahp) Benutzerseite


Lesenswert?

>> Bsp: i=255, j=1, k=???
>Nur funktioniert dieses Beispiel genausowenig mit 8bit signed Zahlen...

Freilich nicht, aber dort kommt es halt auch gar nicht vor!

von Nn N. (jaytharevo)


Lesenswert?

1
uint16_t OCR1A_tmp = 0, OCR1B_tmp = 0;
2
 int16_t delta_th = 0, delta_el = 0;
3
4
.
5
.
6
.
7
.
8
9
delta_el = OCR1A - OCR1A_tmp;
10
delta_th = OCR1B - OCR1B_tmp;
11
12
OCR1A = OCR1A - delta_el/100;
13
OCR1B = OCR1B - delta_th/100;

Hey!

Könnte diese Rechnung theoretisch passen?

Controller ist ein ATMEGA88PA.

MfG,
Julian

Edit: Frohe Weihnachten :)!

von Herr Duden (Gast)


Lesenswert?

@A.K. (prx)

Kleiner, aber freundlich gemeinter Offtopic-Hinweis vom Duden-Team: Es 
heißt "Papst" und dementsprechend auch "päpstlich". Das Wort Kommt vom 
lateinischen "papa" = Vater.

von Tom (Gast)


Lesenswert?

Herr Duden, kleiner aber freundlich gemeinter Hinweis: Der Thread ist 
ca. 13 Monate alt!

von Klaus W. (mfgkw)


Angehängte Dateien:

Lesenswert?

Kommt drauf an, wie er den Satz verstanden haben möchte.
Wenn er meint, man müsse nicht mehr unnötigen Wind machen, als ein
solider Lüfter, dann ist es richtig geschrieben :-)

Abgesehen davon, daß es wohl vielleicht aus dem Griechischen kommt.
Meint zumindest Meyers Konversationslexikon.

von Nn N. (jaytharevo)


Lesenswert?

Wie wärs wenn jemand mal meine Frage liest^^ xD!

von Rolf M. (rmagnus)


Lesenswert?

Der Papst weiß doch alles, oder? Dann kannst du doch den mal fragen. ;-)
Aber mal im Ernst: Warum hängst du deine Frage eigentlich an einen 
Uralt-Thread an?
Und nun noch zur Frage:

> Könnte diese Rechnung theoretisch passen?

Hmm, könnte sie theoretisch, abhängig davon, was sie tun soll. Was steht 
denn in OCR1A_tmp drin? Ist es gewünscht, daß ein negativer Wert 
rauskommt, wenn die Differenz zwischen OCR1A und OCR1A_tmp sehr groß 
ist? Warum ist das delta vorzeichenbehaftet?

von (prx) A. K. (prx)


Lesenswert?

Julian Schild schrieb:

> Wie wärs wenn jemand mal meine Frage liest^^ xD!

Tja, und dann? Die _tmp Dinger sind bei dir 0 und die Deltas sind daher 
identisch mit den OCRs. Die werden folglich schrumpfen bis sie unter 100 
sind. Von da an ändert sich nix mehr.

Sollten die tmps mal nicht 0 sein: Die Sache hängt beispielsweise ein 
bisserl davon ab, wie weit der Zähler zählt. Muss ja nicht 0xFFFF sein.

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
Noch kein Account? Hier anmelden.