Forum: Compiler & IDEs Bitshift und Ansi C


von Benedikt (Gast)


Lesenswert?

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.

von johnny.m (Gast)


Lesenswert?

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.

von Benedikt (Gast)


Lesenswert?

Eigentlich ja, aber ist es in C nicht so, dass alle Operationen als int
ausgeführt werden ?

von Rolf Magnus (Gast)


Lesenswert?

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.

von johnny.m (Gast)


Lesenswert?

Upps, klar, Rolf hat natürlich recht.... Ist heute glaub ich nicht mein
Tag... Aber wie war das noch mit den Vorzeichen beim Schieben?

von Benedikt (Gast)


Lesenswert?

@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)

von Rolf Magnus (Gast)


Lesenswert?

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-de&#64257;ned behavior
  unspeci&#64257;ed behavior where each implementation documents how
the
  choice is made

2 EXAMPLE   An example of implementation-de&#64257;ned behavior is the
  propagation of the high-order bit when a signed integer is
  shifted right.

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


Lesenswert?

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

von Rolf Magnus (Gast)


Lesenswert?

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