Da ich wieder mal auf die feinen Unterschiede einzelner Compiler reingefallen bin, folgede Frage: Welches Ergebnis liefert folgender Code in Ansi C ? unsigned char c=128; unsigned int i; i=c<<8; Steht in i eine 0 oder 32768 ? Beide Ergbenisse hatte ich schon, je nach Compiler. Ist eigentlich festgelegt, ob der Shift bei signed Wertden als Logical oder Arithmetic Shift ausgeführt wird ? Laut K&R ist das nämlich nicht festgelegt. Die beliebte Aufteilung eines int Wertes auf 2 chars würde dann nämlich nur manchmal bei signed Werten funktionieren.
Da auf der rechten Seite nur char-Werte stehen, müsste da eine "0" stehen. Wenn man "i = (unsigned int)c << 8" schreibt, dann sollte 32768 da stehen.
Eigentlich ja, aber ist es in C nicht so, dass alle Operationen als int ausgeführt werden ?
Vor einer Berechnung wie "c << 8" werden alle Integer, die kleiner als int sind, nach int konvertiert ("integer promotion"). Wenn int 16 bits groß ist, ist der maximale Wert 32767. Deshalb ist das Ergebnis 0. Bei einem 32-bit-int wäre das Ergebnis 32768.
Upps, klar, Rolf hat natürlich recht.... Ist heute glaub ich nicht mein Tag... Aber wie war das noch mit den Vorzeichen beim Schieben?
@Rolf Das heißt also, der Compiler führt einen Shift mit signed und unsigned Werten unterschiedlich aus ? Demzufolge müsste ein Rechtsschift auch bei einer negativen Zahl einer Division entsprechen (abgesehen von dem Auf/Abrundungsfehler)
Beim GCC ist es soweit ich weiß so. Es bietet sich ja auch an, bei vorzeichenbehafteten Zahlen einen arithmetischen Shift zu machen, wenn der Prozessor das unterstützt. Allgemein sagt die Norm aber, daß es "implementation-defined" ist. Das steht sogar schon in der Definition von "impelementation-defined" selbst drin: 3.4.1 1 implementation-defined behavior unspecified behavior where each implementation documents how the choice is made 2 EXAMPLE An example of implementation-defined behavior is the propagation of the high-order bit when a signed integer is shifted right.
> Vor einer Berechnung wie "c << 8" werden alle Integer, die kleiner > als int sind, nach int konvertiert ("integer promotion"). Wenn int > 16 bits groß ist, ist der maximale Wert 32767. Bis hierhin gehe ich mit dir mit. > Deshalb ist das Ergebnis 0. Hier nicht mehr. Der Standard erweitert den Ausdruck auf der rechten Seite implizit zu unsigned int, wenn der normale int das Ergebnis nicht mehr fassen kann (andernfalls müsste es ja eine integer overflow detection geben). Der entsprechende unsigned int Wert wird durch die Zuweisung anschließend wieder zu int und damit eine negative Zahl bei 16-bit-Integern.
Ja. Ich hatte irgendwie an vorzeichenlose Werte gedacht, wo das Bit einfach rausfällt, aber beim vorzeichenbehafteten Wert ist ja noch das Vorzeichenbit da.
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.