shiften funktioniert nicht

Persönliche Seite
Das L als Suffix der Konstanten ist nicht erforderlich.
Das rechte Argument des Shift-Operators darf nie so groß werden wie die
Anzahl der Bits des linken Ausdrucks; wenn "long" eine 32-Bit-Variable
ist, darf maximal um 31 geshiftet werden. Wird mit 32 geshiftet, ist das
Ergebnis undefiniert.
(Ist so bei C und C++ definiert).
Gast
@Rufus

"Das L als Suffix der Konstanten ist nicht erforderlich."

Nein.

Das L als Suffix der Konstanten ist immer dann erforderlich, wenn der
andere Operand nicht 32 Bit ist, aber das Ergebnis 32 Bit sein soll.


Die Rechnung wird immer in dem Format durchgeführt, welches dem
Operanden mit dem größeren Format entspricht.
Die Umwandlung ins Zielformat erfolgt erst hinterher:

unsigned long i = 16 << 16; // ergibt 0

unsigned long i = 16L << 16; // ergibt 0x100000L
unsigned long i = 16 << 16L; // ergibt 0x100000L
unsigned long i = 16L << 16L; // ergibt 0x100000L



"Wird mit 32 geshiftet, ist das Ergebnis undefiniert."

Seit wann denn das ?

Von unten werden Nullen reingeschoben, d.h. das Ergebnis ist immer 0.

Manche Programmierer benutzen sogar diesen Befehl, um ein Register zu
löschen.


Peter
Persönliche Seite
.

   "Wird mit 32 geshiftet, ist das Ergebnis undefiniert."

   Seit wann denn das ?

Das steht so sowohl im ANSI-C- als auch im C++-Standard. Das von Dir
geschilderte Verhalten muss so nicht sein.

Hier das Verhalten, wie es beispielsweise der VC++ 6.0-Compiler von
Microsoft an den Tag legt:


183:          unsigned long bla;
184:
185:          bla = 1;
0040161C   mov         dword ptr [ebp-9Ch],1
186:
187:          bla <<= 32;
00401626   mov         eax,dword ptr [ebp-9Ch]
0040162C   shl         eax,20h
0040162F   mov         dword ptr [ebp-9Ch],eax

Das sieht alles ganz unverdächtig aus; betrachtet man aber den
Shift-Befehl (shl eax,20h) genauer und liest die Dokumentation, so
steht da (Zitat Borland Turbo Assembler-Referenzhandbuch)

  Um die maximale Ausführungszeit zu verringern, erlaubt der
  80286/80386-Prozessor nicht mehr als 31 Schiebe-Operationen.
  Werden mehr als 31 Schiebe-Operationen angegeben, so werden
  lediglich die unteren fünf Bits einbezogen.

Die unteren 5 Bits von 0x20 sind 0. Das Resultat obigen Codefragments
ist also 1.

OK, so nimmt man zuerst an, daß MS hier (noch) einen schweren
Compilerfehler programmiert hat, so findet man nach einiger Suche das
hier:

  5.8 - Shift operators [expr.shift]

  -1- The shift operators << and >> group left-to-right.

  shift-expression:
  additive-expression
  shift-expression << additive-expression
  shift-expression >> additive-expression

  The operands shall be of integral or enumeration type and
  integral promotions are performed. The type of the result
  is that of the promoted left operand.
  The behavior is undefined if the right operand is negative,
  or greater than or equal to the length in bits of the
  promoted left operand.

  (Quelle: ISO/IEC 14882:1998)


Der letzte Satz ist entscheidend.
Gast
Jetzt, wo Du es sagst, erinnere ich mich wieder:

Beim 8086 wurde SHL mit 255 gerne als Delayloop verwendet, mit der
Folge, daß aufm 80286 alles viel zu schnell ablief. Und obendrein war
das Register nicht mal richtig gelöscht.


D.h. also, wenn Werte größer als 31 auftreten können, muß man das
abtesten und getrennt behandeln.


Peter

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 21 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.