Forum: Mikrocontroller und Digitale Elektronik bitweise vergleichen


von bitvergleich (Gast)


Lesenswert?

Hallo,

habe eine Frage zu folgendem Konstrukt:

if(Variable_16Bit & 0b0000 0000 0000 0001)
{
mach_was();
}
else
mach_was_andres();

Gewünscht ist, dass ich ausgehend von meiner 16-Bit-Variablen nur genau 
dann die Funktion mach_was() aufrufe, wenn die 16-Bit-Variable an der 
letzten Position eine "1" aufweist.

Erfüllt die obige Schreibweise diesen Zweck?


mfg und vielen Dank schonmal im Voraus.

von dave_chappelle (Gast)


Lesenswert?

Ähm bin mir jetzt grad nicht sicher ob

if(Variable_16Bit & 0b0000 0000 0000 0001)

ausreicht oder ob du auch noch

if(Variable_16Bit & 0b0000 0000 0000 0001 == 1)

schreiben musst. Ich würde zur Sicherheit die 2. Variante bevorzugen.
Ansonsten ist das sicher in Ordnung.

PS. warum schreibst du so eine lange Zahl in Binärschreibweise?
0x0001 würde auch genügen :-)

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

bitvergleich schrieb:
> if(Variable_16Bit & 0b0000 0000 0000 0001)

> Erfüllt die obige Schreibweise diesen Zweck?

Im Prinzip ja, praktisch nicht (weil einerseits nur sehr wenige 
C-Compiler die nicht standardkonforme Binärschreibweise kennen und weil 
andererseits da keine Leerzeichen drin sein dürfen).

Du kannst auch einfach schreiben

  if (Variable_16Bit & 1)

und landest beim gleichen Ziel.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

dave_chappelle schrieb:
> Ähm bin mir jetzt grad nicht sicher ob
>
> if(Variable_16Bit & 0b0000 0000 0000 0001)
>
> ausreicht

Tut es

> oder ob du auch noch
>
> if(Variable_16Bit & 0b0000 0000 0000 0001 == 1)
>
> schreiben musst.

Ist nicht nötig.

> Ich würde zur Sicherheit die 2. Variante bevorzugen.

Wird aber sehr unpraktisch, wenn ein anderes als Bit 0 getestet werden 
soll.

von Ralf G. (ralg)


Lesenswert?

bitvergleich schrieb:
> Erfüllt die obige Schreibweise diesen Zweck?

Ja.

Ich würde etwas mehr Übersicht reinbringen:
1
#define TESTBIT 0
2
3
...
4
5
if (Variable_16Bit & ( 1 << TESTBIT))
6
...

von Thorsten S. (Gast)


Lesenswert?

if

fragt auf Wahrheit ab, wahr ist alles was nicht gleich 0 ist. Du kannst 
das so machen.

& ist das bitweise UND, ist also richtig. Das Ergebnis ist nur "wahr" 
wenn das unterste Bit der Variablen eine 1 beinhaltet, egal was in den 
anderen 15Bit steht!

T.S.

von bitvergleich (Gast)


Lesenswert?

danke!

...Die Leerzeichen habe ich nur deshalb drin, um einfacher den Überblick 
zu behalten. Die kommen natürlci noch raus.

Wie genau funkktioniert die Methode mit dem Define und dem Bitschieben

if (Variable_16Bit & ( 1 << TESTBIT))

?


Wie muss ich mir dies in einzelnen Schritten aufgelöst vorstellen?

mfg

von Thorsten S. (Gast)


Lesenswert?

die 1 wird um "TESTBIT" anzahl bits nach links geschoben und dann UND 
verknüpft.

übrigens, wenn man Zahlen zuweisen möchte, kann man auch die 
Schreibweise:

0xA03 nehmen, damit lässt sich in c gut arbeiten und man sieht schnell 
welche Bitkombination das ist.

T.S:

von Stephan (Gast)


Lesenswert?

Da reicht ein 2-Zeiler

MOV A, Variable_Low (falls nicht eh schon vorhanden)
JB A,0,Ziel

von Ralf G. (ralg)


Lesenswert?

Thorsten S. schrieb:
> 0xA03 nehmen, damit lässt sich in c gut arbeiten und man sieht schnell
> welche Bitkombination das ist.

Find ich eben nicht.

bitvergleich schrieb:
> Wie genau funkktioniert die Methode mit dem Define und dem Bitschieben

Dass du auf dieses Bit testest, hat ja sicher einen Grund. 'Diesem 
Grund' gibt man einfach einen Namen. z.B.:
1
#define BIT_LED1          0
2
#define BIT_LED2          1
3
#define BIT_SONSTNOCHWAS  2

Selbstverständlich kann man auch gleich 1, 2, 4, ... vergeben. Aber die 
Registerbits im AVR sind auch so beschrieben. Da ist es einheitlicher.

von Karl H. (kbuchegg)


Lesenswert?

bitvergleich schrieb:

> Wie genau funkktioniert die Methode mit dem Define und dem Bitschieben

> Wie muss ich mir dies in einzelnen Schritten aufgelöst vorstellen?


Genau so wie es dort steht.

Nimm eine binäre 1

   0000 0000 0000 0001

