Forum: Compiler & IDEs Überlauf bei integer-Berechnung oder nicht??


von Markus (Gast)


Lesenswert?

Hallo,

ist folgender Code in C fehlerfrei möglich, oder bekomme ich einen
Überlauf während der Berechnung?

------
unsigned int zahl1=0xeeee, zahl2=0xdddd, zahl3;
zahl3 = (zahl1+zahl2)/2;
------

Danke für jeden Tipp
:-)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Du bekommst einen Überlauf, aber der bringt keinen Trap, d.h.
der übergelaufene Wert wird stillschweigend auf die Bitlänge
von unsigned int abgeschnitten und danach halbiert.

von Markus (Gast)


Lesenswert?

D.h. das Ergebis ist trotzdem korrekt, richtig? :)

von Walter (Gast)


Lesenswert?

nein, ist natürlich nicht richtig wenn Du von der Summe die erste Ziffer

abschneidest und diese Zahl dann halbierst.
Warum nimmst du nicht 32Bit Zahlen??

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

> D.h. das Ergebis ist trotzdem korrekt, richtig? :)

Wenn für dich 0x6665 (oder 26213) der korrekte Wert ist, dann
ist es das.  Wenn du eher 58981 (0xe665) erwartet hast, dann
wird das nicht dabei rauskommen.  Die ,,nicht mehr passenden''
Bits werden ja schon vor der Division durch 2 abgeschnitten.

Das Ganze hat dennoch einen praktischen Nutzen.  Wenn du z.B.
einen 16-bit-Zeitgeber hast, der einfach nur durchläuft, und
du nimmst zu zwei Zeitpunkten, von denen du nur weißt, dass
sie weniger als 65535 Takte auseinanderliegen, dann kannst du
einfach den ersten Wert vom zweiten subtrahieren, um die
Zeitdifferenz zu ermitteln.  Falls der erste Wert größer war
als der zweite, kommt dennoch die korrekte Differenz heraus.
(Das gilt natürlich nur, solange man mit vorzeichenlosen Zahlen
rechnet.)

von Rolf Magnus (Gast)


Lesenswert?

> Du bekommst einen Überlauf, aber der bringt keinen Trap,

Überlauf gibt es bei unsigned in C nicht. Das Ergebnis ist einfach
modulo den größten darstellbaren Wert. Das meintest du zwar vermutlich,
aber es ist eben kein Überlauf. Ein solcher würde irgendwie
signalisiert, z.B. eben durch Trap oder ein Flag, und sowas gibt's in
C nicht.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Der C-Standard ist hier in der Terminologie nicht völlig
konsistent.  Einerseits wird von "overflow wrapping silently"
gesprochen, andererseits davon, dass unsigned integers keinen
overflow haben können.  Auf jeden Fall entsteht daraus keine
"trap representation".

Achtung, das trifft aber nur für unsigned integers zu.  Für
signed integers ist das Verhalten undefined, d. h. von still-
schweigendem overflow bis trap darf alles passieren.

von Frank (Gast)


Lesenswert?

Kommt drauf an, wie Dein Compiler ein int interpretiert. Nimm ein
unsigned long, dann wirds 32bittig, nimm ein unsigned short, dann sinds
16 bit. Wenn man nicht weiß, was der Compiler macht, sollte man kein int
verwenden (sollte man eigentlich sowieso nicht, da die Länge von int
nicht definiert ist)

von Rolf Magnus (Gast)


Lesenswert?

> Einerseits wird von "overflow wrapping silently" gesprochen,

Wo? Das einzige, was ich da finden konnte, war ein Beispiel zur
Optimierung, wo von einer bestimmten Repräsentation von char
ausgegangen wird. Aber da steht nichts von unsigned.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Ja, hast wohl Recht, ich habe mir den Kontext nicht gut genug
angesehen.  Von overflow ist lediglich bei signed integers die
Rede (oder bei char, bei dem die Möglichkeit gegeben ist, dass
es sich um einen signed Typ handelt -- und natürlich bei
floating point, aber das ist sowieso was anderes).

> Wenn man nicht weiß, was der Compiler macht, sollte man kein int
> verwenden

Einspruch.  Wenn es nicht auf die maximal darstellbare Größe
ankommt, kann man normalerweise davon ausgehen, dass ein "int"
für jeden Prozessor eine relativ gut handhabbare Größe ist.

von Frank (Gast)


Lesenswert?

>Einspruch.  Wenn es nicht auf die maximal darstellbare Größe
>ankommt, kann man normalerweise davon ausgehen, dass ein "int"
>für jeden Prozessor eine relativ gut handhabbare Größe ist.

Da der gute Programmierer aber weiß, was in einer Variable sein kann,
kann er auch den Datentyp entsprechend festlegen. Zeig mir mal einen
Prozessor, der bei einem 8 oder 16 bit Datentyp langsamer ist, als bei
32 bit. Im schlimmsten Fall ist er nicht schneller, es besteht aber
immer noch die Möglichkeit, Speicher zu sparen. Ich bleibe dabei: Wenn
man nicht weiß, was int genau bedeutet, sollte man lieber auf short und
long setzen. Selbst wenn man weiß, was es bedeutet, ist die
Portierbarkeit eingeschränkt, da auf System 1 int gleich long sein kann
und keine Probleme auftreten und auf System 2 int gleich short. Dann hat
man u.U Fehler und weiß nicht, wo man suchen muß.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

> Zeig mir mal einen Prozessor, der bei einem 8 oder 16 bit Datentyp
> langsamer ist, als bei 32 bit.

Wirst du zur Genüge finden können, vor allem im RISC-Bereich, die
müssen dann ihr Ergebnis noch extra zurechtstutzen oder sowas.  Selbst
bei einem Pentidumm wäre ich mir da nicht so sicher.

Gut, ein AVR wird wohl mit 8 bit immer schneller sein als mit 16 bit.

von Rolf Magnus (Gast)


Lesenswert?

> Zeig mir mal einen Prozessor, der bei einem 8 oder 16 bit Datentyp
> langsamer ist, als bei 32 bit

x86 mit jedem eignigermaßen modernen Betriebssystem.

von Frank (Gast)


Lesenswert?

>x86 mit jedem eignigermaßen modernen Betriebssystem.

Ok, das hab ich mittlerweile auch schon rausgefunden. Liegt aber
weniger am Prozessor selbst, sondern am Compiler, der noch einiges
zusätzlich erledigen muß.
Für obiges Problem würde ich aber immernoch ein long vorschlagen, wenn
es keinen Überlauf geben darf und short, wenn es einen geben soll.

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.