Forum: Mikrocontroller und Digitale Elektronik Befehl in C (Bitmanipulation)


von Robert (Gast)


Lesenswert?

Hallo,
kann mir jemand erkären was hier in welcher Reihenfolge passiert?
1
DEECON = (unsigned char) ((adr>>8)&0x01);

Grüße

von Falk B. (falk)


Lesenswert?

adr um 8 Bit nach recht schieben
Ergebnis mit 0x01 UND-verknüpfen
Ergebnis auf unsigned char casten und DEECON zuweisen

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

"adr" wird um 8 Bits nach rechts geshifted, was gleichbedeutend ist mit 
einer Division durch 256.

Das Resultat wird mit der Konstanten 1 verANDet.

Und das Resultat davon wiederum wird nach "unsigned char" gecastet und 
dann etwas namens "DEECON" zugewiesen.

Aufgrund der verANDung mit 1 gibt es hier nur zwei Möglichkeiten: 0 oder 
1.

von Karl M. (Gast)


Lesenswert?

Hallo,

da wir den Datentyp von adr nicht kennen, ist es auch möglich ein 
anderes Ergebnis zu erhalten !

Genau dann wenn - habe ich lange nicht mehr geschrieben -, wenn adr von 
Typ uint8_t ist =0, oder mit dem Datentyp int8_t =1 .

von HildeK (Gast)


Lesenswert?

Rufus Τ. F. schrieb:
> Aufgrund der verANDung mit 1 gibt es hier nur zwei Möglichkeiten: 0 oder
> 1.

Dachte ich mir auch so, warum hat da aber jemand die Shift-Operation 
eingesetzt. Das Ergebnis sollte doch identisch sein mit
1
DEECON =  1;

von HildeK (Gast)


Lesenswert?

HildeK schrieb:
> DEECON =  1;

Mist!
Natürlich:
1
DEECON = (unsigned char) (adr&0x01);

von Falk B. (falk)


Lesenswert?

@HildeK (Gast)

>>DEECON = (unsigned char) ((adr>>8)&0x01);

>DEECON = (unsigned char) (adr&0x01);

Über den Unterschied denken wir nochmal nach . . .

: Bearbeitet durch User
von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Karl M. schrieb:
> da wir den Datentyp von adr nicht kennen, ist es auch möglich ein
> anderes Ergebnis zu erhalten !

Nö. Das Ergebnis kann nur 0 oder 1 sein, völlig unabhängig vom Datentyp 
von "adr".

von gnugnu (Gast)


Lesenswert?

Rufus Τ. F. schrieb:
> Karl M. schrieb:
>> da wir den Datentyp von adr nicht kennen, ist es auch möglich ein
>> anderes Ergebnis zu erhalten !
>
> Nö. Das Ergebnis kann nur 0 oder 1 sein, völlig unabhängig vom Datentyp
> von "adr".

Schon richtig, aber es darf debattiert werden, unter welchen Bedingungen 
abhängig von adr das Ergebnis 0 oder 1 ist! Sieh Dir z.B. die folgenden 
Fälle an:

char adr = 0xff;  // DEECON = 0
short adr = 0xff;  // DEECON = 0
short adr = 0xff00; // DEECON = 1

Da ein Byte immer 8 bit ist und somit eine right shift um 8 IMMER alle 
bits eines Bytes unter den Tisch fallen lässt (mal angenommen die Shift 
Operation ist kein rotate, in welchem Fall noch Fallunterscheidungen 
zwischen signed und unsigned gemacht werden müssen), können wir davon 
ausgehen, dass adr mindestens 16 bit breit ist, sonst wäre die fn ein 
immer konstant 0.

von Mikro 7. (mikro77)


Lesenswert?

gnugnu schrieb:
> char adr = 0xff;  // DEECON = 0
> short adr = 0xff00; // DEECON = 1

The result of E1 >> E2 is E1 right-shifted E2 bit positions. [...] If E1 
has a signed type and a negative value, the resulting value is 
implementation-defined. [ISO/IEC 9899, § 6.5.7 Bitwise shift 
operators]

von HildeK (Gast)


Lesenswert?

Falk B. schrieb:
> Über den Unterschied denken wir nochmal nach . . .

Tu ich - und schäme mich auch schon :-)

von Amateur (Gast)


Lesenswert?

Die Anweisung macht nur dann Sinn, wenn adr wenigstens 16 Bit hat.
Andernfalls ist das Ergebnis vorhersehbar 0.

Übliche Compiler machen das folgende:
                      aaaaaaaa????????
1. >>8                00000000aaaaaaaa
2. & 0000000000000001 000000000000000a
3. (unsigned char)    0000000a

von Jim M. (turboj)


Lesenswert?

Amateur schrieb:
> Übliche Compiler machen das folgende:
>                       aaaaaaaa????????
> 1. >>8                00000000aaaaaaaa
> 2. & 0000000000000001 000000000000000a
> 3. (unsigned char)    0000000a

Wenn man hexadezimale Darstellung gewöhnt ist, kann man das überhaupt 
nicht vernünftig lesen.

Bitte nicht a..f für ein einzelnes Bit verwenden, ich bekomme davon 
Kopfschmerzen... ;-)

von Mikro 7. (mikro77)


Lesenswert?

Amateur schrieb:
> ...wenn adr wenigstens 16 Bit hat.
> Andernfalls ist das Ergebnis vorhersehbar 0.

Ach?
1
$ cat > foo.c <<EOF
2
#include <stdio.h>
3
int main()
4
{
5
  signed char i = 0xff ;
6
  unsigned char j = (i>>8) & 1 ;
7
  printf("%d\n",j) ;
8
  return 0 ;
9
}
10
EOF
11
$ gcc -Wall -o foo foo.c
12
$ ./foo
13
1

von Amateur (Gast)


Lesenswert?

@ Mikro 76,9

Der TO nannte die Ausgangsvariable "adr".

Dumm wie ich nun mal bin, habe ich eine Zahl ohne Vorzeichen 
vorausgesetzt...

Im Übrigen funktioniert Dein Bleistift nur bei Zahlen oberhalb 127.

von Nico W. (nico_w)


Lesenswert?

Amateur schrieb:
> Im Übrigen funktioniert Dein Bleistift nur bei Zahlen oberhalb 127.

Es gibt kein int8_t > 127.

Wenn der Wert <= 127 und >= 0 kommt halt 0 raus.
Wenn der Wert >=-128 und < 0 kommt 1 raus.

von Amateur (Gast)


Lesenswert?

@Nico
>Im Übrigen funktioniert Dein Bleistift nur bei Zahlen oberhalb 127.
Interessanterweise hat Mikro seinen signed char mit 0xff gefüttert.
Schon mit 0x7e sieht das Ganze anders aus.

von Nico W. (nico_w)


Lesenswert?

Amateur schrieb:
> @Nico
>>Im Übrigen funktioniert Dein Bleistift nur bei Zahlen oberhalb 127.
> Interessanterweise hat Mikro seinen signed char mit 0xff gefüttert.

Ja, aber 0xff ist bei signed char -128 und nicht 255 :)

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.