Hallo, folgendes funktioniert bei mir nicht: unsigend long a; unsigend long b; b = (a<<16); was ist hier falsch... gruss samy
> unsigend long a; > unsigend long b; > > b = (a<<16); > > was ist hier falsch... a ist nicht initialisiert.
"unsigend long a; unsigend long b;" heißt das nicht "unsigned long" ? Außerdem mach mal hinter dem 16 noch ein L ran "a = (b << 16L)" Gruss
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).
@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
. "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.
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
Naja, das betrifft alle Datentypen. uint8_t darf maximal mit 7 geshiftet werden, uint16_t maximal mit 15 uint32_t maximal mit 31 uint64_t maximal mit 63 Das ist äußerst heimtückisch.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.