Suche logischen xor_operator



  • 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.



  • Torge schrieb:

    Die Idee von volker finde ich auch gut. Aber so verliere ich das binäre XOR, oder?

    Nein. Der binäre Operator heißt ^, xor ist ein alternatives Token dafür, das vom Lexer identisch übersetzt wird. Wenn du ein #define xor einbaust, kannst du immernoch den normalen operator^ benutzen an Stelle des alternativen Tokens. Probleme kannst alerdings eventuell geben wenn du MSVC zusammen mit einem entsprechenden Header benutzt, der hat nämlich die kleine Unzulänglichkeit dass die alternativen Token nicht implementiert sind, stattdessen gibts einen Header der mit #defines den Mangel behebt.
    Ich würde für den Fall allerdings das alles außen vorlassen und den logischen XOR als #define XOR einbauen - gottseidank ist ja auch der Präprozessor Case-sensitiv und rührt damit das alternative Token bzw. den M$-#define für den binären Operator nicht an.



  • volkard schrieb:

    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.
    [...]

    Hups, siehste mal. Sogar bei einem kurzen Beispiel mach ich da Fehler. Ich meinte natürlich
    ((((a || b) && !(a && b)) || c) && !(((a || b) && !(a && b)) && c))

    In Deiner Schreibweise würde dass dann wohl

    ((!a != !b) != !c) bedeuten (Okay, Klammern sind hier eigentlich überflüssig).

    Mit einem entsprechenden #define kann man dann (!a XOR !b XOR !c) schreiben.
    Das ist nett kurz, aber ich glaube für Dritte wäre (bool(a) XOR bool(b) XOR bool(c)) wohl besser zu verstehen, oder man muss halt einen Kommentar schreiben, weshalb man die Variablen erst negiert...

    @pumuckl: Danke für die Erklärung. Klingt gut.

    Fröhliche Grüße,
    Torge


Anmelden zum Antworten