Forum: Compiler & IDEs if( message>>16 == 0xF084 ) vergleichen ohne verändern?


von Danny P. (Gast)


Lesenswert?

Hey zusammen,

der Betreff zeigt denke ich deutlich, was ich machen möchte, nur nach 
dem ist message natürlich verändert.

Gibt es eine elegantere Lösung, als message vorher in eine andere 
Variable zu kopieren? Bzw. i = message>>16; ?


Danke und Gruß
Danny

von Peter II (Gast)


Lesenswert?

Danny P. schrieb:
> der Betreff zeigt denke ich deutlich, was ich machen möchte, nur nach
> dem ist message natürlich verändert.

warum sollte sich message ändern?

von Ralf (Gast)


Lesenswert?

Die Variable ändert sich nicht, da du keine Zuweisung, sondern einen 
Vergleich machst.

Ralf

von Danny P. (Gast)


Lesenswert?

ja... mit dem == mache ich einen Vergleich.

Aber das message>>16 scheint mit die message dauerhaft zu verschieben

von Peter II (Gast)


Lesenswert?

Danny P. schrieb:
> Aber das message>>16 scheint mit die message dauerhaft zu verschieben

wie kommst du darauf?

von Danny P. (Gast)


Lesenswert?

funktiniert nicht:
1
if(message>>16==0x9FA0){
2
3
4
      if(message==0xB748) puts("Mute\r\n");
5
6
      if(message==0x8778) puts("Power\r\n");
7
8
                       }


funktioniert:
1
uint16_t q1 = message>>16;
2
uint16_t q2 = message;
3
4
5
if(q1==0x9FA0){
6
7
8
      if(q2==0xB748) puts("Mute\r\n");
9
10
      if(q2==0x8778) puts("Power\r\n");
11
12
                       }

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Schalt mal alle Warnungen an (-Wall -Wextra), dann wird dir der
Compiler sagen, dass er im ersten Fall den Code innerhalb der
inneren if-Abfragen gar nicht erreichen kann.

Wenn Message nämlich 0x9FA0XXXX ist (also die oberen 16 Bit sind
0x9FA0), dann kann sie folglich nicht gleichzeitig bspw.
0x0000B748 sein.

von Tobias F. (coldtobi)


Lesenswert?

wie ist den message deklariert?

von Stefan P. (form)


Lesenswert?

Wird message vielleicht in einem Interrupt verändert?

von Thomas K. (muetze1)


Lesenswert?

Scherzkeks. Du hast q1 und q2 als 16 Bit Werte definiert. Damit wirfst 
du alle anderen Bits weg.

D.h. deine beiden letzten IF Abfragen sollten eigentlich auf

      if(q2==0x9FA0B748) puts("Mute\r\n");

      if(q2==0x9FA08778) puts("Power\r\n");

lauten, da du einen (vermutlich) 32 Bit Wert vergleichen willst und 
deine erste IF Abfrage sagt aus, dass die oberen 16 Bit dabei den Wert 
0x9FA0 haben sollten.

/EDIT: Zu langsam, Jörg Wunsch hat schon alles geschrieben...

von Danny P. (Gast)


Lesenswert?

@Jörg: wie bringe ihn denn dazu das message>>16 als uint16_t zu 
interpretieren?   (uint16_t)message>>16 funktiniert auch nicht

von Danny P. (Gast)


Lesenswert?

@Thomas: message enthält ein IR-Signal einer Fernbedienung. Mein Gedanke 
war zunächst die oberen beiden Byte zu ckecken (richtige FB?) und erst 
dann die einzelnen Tasten (unteren beiden Bytes)

von Danny P. (Gast)


Lesenswert?

auch auf die Gefahr hin, Euch zu nerven ;)

wenn mein als uint32_t initialisiertes message 0x9FA0B748 beinhaltet und 
ich message>>16 schreibe, müsste das Ergebnis 0x00009FA0 lauten.
Aber ob ich nun 0x00009FA0 oder 0x9FA0 schreibe, ist das nicht egal, 
schliesslich wird doch rechtsbündig interpretiert?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Du guckst einfach immer noch auf die falsche Stelle.  Dein
“message >> 16” funktioniert prächtig.  Es ist der Rest, der nicht
funktioniert.

Nimm doch mal die Tomaten von den Augen. ;-)

Du musst in den „inneren“ if-Abfragen schreiben
1
  if ((message & 0xffff) == 0xB748) { ... }

oder, wie Thomas in Beitrag "Re: if( message>>16 == 0xF084 ) vergleichen ohne verändern?"
schreibt, den Vergleich sofort als 32-Bit-Zahl aufschreiben und es dem
Compiler überlassen, das ggf. bytweise zu optimieren.

von Thomas K. (muetze1)


Lesenswert?

