Hallo,
ich möchte Abfragen ob ein bestimmter Bit gesetzt ist oder nicht. Den
Artikel zu Bitmanipulation habe ich gelesen, doch leider hilft er mir
nicht genau weiter.
Ich habe folgenden Code
1
#define RF_ACK1 0x04
2
#define RF_ACK2 RF_ACK1 | 0x00
3
#define RF_ACK3 RF_ACK2 | 0x01
4
#define RF_ACK0 RF_ACK2 | 0x01
5
6
if(RF_ACK3&RF_ACK0)// soll true
7
i2clcd_printlr(1,1,"if 1");
8
9
if(RF_ACK2&RF_ACK3)// soll false
10
i2clcd_printlr(2,1,"if 2");
Nun bekomme ich für beide IF's ein true. Leider nicht genau das, was ich
erwarte. Denn RF_ACK3 ist nicht RF_ACK0, also ertwarte ich ein false.
Was genau mache ich falsch und wie löse ich es am besten.
Chris schrieb:> Nun bekomme ich für beide IF's ein true.
Jep.
Der Ausdruck wird ausgewertet und wenn da etwas ungleich 0 herauskommt,
dann gilt das als TRUE
> erwarte. Denn RF_ACK3 ist nicht RF_ACK0
Dein Vergleich ist ja auch nicht auf Gleichheit. Du verundest 2 Zahlen.
> Was genau mache ich falsch und wie löse ich es am besten.
Spiel Präprozessor und mach die Textersetzung. Da bleibt dir dann ein
Ausdruck über in dem nur noch Zahlen und Verknüpfungen vorkommen. Den
wertest du dann mal händisch aus. Und dann macht es irgendwann klack und
du verstehst, die dein Egrebnis zu Stande kommt.
if(RF_ACK3 & RF_ACK0)
Textersetzung: Statt RF_ACK3 setzt du den Text RF_ACK2 | 0x01 ein
if (RF_ACK2 | 0x01 & RF_ACK0)
nächste Textersetzung: statt RF_ACK0 setzt du den Text RF_ACK2 | 0x01
ein
if (RF_ACK2 | 0x01 & RF_ACK2 | 0x01)
nächste Textersetzung: anstelle von RF_ACK2 setzt du RF_ACK1 | 0x00 ein
if (RF_ACK1 | 0x00 | 0x01 & RF_ACK1 | 0x00 | 0x01)
nächste Textersetzung: anstelle von RF_ACK1 setzt du 0x04 ein
if (0x04 | 0x00 | 0x01 & 0x04 | 0x00 | 0x01)
und jetzt wertest du den Ausdruck mit den C Regeln aus. Was kommt raus?
Chris schrieb:> Nun bekomme ich für beide IF's ein true. Leider nicht genau das, was ich> erwarte.
Das blöde ist, dass Computer immer das machen, was man ihnen sagt und
nicht unbedingt das, was man erwartet.
Karl Heinz Buchegger schrieb:> und jetzt wertest du den Ausdruck mit den C Regeln aus. Was kommt raus?
ich weiß nicht genau was du mit C Regeln meinst.
Bekomme if(0x05 & 0x05) oder halt (101 & 101)
Chris schrieb:> Karl Heinz Buchegger schrieb:>> und jetzt wertest du den Ausdruck mit den C Regeln aus. Was kommt raus?>> ich weiß nicht genau was du mit C Regeln meinst.>> Bekomme if(0x05 & 0x05) oder halt (101 & 101)
Und?
Was ist das Ergebnis wenn du die beiden verundest?
Ja, das ist quasi die Fortführung von
Beitrag "C: Funktion mit #define als Platzhalter"
Immer tüchtig #define hinschreiben, damit man schon nach ein paar
Codezeilen (selbst) nimmer durchsteigt !
Und unbedingt auch immer die Klammern weglassen, besonders wenn
unterschiedliche Operatoren im Spiel sind.
wenn ich das richtig mache ist es 0b101.
Karl Heinz Buchegger schrieb:> Der Ausdruck wird ausgewertet und wenn da etwas ungleich 0 herauskommt,>> dann gilt das als TRUE
OK ich verstehe warum es nun true liefert. Wie genau muss ich nun
abfragen, damit es nur true liefert, wenn die Bits gesetzt sind?
Erich schrieb:> Immer tüchtig #define hinschreiben, damit man schon nach ein paar>> Codezeilen (selbst) nimmer durchsteigt !>> Und unbedingt auch immer die Klammern weglassen, besonders wenn>> unterschiedliche Operatoren im Spiel sind.
Mein Code ist länger !!!
Sollte oben nur mein Problem erläutern. Und welche Klammern vermisst du,
damit du auch produktives zum Thema schreiben kannst?
Chris schrieb:> wenn ich das richtig mache ist es 0b101.>> Karl Heinz Buchegger schrieb:>> Der Ausdruck wird ausgewertet und wenn da etwas ungleich 0 herauskommt,>>>> dann gilt das als TRUE>> OK ich verstehe warum es nun true liefert. Wie genau muss ich nun> abfragen, damit es nur true liefert, wenn die Bits gesetzt sind?
Wenn welche Bits gesettz sind?
Wo sind diese Bits gesetzt?
Bis jetzt sind das alles ja nur konstante Zahlen. Da kannst du
genausogut auch
if( 1 )
hinschreiben
PS:
Bist du sicher, dass
#define RF_ACK3 RF_ACK1 | 0x01
#define RF_ACK0 RF_ACK1 | 0x01
RF_ACK3 und RF_ACK0 exakt die gleiche Binärdarstellung haben sollen?
Wenn ja: Wazu gibt es dann RF_ACK3 überhaupt?
Chris schrieb:> Erich schrieb:>> Immer tüchtig #define hinschreiben, damit man schon nach ein paar>>>> Codezeilen (selbst) nimmer durchsteigt !>>>> Und unbedingt auch immer die Klammern weglassen, besonders wenn>>>> unterschiedliche Operatoren im Spiel sind.>> Mein Code ist länger !!!
umso schlimmer.
Was bei kurzen Programmen unter Zusammenkneifen aller Augen (inklusive
Hühneraugen) noch angehen mag, ist bei längeren Programmen der
Dolchstoss in den Rücken des Programmierers.
> Sollte oben nur mein Problem erläutern. Und welche Klammern vermisst du,> damit du auch produktives zum Thema schreiben kannst?
Denk mal über folgendes nach
1
#define TWICE(x) 2*x
2
3
...
4
inti=5;
5
intj=TWICE(i+3);
welchen Wert hat j?
Ist das intuitiv? Würde man diess Ergebnis erwarten, wenn man das Makro
nicht kennt und nur den Makronamen weiß?
Weiters denke über folgendes nach
1
#define ADD_TWO(x) x+2
2
3
...
4
inti=5;
5
intj=2*ADD_TWO(i)
Welchen Wert hat j?
Ist das intuitiv? Würde man diess Ergebnis erwarten, wenn man das Makro
nicht kennt und nur den Makronamen weiß?
Stefan T. schrieb:> Ja das mit den Konstanten war schon soweit richtig, ich wollte nur eine> kleine Testumgebung. Zusammengefasst sollte es so aussehen>>
1
>#defineRF_T0x04
2
>#defineRF_ACK_YESRF_T|0x00// 0b00000100
3
>#defineRF_ACK_NORF_T|0x01// 0b00000101
4
>
5
>if(0b00100100&RF_ACK_YES)// soll true
6
>i2clcd_printlr(1,1,"if t");
7
>
8
>if(0b00100100&RF_ACK_NO)// soll false
9
>i2clcd_printlr(2,1,"if .");
10
>
>> Der Wert 0b00100100 wird übergeben und nun geprüft ob bits RF_ACK_YES> oder ob RF_ACK_NO gesetzt sind.
Welches ist das Bit RF_ACK_YES?
Die beiden Konstanten
> #define RF_ACK_YES RF_T | 0x00 // 0b00000100> #define RF_ACK_NO RF_T | 0x01 // 0b00000101
müssen sich ja in 2 Bits unterscheiden.
In der einen Konstante ist das eine Bit gesetzt und das andere gelöscht
und in der anderen Konstante genau umgekehrt
Aber bei deinen Konstanten ist das nicht so
Da ist nur das Bit 0 unterschiedlich
Ist es gesetzt, dann: NO
ist es gelöscht, dann: YES
aber mehr kann ich aus dem nicht herauslesen. Insbesondere ergibt diese
Frage
> ob bits RF_ACK_YES> oder ob RF_ACK_NO gesetzt sind.
keinen Sinn, weil es nun mal kein spezifisches Bit für YES gibt, welches
gesetzt sein könnte.
Ich denke, deine Fragestellung stimmt schon von Anfang an nicht.
Du willst gar nicht wissen, ob irgendwelche Bits gesetzt sind oder
nicht.
Was du wissen willst: Wenn man einen Wert so manipuliert, dass nur die
untersten 4 Bits übrig bleiben und alle anderen 0 sind, bleibt dann der
Wert RF_ACK_YES bzw der Wert RF_ACK_NO übrig. Oder anders ausgedrückt:
Welchen Wert aus deinen möglichen Werten ist in den untersten 4(?) Bits
kodiert
if( ( Wert & 0x0F ) == RF_ACK_YES )
....
if( ( Wert & 0x0F ) == RF_ACK_NO )
....
oder auch
switch ( Wert & 0x0F ) {
case RF_ACK_YES:
....
break;
case RF_ACK_NO:
....
break;
Alles in allem wieder mal ein Musterbeispiel dafür, dass man am besten
hier im Forum von Anfang an die Karten auf den Tisch legt und nicht um
den heißen Brei herumredet mit Analogieprogrammen die dann ganz was
anderes zeigen als das Problem, das man eigentlich hat.
Es ist immer gut mit einer exakten Problemstellung zu fragen, anstelle
Hilfe zu einer Lösung zu suchen, die von Anfang an gar nicht dazu
geeignet ist das eigentliche Problem zu lösen.