Bitshift und Ansi C

Gast #412151
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.
Gast
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.
Gast
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.
Gast
@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)
Gast
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.
Moderator Persönliche Seite
> 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.
Gast
Ja. Ich hatte irgendwie an vorzeichenlose Werte gedacht, wo das Bit
einfach rausfällt, aber beim vorzeichenbehafteten Wert ist ja noch das
Vorzeichenbit da.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 20 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

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.