mikrocontroller.net

Forum: Compiler & IDEs Bitshift und Ansi C


Autor: Benedikt (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Benedikt (Gast)
Datum:

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

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Benedikt (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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)

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.