mikrocontroller.net

Forum: PC-Programmierung Funktion ^= Operator


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von OP (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

Kann mir hier jemand die Funktion von dem ^= Operator erklären ?

Habe einen Code gesehen den ich leider nicht mehr vorliegen habe wo der 
benutzt wurde in etwa so meine ich :

Variable ^= 0x01

Vielen Danke schonmal.

von schobbejack (Gast)


Bewertung
3 lesenswert
nicht lesenswert
variable = variable xor 0x01

von Dirk B. (dirkb2)


Bewertung
0 lesenswert
nicht lesenswert
Zumindest in C und Abarten ist es die Kurzschreibweise für
Variable = Variable ^ 0x01; // ^ ist Exklusiv-Oder oder XOR

Das Bit 0 (mit der Wertigkeit 1) wird invertiert

von Programmierer (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Und jetzt das lustige Quiz:

& ist die bitweise Version von &&,
| ist die bitweise Version von ||,
~ ist die bitweise Version von !,
und ^ ist die bitweise Version von ...?

von Sebastian R. (sebastian_r569)


Bewertung
0 lesenswert
nicht lesenswert
Programmierer schrieb:
> und ^ ist die bitweise Version von ...?

Ich würde sagen: von !=

Logisches XOR müsste doch ein ungleich sein, oder?

von Dirk B. (dirkb2)


Bewertung
0 lesenswert
nicht lesenswert
Programmierer schrieb:
> und ^ ist die bitweise Version von ...?

!=

von Programmierer (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Korrekt ;-)

von Yalu X. (yalu) (Moderator)


Bewertung
0 lesenswert
nicht lesenswert
Programmierer schrieb:
> und ^ ist die bitweise Version von ...?

Von ^ gibt es in C kein logisches Äquivalent. Die Wertetabelle dafür
sähe (analog zu && und ||) so aus:

  x   y   x xor y
――――――――――――――――――
 =0  =0      0
 =0  ≠0      1
 ≠0  =0      1
 ≠0  ≠0      0
――――――――――――――――――

2 xor 1 sollte also 0 (false) ergeben, weil beide Operenden von null
verschieden (true) sind.

: Bearbeitet durch Moderator
von Bartosz B. (bartosz)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
@OP (Gast)
ich hab uns mal schnell etwas programmiert, was das verdeutlicht.

von links nach rechts:
1.) Originalzahl 2.)in binär 3.) mit ^= bearbeitet 4.) dessen binär


An die anderen: wozu braucht man das konkret?

LG

von PittyJ (Gast)


Bewertung
1 lesenswert
nicht lesenswert
Man kann schnell z.B. einzelne Bits invertieren

a = a ^ 8
Invertiert das Bit 3, und lässt alles andere gleich.


Benutzt auch in CRC-Berechnungen, bei Verschlüsselungen.

Und man kann auch einen swap ohne Hilfsvariable machen:
https://en.wikipedia.org/wiki/XOR_swap_algorithm

von Programmierer (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Yalu X. schrieb:
> Von ^ gibt es in C kein logisches Äquivalent.

Das ist jetzt aber sehr pingelig :) Wenn man boolesche Datentypen nimmt 
(bool aus stdbool.h, oder einfach C++), schon. Oder halt mit "!!" vor 
dem Wert.

Bartosz B. schrieb:
> An die anderen: wozu braucht man das konkret?

z.B. bei P.D.'s Entprellroutine:
https://www.mikrocontroller.net/articles/Entprellung#Komfortroutine_.28C_f.C3.BCr_AVR.29
key_state ^= i;

Damit kann man einen ganzen Satz an Bits auf einmal negieren oder eben 
XOR-en.

von Bartosz B. (bartosz)


Bewertung
0 lesenswert
nicht lesenswert
PittyJ schrieb:

> Benutzt auch in CRC-Berechnungen, bei Verschlüsselungen.
>
> Und man kann auch einen swap ohne Hilfsvariable machen:
> https://en.wikipedia.org/wiki/XOR_swap_algorithm


Programmierer (Gast)

> z.B. bei P.D.'s Entprellroutine:

Danke!

von Yalu X. (yalu) (Moderator)


