Почему на многих языках отсутствует логический оператор XOR?

Сверху моей головы я не могу представить ни одного языка, который я использовал, который имел логический эксклюзив или оператор, но у всех есть логические и побитовые операторы and и or.

Оглядываясь по сторонам, единственная причина, по которой я мог найти, - это исключительная или не может быть короткой, поэтому логическая версия будет бесполезной, что я действительно не вижу. Причина, по которой мне приходило в голову, что у большинства языков это не так, - это то, что мне это нужно (я использовал Ruby, поэтому я написал метод преобразования целого числа в логическое, а затем использовал побитовое XOR, которое по логическим операциям действует как логический XOR).

Просто использование побитового XOR тоже не работает, потому что это даст другой результат.

0b0001  ^  0b1000 = 0b1001 (True)
0b0001 XOR 0b1000 = False
// Where ^ is bitwise exclusive or and XOR is logical exclusive or
// Using != (not equal to) also doesn't work
0b0001 != 0b1000 = True

Так почему же большинство языков не включает логический эксклюзив или оператор?

Изменить: я добавил пример с тем, как != также не делает то, что я хочу, он почти делает, но попадает в ту же проблему, что с использованием побитового исключения или делает это работает только если вы знаете, что работаете с ноль или один, а не любое другое число.

И отметить, что это предполагает, что язык использует ноль как ложный и ненулевой как истинный.

Ответ 1

ОК, так что вы ищете пошаговое эксклюзивное - или по сравнению с побитовым эксклюзивным - или. Кажется, что вы ищете что-то, что будет работать на байте как "on" или "off", так как считается, что байты "0" или "отличные от нуля", а затем XOR. Похоже, вы пытаетесь сжать каждый байт в один бит, указав true или false. Итак, похоже, что вы хотите (a!= 0) ^ (b!= 0)

 a  b    a YOURXOR b    a!=0   b!=0   (a!=0)^(b!=0)
 0  0         0          0       0        0        
 0  1         1          0       1        1
 1  0         1          1       0        1
 7  0         1          1       0        1
 0  7         1          0       1        1
 3  7         0          1       1        0
 7  3         0          1       1        0
 7  7         0          1       1        0

Что касается того, почему это не на каждом языке... на который я не могу ответить. Однако это не все, что сложно реализовать со строительными блоками побитового xor, доступными на каждом языке, и ни один язык не предлагает все возможные функции - они просто предлагают достаточно, чтобы позволить вам создавать расширенные функции, которые могут вам понадобиться. О, и если бы это была достаточно популярная проблема, вы ожидали увидеть библиотеки или макросы повсюду для нее; в то время как я, возможно, не сделал достаточного поиска для таких libs/code, я сам не нашел ни одного, указав, что это требование либо тривиально для записи, либо как нишевое требование.

Ответ 2

Почти каждый язык имеет логический XOR. Символ, который они используют для него, меняется, но независимо от символа большинство людей произносят его "не равным".

Изменить: для тех, кто сомневается, проверьте код для трех переменных:

#include <iostream>

int main() { 
    for (int i=0; i<2; i++)
        for (int j=0; j<2; j++)
            for (int k=0; k<2; k++) {
                std::cout << "\n!=" << (i!=j!=k);
                std::cout << "\t^ " << (i^j^k);
            }
    return 0;
}

Ответ 3

Что вы подразумеваете под "логическим оператором XOR"? Я не уверен, какой результат вы ожидаете от своих примеров, но вот мой ответ:

a (logical XOR) b совпадает с bool(a) != bool(b)

Неравенство является логическим XOR. Поскольку у вас уже есть побитовая версия XOR, вам не нужен специальный оператор для логического.

Ответ 4

Вы также можете написать !a ^ !b, чтобы получить тот же эффект, что и логический xor.

Вероятно, вы не найдете логического xor в языках программирования, потому что:

  • он не генерирует очень эффективный код сборки
  • не требуется очень часто
  • разработчики языка должны помещать строку где-то, почему не NAND, NOR, NXOR и т.д.

Ответ 5

Единственная причина, по которой я могу думать, это то, что операция относительно редка. Я не понимаю, почему что-то вроде ^^ не может быть назначено ему, хотя, возможно, люди, которые разрабатывают языки, хотят избежать беспорядка оператора.

Что касается того, что он бесполезен, потому что он не может быть короткозамкнутым, то на многих сильно типизированных языках вы не можете использовать побитовый оператор XOR для сравнения логических значений без кавычек назад и вперед, и в этом случае даже без короткого замыкания логический XOR имеет смысл иметь.

Ответ 6

Вероятно, потому что XOR обычно не требуется как логический оператор, и вы можете сделать это почти так же легко, как это:

// foo xor bar
(foo & !bar) || (bar & !foo)

// or like this (assuming foo and bar are booleans)
!(foo==bar)

// assume boleans that can be cast as integers with true=1 and false=0
// foo XOR bar XOR baz XOR alice
((int)foo + (int)bar + (int)baz + (int)alice)&0b1