Wobei ich bei dem Code in meinem Beitrag natürlich "message" anstatt 
"q2" in den IF Abfragen hätte schreiben müssen. Vllt. führt dies auch zu 
Verständnisschwierigkeiten.

Aber trotzdem hier mal der Code wie ihn Danny eigentlich wohl will:
1
  if ( message >> 16 == 0x9FA0 )
2
  {
3
    uint16_t lLowWord = message & 0xffff;
4
5
    if ( 0xB748 == lLowWord ) 
6
      puts("Mute\r\n");
7
8
    else if ( 0x8778 == lLowWord ) 
9
      puts("Power\r\n");
10
11
  }

(Das vertauschen der Vergleichswerte hat keinen Einfluß bei den letzten 
beiden IF Abfragen, aber den netten Nebeneffekt eines Compiler Errors, 
wenn man mal ein = vergißt)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Thomas K. schrieb:
> Das vertauschen der Vergleichswerte hat keinen Einfluß bei den letzten
> beiden IF Abfragen, aber den netten Nebeneffekt eines Compiler Errors,
> wenn man mal ein = vergißt

Dafür finde ich es scheußlich zu lesen, da es unseren gewohnten
Gedankenfluss stört.  Das fehlende Gleichheitszeichen warnen die
Compiler wiederum seit einigen Jahren an, sofern man sie lässt.

von Thomas K. (muetze1)


Lesenswert?

Kann ich mir vorstellen - ich für meinen Teil ist es egal vom Lesen. Ich 
erfasse den Termin als Ganzes. Und Warnungen werden oftmals ignoriert 
oder in den Projekteinstellungen/Makefiles ausgeschaltet und sind somit 
nicht zuverlässig. Bei Embarcadero muss man solche Zuweisungen explizit 
klammern um die Warnung zu beseitigen. Alles persönliche Vorlieben halt.

von Arno (Gast)


Lesenswert?

Jörg hat es schon geschrieben, aber ich versuchs nochmal...

Danny P. schrieb:
> wenn mein als uint32_t initialisiertes message 0x9FA0B748 beinhaltet und
> ich message>>16 schreibe, müsste das Ergebnis 0x00009FA0 lauten.

Richtig. Soweit wird es auch funktionieren.

Das verändert aber message nicht, so dass message danach immer noch den 
Wert 0x9fa0b748 hat. Und damit message==0xb748 falsch (also nicht wahr) 
ist.

MfG, Arno

von Danny P. (Gast)


Lesenswert?

Danke Euch allen für die Antworten, nun sind die Tomaten weg von den 
Augen ;)


Aber eine hab ich noch ;)

message hat 0x9fa0b748
Damit ist message==0xb748 (nun auch in meiner Welt) falsch

Gibt es nicht irgend einen Kniff um diese Abfrage direkt als 16 Bit zu 
betrachten?
Wenn ich bspw. einen 16 Bit Wert in eine 8 Bit Variable schreibe, fällt 
das high Byte weg und das low Byte habe ich in der Variable.

Ich meine mal etwas gesehen zu haben in der Form:  ( (uint16_t) if 
message==0xb748)

von Thomas K. (muetze1)


Lesenswert?

wie Jörg und ich schon geschrieben hatten: ausmaskieren

if ( message & 0xffff == 0x1234 )

oder wirklich casten, was in diesem Falle aber eigentlich verschleiert 
was du eigentlich willst. Im Normalfall würde man einen temporary 
anlegen, dort würde es dann zu einer Warnung kommen, weil Informationen 
verloren gehen:

if ( uint16_t(message) == 0x1234 )

Oder wirklich hart casten:

if ( (uint16_t)message == 0x1234 )

Aber wie gesagt, ist nicht unbedingt eine "nette" Art in Sachen 
Lesbarkeit, etc. Es wird einem Leser nicht sofort bewusst, dass dort 
Informationen verloren gehen bzw. Daten verändert werden.

von Danny P. (Gast)


Lesenswert?

aaaaaahh :)    die Erinnerung hat if/uint16_t vertauscht...

Super, dann hab ichs nun geschnallt, vielen Dank nochmal!

von DirkB (Gast)


Lesenswert?

Aber lass das mit dem cast sein.
Nimm das
1
if ( message & 0xffff == 0x1234 )
Das erkennt man auf den ersten Blick.
Auch beim scrollen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

DirkB schrieb:

> Nimm das
>
1
if ( message & 0xffff == 0x1234 )

Lieber nicht. ;-)

Nimm lieber das:
1
if ((message & 0xffff) == 0x1234)

Der ==-Operator bindet nämlich stärker als das bitweise Und (&).

von Thomas K. (muetze1)


Lesenswert?

Ach verdammt, wieder was vergessen. Ich klammere bitweise Operatoren 
(ausgenommen natürlich ~) immer...

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.