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.
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
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 ...?
Programmierer schrieb: > und ^ ist die bitweise Version von ...? Ich würde sagen: von != Logisches XOR müsste doch ein ungleich sein, oder?
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
@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
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
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.
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!
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.
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.
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.
Dirk B. schrieb: > 0x01 Ich würde jetzt sowas als %00000001 schreiben. Ist überschaubarer wenn andere/mehrere Bits involviert sind! Gruss Chregu
Christian M. schrieb: >> 0x01 > > Ich würde jetzt sowas als %00000001 schreiben. In C? > Ist überschaubarer wenn andere/mehrere Bits involviert sind! 0x8000000000000001 auch?
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. ;-)
A. K. schrieb: > In welchem Standard wurde eigentlich 0b01 definiert? Ich glaub das ist seit C99 offiziell. Hab das Buch aber nicht da.
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
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.
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
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.
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
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
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
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.
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
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.