Hallo, ich verzweifle gerade beim beschreiben einer 32Bit Variablen ... 1. Versuch unsigned long test; test = 0x12345678; mein Debugger zeigt anschließend im Watch Window den Wert 0x12345678 an. Test ok 2. Versuch unsigned long test; test = ((0x12<<24) | (0x34<<16) | (0x56<<8) | (0x78<<0)); oder test = ((unsigned long)(0x12<<24) | (0x34<<16) | (0x56<<8) | (0x78<<0)); mein Debugger zeigt 0x00005678 an ... was läuft hier schief? auch der Compiler schmeißt eine Warning warning: left shift count >= width of type Warum? Gruß
Verzweifelter schrieb: > test = ((0x12<<24) Das geht bei einer 8/16-Bit Kiste in die Hose. Den Grund hat dir der Compiler auch genannt. Das ist eine "int" Rechnung. Besser: test = ((0x12L<<24) Und auch das wird erst in "int" berechnet und danach erweitert, zu spät: > test = ((unsigned long)(0x12<<24)
Hallo, danke, jetzt funktioniert es. Aber was passiert denn da genau? Mit dem L caste ich doch das Byte in einen long ... eigentlich müsste es doch dann in die Hose gehen?????
Verzweifelter schrieb: > Aber was passiert denn da genau? Mit dem L caste ich doch das Byte in > einen long ... eigentlich müsste es doch dann in die Hose gehen????? Wieso? 0x12 nach "long" konvertiert ändert den Wert nicht. Übrigens ist das L kein Cast, sondern ein Teil der Zahl. Und 0x12 ist kein Byte, sondern "int".
>eigentlich müsste es doch dann in die Hose gehen
Warum meinst Du das?
Es ist im Gegenteil so, das dieses L (das ist übrigens ein Suffix, der
den Datentyp anzeigt, jedoch kein cast [nicht im eigentlichen Sinne])
gerade das möglich macht, was Du willst.
1 | 0x12<<24 |
gucken wir uns mal binär an. Die 12 ist ein Integer, hat 16 Bit: 0000.0000.0000.1010 Wenn man das 24 mal nach links verschiebt, dann bleibt 0000.0000.0000.0000 denn links von dem 15. Bit ist nichts mehr. Deswegen warnt Dich auch der Compiler. Bei
1 | 0x12L<<24 |
erhälst Du 0000.0000.0000.0000.0000.0000.0000.1010 was nach dem Schieben um 24 Bit durchaus noch darstellbar ist. 0000.1010.0000.0000.0000.0000.0000.0000
0x12 ist einfach nur eine konstante Zahl (dezimal 18). Standardmäßig ist sie so breit wie ein int, also auf Deiner Plattform 16 Bit. So lange sie nicht in eine Variable mit anderer Breite gespeichert wird, wird mit ihr gerechnet, als ob sie aus einer 16-Bit-Variable käme, also 0x0012. Wenn Du das um 16 Stellen nach links schiebst, bleibt nur noch 0x0000. Die "Variable" wird nicht automatisch verbreitet, wenn das Ergebnis nicht reinpasst. Das ginge zur Laufzeit auch schlecht. Wenn Du ein L für long dahinter schreibst, wird die Zahl dagegen als 32-Bit-Konstante betrachet, also als 0x00000012 und entsprechend damit gerechnet. Dann klappen auch die Shifts, ohne dass der Wert links rausfällt.
Hmm schrieb: > Die 12 ist ein Integer, hat 16 Bit: > 0000.0000.0000.1010 0x12 ist eher 0000.0000.0001.0010
@ A.K. Oh, Sch... Hast recht. Danke für den Hinweis. Es muss also heissen: 0x12<<24 gucken wir uns mal binär an. Die 12 ist ein Integer, hat 16 Bit: 0000.0000.0001.0010 Wenn man das 24 mal nach links verschiebt, dann bleibt 0000.0000.0000.0000 denn links von dem 15. Bit ist nichts mehr. Deswegen warnt Dich auch der Compiler. Bei 0x12L<<24 erhälst Du 0000.0000.0000.0000.0000.0000.0001.0010 was nach dem Schieben um 24 Bit durchaus noch darstellbar ist. 0001.0010.0000.0000.0000.0000.0000.0000
Was würde ein L hinter der Zahl auf einer 32Bit Maschine machen ... ? Dann ist es doch 64Bit, oder? Wie würde ich die Sache generisch programmieren?
Verzweifelter schrieb: > Was würde ein L hinter der Zahl auf einer 32Bit Maschine machen ... ? > Dann ist es doch 64Bit, oder? Im 32-Bit Programmiermodell (LP32) eher selten. Und auch bei 64-Bit Maschinen im 64-Bit Programmiermodell nur in Linux (LP64), nicht aber bei Microsoft (LLP64). http://www.unix.org/version2/whatsnew/lp64_wp.html > Wie würde ich die Sache generisch programmieren? Der Einfachheit halber L verwenden. In LP64 ist das dann zwar 64 Bit breit, aber das dann auf 32 Bits runter zu konvertieren ist kein Problem. Wenn du Variablen von stets exakt 32 Bits brauchst: Wie schon erwähnt unbedingt (u)int32_t als Datentyp verwenden.
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.