Bewertung
0 lesenswert
nicht lesenswert
Programmierer schrieb:
> Yalu X. schrieb:
>> Von ^ gibt es in C kein logisches Äquivalent.
>
> Das ist jetzt aber sehr pingelig :) Wenn man boolesche Datentypen nimmt
> (bool aus stdbool.h, oder einfach C++), schon. Oder halt mit "!!" vor
> dem Wert.

In diesem Fall gibt es keinen Unterschied zwischen dem bitweisen und dem
logischen XOR, weswegen sich der logische Operator erübrigt.

von Rolf M. (rmagnus)


Bewertung
0 lesenswert
nicht lesenswert
Yalu X. schrieb:
> Programmierer schrieb:
>> Yalu X. schrieb:
>>> Von ^ gibt es in C kein logisches Äquivalent.
>>
>> Das ist jetzt aber sehr pingelig :) Wenn man boolesche Datentypen nimmt
>> (bool aus stdbool.h, oder einfach C++), schon. Oder halt mit "!!" vor
>> dem Wert.
>
> In diesem Fall gibt es keinen Unterschied zwischen dem bitweisen und dem
> logischen XOR, weswegen sich der logische Operator erübrigt.

Das ist aber beim AND und OR auch nicht anders, bis darauf, dass diese 
noch eine short-circuit-evaluation machen.
Man muss für ein logisches exklusives Oder dann an Stelle von  a != b 
lieber !!a != !!b schreiben, wenn man nicht garantieren kann, dass die 
Werte nur 0 oder 1 sein können.

von fop (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Dirk B. schrieb:
> Programmierer schrieb:
>> und ^ ist die bitweise Version von ...?
>
> !=

Hm, auf den ersten Blick ja. Aber ich habe so meine Zweifel.
( (a) != (b) )
müsste ja dann die selben Ergebnisse liefern wie
(!! ((!!(a)) ^ (!!(b))))
Was aber für a=4 und b=2 nicht hin kommt.

von Christian M. (Firma: magnetmotor.ch) (chregu) Benutzerseite


Bewertung
-1 lesenswert
nicht lesenswert
Dirk B. schrieb:
> 0x01

Ich würde jetzt sowas als %00000001 schreiben. Ist überschaubarer wenn 
andere/mehrere Bits involviert sind!

Gruss Chregu

von A. K. (prx)


Bewertung
0 lesenswert
nicht lesenswert
Christian M. schrieb:
>> 0x01
>
> Ich würde jetzt sowas als %00000001 schreiben.

In C?

> Ist überschaubarer wenn andere/mehrere Bits involviert sind!

0x8000000000000001 auch?

von Nick M. (muellernick)


Bewertung
0 lesenswert
nicht lesenswert
Christian M. schrieb:
> Ich würde jetzt sowas als %00000001 schreiben.

Also ich würde nicht mal b00000001 schreiben. Ich komm bei solchen 
Zahlen noch nicht ins Trudeln. ;-)

von A. K. (prx)


Bewertung
0 lesenswert
nicht lesenswert
In welchem Standard wurde eigentlich 0b01 definiert?

von Nick M. (muellernick)


Bewertung
0 lesenswert
nicht lesenswert
A. K. schrieb:
> In welchem Standard wurde eigentlich 0b01 definiert?

Ich glaub das ist seit C99 offiziell. Hab das Buch aber nicht da.

von A. K. (prx)


Bewertung
0 lesenswert
nicht lesenswert
Nick M. schrieb:
>> In welchem Standard wurde eigentlich 0b01 definiert?
>
> Ich glaub das ist seit C99 offiziell.

Weder in C11 (N1570) noch in C++11 (N4659) ist es drin.

: Bearbeitet durch User
von Rolf M. (rmagnus)


Bewertung
0 lesenswert
nicht lesenswert
Nick M. schrieb:
> A. K. schrieb:
>> In welchem Standard wurde eigentlich 0b01 definiert?
>
> Ich glaub das ist seit C99 offiziell. Hab das Buch aber nicht da.

Nein, in C ist das kein offizielles Standard-Feature, weder in C99, noch 
danach. In C++ gibt es das aber seit C++14.

von A. K. (prx)


Bewertung
0 lesenswert
nicht lesenswert
A. K. schrieb:
> Weder in C11 (N1570) noch in C++11 (N4659) ist es drin.
                                      N3337

Im GCC ist es allerdings schon lange drin. Nonstandard.

: Bearbeitet durch User
von Rolf M. (rmagnus)


Bewertung
0 lesenswert
nicht lesenswert
Nick M. schrieb:
> Christian M. schrieb:
>> Ich würde jetzt sowas als %00000001 schreiben.
>
> Also ich würde nicht mal b00000001 schreiben. Ich komm bei solchen
> Zahlen noch nicht ins Trudeln. ;-)

Ich finde da auch die hexadezimale Schreibung übersichtlicher, als 
endlose Kollonen von 0en abzählen zu müssen. Wenn man mal ein bisschen 
damit gearbeitet hat, passiert die Zuordnung von Hex-Ziffern zu den 
entsprechenden Bitmustern auch ganz automatisch.

von A. K. (prx)


Bewertung
1 lesenswert
nicht lesenswert
Rolf M. schrieb:
> Ich finde da auch die hexadezimale Schreibung übersichtlicher, als
> endlose Kollonen von 0en abzählen zu müssen.

Was bei 64 Bits aber auch hex keinen Spass macht. Nett wäre z.B.
  0x8000_0000_0000_0001

von Rolf M. (rmagnus)


Bewertung
0 lesenswert
nicht lesenswert
Kann sogar auch mal in dezimal passieren, z.B. wenn man eine struct 
timespec mit Sekunden und Nanosekunden in einen einzelnen 
64-Bit-Nanosekunden-Timestamp konvertieren will:
my_time = ts.tv_sec * 1000000000ULL + ts.tv_nsec;
Ist das jetzt die richtige Anzahl Nullen?
Wobei ich in einem solchen Fall dann schreibe:
my_time = ts.tv_sec * 1000 * 1000 * 1000ULL + ts.tv_nsec;

: Bearbeitet durch User
von Christian M. (Firma: magnetmotor.ch) (chregu) Benutzerseite


Bewertung
-2 lesenswert
nicht lesenswert
A. K. schrieb:
> In C?

Es wurde nirgends gesagt, dass es C sein muss!

Und kann C denn kein binär? Ein Grund mehr das zu meiden...

Rolf M. schrieb:
> endlose Kollonen von 0en

Bin ich gewohnt vom Forum hier :-)

A. K. schrieb:
> 64 Bits aber auch hex keinen Spass mach

90% der XOR Anwendungen betreffen eh nur Mikrocontroller.

Gruss Chregu

von Rolf M. (rmagnus)


Bewertung
1 lesenswert
nicht lesenswert
Christian M. schrieb:
> A. K. schrieb:
>> In C?
>
> Es wurde nirgends gesagt, dass es C sein muss!
>
> Und kann C denn kein binär? Ein Grund mehr das zu meiden...

Das stimmt. Das ist tatsächlich ein weiterer Grund, diese 
Binärdarstellung zu meiden. Aber Hauptgrund bleibt die Unleserlichkeit.

von A. K. (prx)


Bewertung
0 lesenswert
nicht lesenswert
Christian M. schrieb:
> Es wurde nirgends gesagt, dass es C sein muss!

Gibts eine Sprache mit xor assign op und deutlich oberhalb von 
Assembler, in der %01 eine binäre Zahl ist?

: Bearbeitet durch User
von leo (Gast)


Bewertung
0 lesenswert
nicht lesenswert
A. K. schrieb:
> Was bei 64 Bits aber auch hex keinen Spass macht. Nett wäre z.B.
>   0x8000_0000_0000_0001

Geht ja, seit c++14:
cat x.c
#include <stdio.h>
int main()
{
  int a = 0b0100'0010;
  printf("%d\n", a);
}
$ gcc -xc++ x.c && ./a.out 
66

Binary nebst Separator

leo

von A. K. (prx)


Bewertung
0 lesenswert
nicht lesenswert
leo schrieb:
> Geht ja, seit c++14:

Na endlich.

von Kaj (Gast)


Bewertung
0 lesenswert
nicht lesenswert
A. K. schrieb:
> Was bei 64 Bits aber auch hex keinen Spass macht. Nett wäre z.B.
>   0x8000_0000_0000_0001
In Rust geht das genau so ;)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.