und schiebe die entsprechend oft nach links. Schiebst du 0 mal, dann 
bleibt die 1 an dieser Stelle (also ein 1 Bit an der Bitposition 0). 
Schiebst du 1 mal

   0000 0000 0000 0001 << 1

dann erhältst du

   0000 0000 0000 0010

also ein 1 Bit  an der Bitposition 1 (bei 0 anfangen zu zählen). 
Schiebst du 2 mal

   0000 0000 0000 0001 << 2

dann erhältst du

   0000 0000 0000 0100

also ein 1 Bit an der Bitposition 2. Schiebst du 3 mal


   0000 0000 0000 0001 << 3

dann erhältst du

   0000 0000 0000 1000

also ein 1 Bit an der Bitposition 3

usw. usw.

Ergo: Es funktioniert genau so, wie es dort steht.
(1 << Nummer)
liefert einen Integer der genau an der Bitposition 'Nummer' ein 1 Bit 
hat und ansonsten lauter 0 Bits.
Wie das dann mit dem & weitergeht, scheinst du ja schon durchschaut zu 
haben.

von Hannes (Gast)


Lesenswert?

@bitvergleich

>>man sieht schnell

ist natürlich Übungssache.

>>Ralf:Find ich eben nicht.

nicht für jeden geeignet.

T.S:

Beispiel:

0x80 entspr.: b 1000 0000
0x04          b 0000 0100
0x20          b 0010 0000

etc...

besser als:

128 entspr.: b 1000 0000
4            b 0000 0100
32           b 0010 0000

wie ich finde, weil ein bitbezug da ist. Man muss nur die Ziffern 0-9 
und A-F kennen, und kann beliebig große Variablen übersichtlich füllen 
und Abfragen und auch schneller ändern.

von Ralf G. (ralg)


Lesenswert?

Hannes schrieb:
> und kann beliebig große Variablen übersichtlich füllen
> und Abfragen und auch schneller ändern.

Na jaaa...,

ich ändere nur den Wert im #define und das komplette Programm ist 
angepasst!

von Karl H. (kbuchegg)


Lesenswert?

Hannes schrieb:
> @bitvergleich
>
>>>man sieht schnell
>
> ist natürlich Übungssache.

Genau.
Das dauert auch nicht lange, bis man die Binärdarstellungen der 16 
Hex-Ziffern auswendig kann, zumal es da ein paar Eselsbrücken gibt.

Alle ungeraden Zahlen haben an der Bitposition 0 logischerweise eine 1
Von den Ziffern 0 bis 9 weiß jeder welche Ziffer gerade bzw. ungerade 
ist.

Die 2-er Potenzen: 1, 2, 4, 8 kennt man auch ganz schnell. Nur 1 Stück 1 
Bit an den 4 möglichen Positionen.

Die Zahlen vor den 2-er Potenzen: 1, 3, 7, F sind auch einfach: lauter 1 
Bits, mit wachsender Länge. F merkt man sich sowieso leicht, genauso wie 
1. Bleiben nur noch 7 und 3, die man aber auch nach dem 3. mal sehen 
auswendig kann.

5 und 9 sind auch so Sonderfälle, die man schnell lernt: 1 .. Anzahl 0en 
dazwischen, und wieder eine 1.

A merkt man sich auch leicht. A ist dezimal 10. Zweimal "10" 
hintereinander, also 1010 und schon hat man das Bitmuster für A

Lediglich B, C, D muss ich auch immer mit den Fingern abzählen, wobei 
ich bei A anfange und einfach im Kopf die Binäraddition mit den 
Überträgen  mache.

   0000   0   trivial
   0001   1   trivial
   0010   2   trivial, 2-er Potenz
   0011   3   leicht gemerkt, die nächste ungerade Zahl nach 2
   0100   4   trivial, 2-er Potenz
   0101   5   immer abwechselnd
   0110   6   4+2, merkt man sich leicht
   0111   7   das ist 1 vor 8, also alle Bits unter '8' auf 1
   1000   8   trivial, 2-er Potenz
   1001   9   Symetrie, bzw. die nächste ungerade nach 8
   1010   A   zweimal die 10
   1011   B   mach ich zumindest durch Weiterzählen von A
   1100   C   mach ich zumindest durch Weiterzählen von A
   1101   D   mach ich zumindest durch Weiterzählen von A
   1110   E   irgendwann mal verinnerlicht, 1 vor F
   1111   F   trivial, Gegenteil von 0

von Hannes (Gast)


Lesenswert?

>>und das komplette Programm ist angepasst!

Das ist doch eine Eigenschaft des defines und hat nichts mit der 
Zahlendarstellung um die es mir ging zu tun. :-)

Jede Methode hat seinen Vorteil.

Die Shift Methode ist gut wenn man nur ein Bit behandeln will :-) da man 
die Bitnummer angeben kann :-)

Die Eingabe als Hex ist für alle komplexen Masken und Abfragen eine 
übersichtlere als die dezimale.

Man kann natürlich auch Shift bedingungen "verodern".

#define X1 2
#define X2 1

(1<<X1)|(1<<X2)

je nach Anwendungsfall kann

#define X1X2 0x6

übersichtlicher sein.

Ich wollte nur darauf hinweisen....

von ET-Tutorials (Gast)


Lesenswert?

Ich habe dazu ein Video gedreht:
http://et-tutorials.de/1908/bitweise-manipulation/

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.