Оператор C !
на самом деле является просто сокращением для != 0
, поэтому его использование кажется очень близким к мошенничеству:)
Вот мой пример, использующий только побитовые операции, предполагая, что 32-разрядная машина с двумя дополнительными числами с арифметическими сдвигами вправо (технически, в C арифметические сдвиги вправо не определены, но каждый компилятор C, который я когда-либо видел на машине дополнения до двух, поддерживает правильно):
int t = (x - y) | (y - x); // <0 iff x != y, 0 otherwise
t >>= 31; // -1 iff x != y, 0 otherwise
return 1 + t; // 0 iff x != y, 1 otherwise
Тем не менее, фактические компиляторы не имеют этой проблемы. Реальное оборудование имеет прямую поддержку для сравнения. Детали зависят от архитектуры, но есть две основные модели:
- Коды условий, возвращаемые для арифметических операций (например, x86 и ARM делают это). В этом случае обычно есть команда сравнения, которая вычитает два значения, не записывает обратно в регистр целых чисел, но устанавливает код / флаги условия на основе результата.
Больше RISC-подобных платформ обычно имеют прямые операнды «ветвь, если равен» и «ветвь, если меньше, чем», которые выполняют сравнение и ветвление на основе результата. Это в основном эквивалентно коду C
if (a == b) goto label;
или
if (a < b) goto label;
все в одной машинной инструкции.