Suche logischen xor_operator



  • Und das in C++? Gewagt …



  • Hallo,

    ich weiß, der Thread ist schon etwas älter aber da ich im Prinzip das selbe Problem habe, stelle ich meine Frage hier.

    Im Prinzip bin ich auch auf der Suche nach einem logischen XOR. Allerdings ist bei mir der Grund, dass ich ein XOR auf mehrere Operanden anwenden möchte und eine Schachtelung wie XOR(XOR(a,b),c) ist einfach schwierig zu lesen.

    (a != b != c) dürfte auch zu einigen Verwirrungen führen, zumal ich mir nicht sicher wäre, dass das immer unter allen Umständen funktioniert.

    Gibt es vielleicht eine Möglichkeit einen "Pseudooperators" über ein Define zu erzeugen? Ich habe in die Richtung leider nichts gefunden. Aber im Prinzip suche ich in diesem Zusammenhang nach einem Define o.ä. was z.B. a XOR b auf XorFunction(a,b) abbildet.

    Ansonten könnte man natürlich XOR einfach auf != abbilden, aber ich hätte dabei Bauchschmerzen, da TRUE und FALSE ja immer noch nur Abbildungen auf Eins und Null sind und letztendlich alles ungleich Null einfach wahr ist...

    Oder sehe ich das zu kompliziert und die C/C++-Operatoren && bzw. || funktionieren ebenfalls nur mit Eins und Null?

    Vielleicht hat da ja einer eine Idee oder kann mich einfach schlauer machen 🙂

    Fröhliche Grüße,
    Torge



  • erstmal schauen, wo in der rangfolge der operatoren dein XOR landen soll. vielleicht bei ^? ich machs mal bei ^.

    #define XOR ^foo()^
    

    foo() gibt einen XorProxy zurück und für den XorProxy überladenen operatoren ^ machen den rest.



  • Gibt es eine Bibliothek, die einige zusätzliche logische Operatoren anbietet?

    Warum, das kann man doch aus Not (!), And (&&() und Or(||) nachbilden. Not, And ( und Or) werden gebraucht, da sie eine (minimale) Basis der boolschen Funktionen bilden.

    Naja, den logischen XOR gibt's vermutlich deshalb nicht, weil er keine "Kurzschlusssemantik" ...

    Falsch!



  • knivil schrieb:

    Gibt es eine Bibliothek, die einige zusätzliche logische Operatoren anbietet?

    Warum, das kann man doch aus Not (!), And (&&() und Or(||) nachbilden. Not, And ( und Or) werden gebraucht, da sie eine (minimale) Basis der boolschen Funktionen bilden.

    Or ist völlig nutzlos.



  • Or ist völlig nutzlos.

    Sollte auch in Klammern stehen, aber deswegen ist es nicht zwingend nutzlos. Ich will mein Oder-Ausdruck nicht staendig Mit NAnd und Konstante schreiben. Das logische XOr hat halt Pech, da es selten benutzt wird und deswegen kein Extrawurst bekommt.



  • knivil schrieb:

    Naja, den logischen XOR gibt's vermutlich deshalb nicht, weil er keine "Kurzschlusssemantik" ...

    Falsch!

    Beweise. Und erklär vor allem erstmal welche der beiden zitierten Aussagen falsch sein soll.

    Im Übrigen dürfte man für ein boolsches XOR einfach das binäre xor verwenden können, vorausgesetzt es gibt für true und false jeweis nur eine binäre Darstellung (was meines Wissens der Fall ist, hab aber grad den Standard nicht zur Hand).



  • was spricht nochmal gegen != ?



  • Shade Of Mine schrieb:

    was spricht nochmal gegen != ?

    Ist zu einfach, so wie in deinem Thread ntfs-3g.



  • Shade Of Mine schrieb:

    was spricht nochmal gegen != ?

    es ist nicht a!=b gesucht, sondern bool(a)!=bool(b) oder um das machZuBoolFürMsvcNutzer-idiom !! zu verwenden !!a!=!!b, ohne bool() oder !! wärs zu unsicher, nehmen wir mal !a!=!b. aber das ist den mädels zu schwer zu schreiben oder zu lesen oder so.



  • pumuckl schrieb:

    knivil schrieb:

    Naja, den logischen XOR gibt's vermutlich deshalb nicht, weil er keine "Kurzschlusssemantik" ...

    Falsch!

    Beweise. Und erklär vor allem erstmal welche der beiden zitierten Aussagen falsch sein soll.

    Wie waere es mit Brain.exe. (Rumtrollen kann ich auch). Ausserdem: Es ist genau eine zitierte Aussage.



  • volkard schrieb:

    Or ist völlig nutzlos.

    Also ich finde ja AND völlig nutzlos.



  • pumuckl schrieb:

    Im Übrigen dürfte man für ein boolsches XOR einfach das binäre xor verwenden können, vorausgesetzt es gibt für true und false jeweis nur eine binäre Darstellung (was meines Wissens der Fall ist, hab aber grad den Standard nicht zur Hand).

    soweit ich weiß ist false definiert als 0 und true definiert als nicht 0, also kann true beliebige andere Werte annehmen, in der Regel ist bool einfach 1 Byte, welches dann numerische Werte von 0 bis 255 beinhalten kann, darum sollte man afaik auch immer eine Funktion mit Rückgabetyp so abfragen:

    if(foo())
    

    und nicht

    if(foo() == true)
    

    Denn wenn intern so etwas steht:

    #define false 0
    #define true  1
    

    und du z.B. eine funktion hast, die etwas berechnet und nur true / false für zahl != 0 / == 0 zurückgeben soll, dann hast du:

    bool bar(unsigned char x) {
      return x - 1;
    }
    

    was bei if(bar(5)==true) fälschlicherweise nicht erfüllt werden würde



  • kleiner Nachtrag:

    Im Zuge meiner Beschäftigung mit Mikrocontrollerprogrammierung mit C und C++ bin ich außerdem schon über dieses gestolpert:

    #define false 0x00
    #define true  ~false;
    

    was gleichbedeutend ist mit 255 bei der Betrachtung von bool als vorzeichenloses integrales Byte bzw. mit -1 bei der Betrachtung von bool als vorzeichenbehaftetes integrales Byte, da sämtliche Bits umgekehrt sind dann.



  • @Paul Manns:
    Das ist nur dann der Fall wenn das System keinen Datentyp bool kennt...



  • Shade Of Mine schrieb:

    was spricht nochmal gegen != ?

    nicht viel, mal von Volkards Typen-Bedenken abgesehen die für ^ ja auch zutreffen. Das einzige was mir noch einfällt hat mit Operatorpräzedenz zu tun:

    if (a == 5 || b == 7); //tut das was man erwartet
    if (a == 5 xor b == 7); //auch okay, op== hat Vorrang vor op^
    if (a == 5 != b == 7); //ups..... daraus wird (((a == 5) != b) == 7)
    

    Ich würde im Ernstfall tatsächlich sowas wie volkards Vorschlag mit dem Proxy und dem Makro in Betracht ziehen, allerdings mit anderen Operatoren:

    template<class L, class T>
    struct xor_proxy
    {
      xor_proxy(L const& t) : l_(l) {}
      L const& l_;
    };
    
    template<class T>
    struct xor_dummy {};
    
    template<class T>
    xor_dummy xor_d();
    
    template<class L, class T> 
    xor_proxy<L, T> operator&& (T const& lhs, xor_dummy<T>)
    {
      return xor_proxy<L, T>(lhs);
    }
    
    template<class L>
    xor_proxy<L,L> operator&& (L const& lhs, xor_dummy<void>)
    {
      return xor_proxy<L,L>(lhs)
    }
    
    template <class L, class T, class R>
    T operator|| (xor_proxy<L,T> const& lhs, R const& rhs)
    {
      return (lhs.l_ && !rhs || rhs && !lhs);
    }
    
    #define XOR             && xor_d<void>() ||
    #define XOR_T (res_t)   && xor_d<##res_t##>() ||
    


  • pumuckl schrieb:

    Ich würde im Ernstfall tatsächlich sowas wie volkards Vorschlag mit dem Proxy und dem Makro in Betracht ziehen, allerdings mit anderen Operatoren:

    Ich wuerde klammern setzen.
    Aber gut, ich verstehe das verlangen nach einem xor halt auch einfach nicht.
    insofern muss ich ja alle etwaigen loesungen schlecht finden...



  • Shade Of Mine schrieb:

    Aber gut, ich verstehe das verlangen nach einem xor halt auch einfach nicht.
    insofern muss ich ja alle etwaigen loesungen schlecht finden...

    Nö. So ganz nachvollziehen kann ich den Wunsch sowas zu haben auch nicht, geht halt auch ohne und es wird eh nur selten gebraucht - aber die Problemstellung, da was halbwegs zufriedenstellendes hinzubasteln reizt mich 😉

    Das mit den Klammern würde ich natürlich normalerweise auch machen, deswegen ists es auch nur ein minimaler Vorteil dass op^ von der Priorität her ein kleines bisschen näher an den logischen Operatoren ist als op!=



  • Hallo,

    um es nochmal zu erklären. Der Wunsch nach einem XOR kommt bei mir schlicht daher, dass Konstrukte wie

    ((((a || b) && !(a && b)) || c) && !(((a || b) && !(a && b)) || c))

    einfach schlecht zu lesen sind. Natürlich kann man das dann in eine Funktion legen etc. Aber XOR(XOR(a,b),c) oder noch tiefer geschachtelt ist irgendwie auch hässlich. Da kam in mir einfach die Frage auf, ob das nicht ansprechender geht.

    Gegen != spricht lediglich, dass das nur so lange funktioniert, wie man sich auf bool'schen oder bool simulierenden Werten bewegt.

    D.h. wenn ich plötzlich aus irgendeinem Grund beliebige Integer nehme - die ja laut Definition "wahr" sind sofern sie ungleich Null sind - geht das schief.

    Aber ich werde jetzt erstmal != verwenden. Für meinen Anwendungsfall bewege ich mich eh nur auf den definierten bool'schen Werten. Ist halt nur nicht "idiotensicher".

    Die Idee von volker finde ich auch gut. Aber so verliere ich das binäre XOR, oder? Nicht, dass ich es brauchen würde...

    Fröhliche Grüße,
    Torge



  • Torge schrieb:

    Hallo,
    um es nochmal zu erklären. Der Wunsch nach einem XOR kommt bei mir schlicht daher, dass Konstrukte wie
    ((((a || b) && !(a && b)) || c) && !(((a || b) && !(a && b)) || c))
    ...

    das wird mit meinem !!=! zu
    (!a!=!b || c) && !(!a!=!b || c)
    ok, da ist wohl
    (a XOR b || c) && !(a XOR b || c)
    netter.

    andererseits, kann shade mit
    (xor(a,b) || c) && !(xor(a,b) || c)
    auch viele punkte für sich verbuchen.


Anmelden zum Antworten