Forum: Mikrocontroller und Digitale Elektronik Bit-Shifting Verständnisproblem


von Manuel H. (manu77)


Lesenswert?

Hallo,
eine kurze Frage zu einem Bit-Shift:
1
uint32_t FirmwareByteAnzahl;
2
FirmwareByteAnzahl = (uint8_t)0x80;
3
FirmwareByteAnzahl |= ((uint8_t)0x80 << 8) & 0xFF00;
4
FirmwareByteAnzahl |= ((uint8_t)0 << 16) & 0xFF0000;

Ohne die UND Operatoren kommt:
1
11111111 11111111 10000000 10000000
heraus. Wieso sind die letzten beiden Bytes 0xFF ?

von (prx) A. K. (prx)


Lesenswert?

Weil "int" auf deiner Maschine nur 16 Bits breit ist.

von Karl M. (Gast)


Lesenswert?

Diese Zeile mach schon mal gar nichts!
1
FirmwareByteAnzahl |= ((uint8_t)0 << 16) & 0xFF0000;

von (prx) A. K. (prx)


Lesenswert?

Merke: Bei
  var = expr;
ist die Breite der Arithmetik nicht von "var" abhängig, sondern nur 
von dem, was in "expr" steht.

von Manuel H. (manu77)


Lesenswert?

Karl M. schrieb:
> Diese Zeile mach schon mal gar nichts!
> FirmwareByteAnzahl |= ((uint8_t)0 << 16) & 0xFF0000;

Ja Imgrunde stammt der Code aus einer Routine. Die Null kann dort ein 
weiteres Byte sein.

Trotzdem ist es mir nocht nicht klarer geworden.

Wenn ich 0x80 in die Variable lade kommt das raus:
1
00000000 00000000 00000000 10000000
Wenn ich das Byte 0x80 Shifte und mit Oder reinkopple, müsste doch 
eigentlich folgendes herauskommen:
1
00000000 00000000 10000000 10000000

von Manuel H. (manu77)


Lesenswert?

A. K. schrieb:
> Merke: Bei
>   var = expr;
> ist die Breite der Arithmetik nicht von "var" abhängig, sondern nur
> von dem, was in "expr" steht.

Okay, also muss ich casten:
1
FirmwareByteAnzahl = 0x80;
2
FirmwareByteAnzahl |= ((uint32_t)0x80 << 8);

Danke!

von (prx) A. K. (prx)


Lesenswert?

Und schau auf die Warnungen des Compilers.
Die sind nicht zum Spass da.

von Rolf M. (rmagnus)


Lesenswert?

Manuel H. schrieb:
> Trotzdem ist es mir nocht nicht klarer geworden.
>
> Wenn ich 0x80 in die Variable lade kommt das raus:
> 00000000 00000000 00000000 10000000
> Wenn ich das Byte 0x80 Shifte und mit Oder reinkopple,
> müsste doch eigentlich folgendes herauskommen:
> 00000000 00000000 10000000 10000000

Nur wenn int bei dir 32 Bit breit ist. Bei einem 16-Bit-int kommt 
erstmal raus:
10000000 10000000
Zur Erweiterung auf den uint32_t auf der linken Seite wird nun erstmal 
der int vorzeichenrichtig auf 32 Bit erweitert, was im Prinzip bedeutet, 
daß das oberste Bit des int in die nächsten 16 Bit reinkopiert wird. 
Danach wird dieses Bitpattern dann in einen uint32_t geschrieben.

von (prx) A. K. (prx)


Lesenswert?

Und bei der Version mit "& 0xFF00" wirds noch etwas subtiler. Denn 
0xFF00 ist vom Typ "unsigned". Das ändert zwar zunächst nichts am 
Bitpattern des Ergebnisses, aber an dessen Typ. Der ist nun auch vom Typ 
"unsigned". Und der wird bei der Zuweisung ohne Vorzeichen auf 32 Bits 
erweitert.

: Bearbeitet durch User
von Manuel H. (manu77)


Lesenswert?

A. K. schrieb:
> Und schau auf die Warnungen des Compilers.
> Die sind nicht zum Spass da.

Das wird bei mir nicht als Warnung aufgeführt.

von (prx) A. K. (prx)


Lesenswert?

Welcher Compiler? GCC liefert
warning: left shift count >= width of type
für (uint8_t)0 << 16

von quarzlöter (Gast)


Lesenswert?

Da du mal wieder hier vorbeischaust: was ist denn aus der 
Quarz-Reflowsache geworden? wüsste schon gern, worans lag.

von Manuel H. (manu77)


Lesenswert?

Habe leider noch keine defekte Platine erwischt, an der ich endlich 
testen kann. Sobald ich eine in den Händen halte, werde ich die neue 
Firmware testen. Teile es dann natürlich im anderen Thread ;)

@ A.K. die Null Version kommt in meinem Code gar nicht vor, ist nur beim 
Posten entstanden.

: Bearbeitet durch User
von (prx) A. K. (prx)


Lesenswert?

Ob 0 oder nicht 0, das ist hier nicht die Frage.
Die 16 ist's, um die es geht.

von Manuel H. (manu77)


Lesenswert?

A. K. schrieb:
> Ob 0 oder nicht 0, das ist hier nicht die Frage.
> Die 16 ist's, um die es geht.

Die ganze Zeile kommt nicht vor. Hab sie gerade hinzugefügt und du hast 
Recht, er warnt (ist der GCC). Ich werde mehr auf Warnungen achten.

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
Noch kein Account? Hier anmelden.