Fehler bei Bitmanipulation

Gast #2724952
Lesenswert?

Hallo Leute,
ich bin noch Anfänger im Programmieren und hoffe, dass mir Jemand 
erklären kann, was ich hier falsch mache:
1
unsigned char a,b,c;
2
unsigned short long d;
3
a=0x12;
4
b=0x34;
5
d=0x56;
6
d=((a<<16) |(b<<8) | c);
Eigentlich möchte die 3 Char zu einer Long Variablen zusammenbasteln, 
sodass in d=0x123456 ist. Beim (a<<16) scheint aber etwas nicht zu 
funktionieren. Kann ich nicht so weit verschieben?? Ich programmieren 
einen PIC12F1840 (8 Bit) und benutzte den HIGH_TECH Compiler und MPLAB.
Gast #2725023
Lesenswert?

Falk Brunner schrieb:
> Was ist ein short long?
Das ist eine 24 Bit Variable. Habe ich aus dem Manuel vom HIGH_TECH 
Compiler.
Vielen Dank für die Hilfe, jetzt klappt es! Ich war sogar schon ganz nah 
dran mit:
1
d=(((long)(a <<16() | ((long)(b<<8)) | c);
Aber da habe ich die Klammern falsch gesetzt und die Convertierung erst 
gemacht, als bereits Werte abgeschnitten wurden.

Was mich noch wundert, ist dass ich ein Char um 8 bin verschieben kann, 
ohne dass etwas abgeschnitten wird, sobald ich es aber um 12 Bit 
verschiebe, klappt es nicht mehr. Hier kommt also wie erwartet y = 0x 00 
00 12 00 raus
1
unsigned char x;
2
unsigned long y;
3
x=0x12;
4
y=x<<8;
Hier dagegen kommt y = 0x 00 00 20 00 raus, die 1 wird abgeschnitten.
1
x=0x12;
2
y=x<<12;
Aber das soll mich nicht weiter stören. Vielen Dank!
#2725031
Lesenswert?

Horst schrieb:

> Was mich noch wundert, ist dass ich ein Char um 8 bin verschieben kann,
> ohne dass etwas abgeschnitten wird,

Das ist nicht weiter verwunderlich.

In C gilt die Regel:
Gerechnet wird grundsätzlich immer mindestens mit int (bei dir also mit 
16 Bit) als der kleinsten Einheit.
Der Compiler kann, wenn er nachweisen kann dass sich das Ergebnis nicht 
ändert, auf 8 Bit optimieren, aber das ist eine Optimierung, d.h. er 
muss es nicht machen.
Was er aber machen muss, ist sich an den C-Standard zu halten. Und der 
schreibt int als kleinste Einheit bei Rechenoperationen (und Schieben 
ist auch nichts anderes) vor.

d.h.
    a << b

ist grundsätzlich mindestens eine int Operation, selbst dann, wenn a ein 
8 Bit Datentyp ist. (Der Datentyp von b spielt in dieser Operation keine 
Rolle)

> sobald ich es aber um 12 Bit
> verschiebe, klappt es nicht mehr.

Klar. Jetzt knallst du links über die 16 Bit deines 
int-Zwischenergebnisses raus.

> Aber das soll mich nicht weiter stören.

Falsche Einstellung. Du musst dich fragen: Was steckt da dahinter? Ist 
das vom C-Standard so definiert oder ist das etwas was mein Compiler so 
macht, weil ihm der C-Standard dazu die Freiheit lässt. Das sind relativ 
wichtige Punkte, zu wissen, welches Verhalten garantiert ist (und daher 
auf allen C-Compilern gleich funktioniert) und was nicht garantiert ist.
Gast #2725180
Lesenswert?

Ach so ist das! Vielen Dank für die gute Erklärung!

Karl Heinz Buchegger schrieb:
>> Aber das soll mich nicht weiter stören.
>
> Falsche Einstellung. Du musst dich fragen: Was steckt da dahinter?

Da hast du eigentlich Recht. Das sind nur so Dinge, die sehr schwer 
sind, alleine herauszufinden. Geht mir jedenfalls so. Darum umso mehr 
Dank für die Erklärung! :)

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