Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - XOR mit Set


JSchirrmacher - Di 27.12.11 10:02
Titel: XOR mit Set
Habe zwei Sets die ich miteinander auf Unterschiede untersuchen will, z.B.

type
TFlag = (f1, f2, f3, f4);
TFlags = set of TFlag;

...

var
v1, v2, v3 :TFlags;

...

v1 := [f1, f3];
v2 := [f1, f4];

v3 := v1 XOR v2; // geht nicht

v3 hätte jetzt [f3, f4] als Inhalt

Ich möcht also wissen, welche flags sich geändert haben. Mit den Flags in integern könnte ich das lösen, aber dan habe ich die bequeme Lesbarkeit der Aufzählungen und sets nicht.

Idee?


jaenicke - Di 27.12.11 10:22

Schnellschuss:

Delphi-Quelltext
1:
v3 := (v1 - v2) + (v2 - v1);                    
Vielleicht geht es noch einfacher.


JSchirrmacher - Di 27.12.11 10:34

also funktionieren tut das anscheinend mit

v3 := (v1-v2) + (v2-v1);

aber von Eleganz ist da keine Rede. Denk ich da irgendwie falsch?
Mal gucken, was der Compiler daraus macht.


jaenicke - Di 27.12.11 10:47

Sieht das vielleicht schöner für dich aus? ;-)

Delphi-Quelltext
1:
v3 := v1 + v2 - v1 * v2;                    
Es gibt AFAIK keinen Operator für die Menge der Elemente, die nicht in der Intersektion der beiden Mengen drin sind, also die Summe der Komplemente.


baka0815 - Di 27.12.11 10:52

Mach dir doch eine Funktion aus dem, was Jaenicke schreibt.


Delphi-Quelltext
1:
2:
3:
4:
function Xor(Set1, Set2: TFlags): TFlags;
begin
  Result := (Set1 - Set2) + (Set2 - Set1);
end;


Dann hast du's "eleganter":


Delphi-Quelltext
1:
Flags := Xor(Flags1, Flags2);                    


JSchirrmacher - Di 27.12.11 12:36

Besten Dank für die schnellen Antworten.

Ich liege also mit meiner Lösung richtig. (Man hat ja manchmal das Gefühl das es ganz einfach gehen müsste, aber man findets nicht).

Habe mal in den CPU-Code geguckt, was der Compiler aus dem Ausdruck (v1-v2) + (v2-v1) so macht:

Er macht mit 32bit-Registern 2x AND/NOT und ein OR hinterher, ist also effektiv. Wie so oft darf man in den Delphi-Compiler Vertrauen haben.