shiften funktioniert nicht

Gast #211963
Lesenswert?

@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 #211964
Lesenswert?

.

   "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 #211965
Lesenswert?

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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren