Forum: PC-Programmierung Funktion ^= Operator


von OP (Gast)


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)


Lesenswert?

variable = variable xor 0x01

von Dirk B. (dirkb2)


Lesenswert?

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

Das Bit 0 (mit der Wertigkeit 1) wird invertiert

von Programmierer (Gast)


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)


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)


Lesenswert?

Programmierer schrieb:
> und ^ ist die bitweise Version von ...?

!=

von Programmierer (Gast)


Lesenswert?

Korrekt ;-)

von Yalu X. (yalu) (Moderator)


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:

1
  x   y   x xor y
2
――――――――――――――――――
3
 =0  =0      0
4
 =0  ≠0      1
5
 ≠0  =0      1
6
 ≠0  ≠0      0
7
――――――――――――――――――

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

: Bearbeitet durch Moderator
von Bartosz B. (bartosz)



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)


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)


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
1
key_state ^= i;

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

von Bartosz B. (bartosz)


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)


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)


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)


Lesenswert?

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

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

von Christian M. (Gast)


Lesenswert?

Dirk B. schrieb:
> 0x01

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

Gruss Chregu

von (prx) A. K. (prx)


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. (Gast)


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 (prx) A. K. (prx)


Lesenswert?

In welchem Standard wurde eigentlich 0b01 definiert?

von Nick M. (Gast)


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 (prx) A. K. (prx)


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)


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 (prx) A. K. (prx)


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)


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 (prx) A. K. (prx)


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)


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:
1
my_time = ts.tv_sec * 1000000000ULL + ts.tv_nsec;
Ist das jetzt die richtige Anzahl Nullen?
Wobei ich in einem solchen Fall dann schreibe:
1
my_time = ts.tv_sec * 1000 * 1000 * 1000ULL + ts.tv_nsec;

: Bearbeitet durch User
von Christian M. (Gast)


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)


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 (prx) A. K. (prx)


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)


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:
1
cat x.c
2
#include <stdio.h>
3
int main()
4
{
5
  int a = 0b0100'0010;
6
  printf("%d\n", a);
7
}
8
$ gcc -xc++ x.c && ./a.out 
9
66

Binary nebst Separator

leo

von (prx) A. K. (prx)


Lesenswert?

leo schrieb:
> Geht ja, seit c++14:

Na endlich.

von Kaj (Gast)


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 ;)

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.