Условное использование побитовых операторов

Как условный оператор представляется с помощью побитовых операторов?

Изменить: Извините за плохое объяснение. Это домашний вопрос, в котором я должен реализовать условный оператор, используя только побитовые операции. Было бы просто, если бы операторы были разрешены, однако это должны быть строго побитовые операторы. Функция принимает три целых числа и работает так же, как обычный условный оператор. Этот первый int оценивается, и один из последних двух возвращается в зависимости от значения первого. Я надеялся, что для этого будет простой алгоритм. Любые идеи о том, с чего начать, будут очень полезны. Спасибо!

 Matt26 сент. 2010 г., 19:42
Только ! ~ & ^ | + >> и << можно использовать. Нет, если можно использовать операторы или циклы.
 caf27 сент. 2010 г., 00:29
позволяющий+ но нет- кажется совершенно произвольным.
 AnT26 сент. 2010 г., 18:21
В терминологии С терминусловный оператор обозначает троичный?: оператор. Этот оператор не является и не может быть представлен побитовыми операторами каким-либо значимым образом. Ваш вопрос, как указано, не имеет большого смысла (если таковой имеется). Пожалуйста, уточните это.
 Matt26 сент. 2010 г., 19:22
Нулевая / ненулевая проверка - это то, что мне нужно сделать, но я не могу использовать любые операторы if.
 AnT26 сент. 2010 г., 19:18
Как зависит результат вашего оператора от первого int? Просто простая проверка нуля / ненулевой или что-то еще?
 zwol26 сент. 2010 г., 18:06
Не могли бы вы быть более конкретным, пожалуйста? Это звучит как плохо сформулированный домашний вопрос. Я не знаю, что значит «представлять» одного оператора другим.
 AnT26 сент. 2010 г., 19:38
Извините, но существует большая разница между словами "нельзя использовать операторы if" и "можно использовать только побитовые операторы". Итак, что это?

Ответы на вопрос(5)

этот, Я не могу думать ни о каком другом заявлении на ваш вопрос.

один второго или третьего операндов; побитовые операторы всегда оценивают оба операнда.

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

 T.E.D.26 сент. 2010 г., 18:22
Приходится соглашаться со вторым пунктом здесь. Лучше думать о них обоих с точки зрения того, что они делают на уровне машины, чем пытаться связать одно с другим.

что ОП ищет способ выразить вещи, которые обычно требуют условного выражения без ответвлений. Например (при условииunsigned x,y,z; а такжеx ограниченINT_MAX):

if (x>2) y+=z;

может быть выражено как:

y += z & -(2-x >> sizeof(unsigned)*CHAR_BIT-1);

Этот пример приходит на ум, потому что я несколько раз использовал его в «бинарной сортировке без ветвей». Когда размер искомого массива постоянен, это позволяет полностью развернуть цикл поиска в последовательность операций без ветвей и компилировать всего несколько кодов операций за шаг. Те, кто возражает против написания «ассемблера в C», могут предпочесть, чтобы это было написано:

y += (x>2) ? z : 0;

и надеюсь, что компилятор генерирует эквивалентную битовую маску илиcmov инструкция. :-)

это может быть представлено с использованием побитовых операций, но только в определенных случаях (на самом деле это оптимизация для использования побитовых операций в некоторых случаях). Например:(getsomevalue() == 1) ? somepointer : NULL; может быть представлен какsomepointer & ~((unsigned)(getsomevalue()) - 1); при условии,getsomevalue() возвращает только 1 или 0 (он же BOOL)

Решение Вопроса

ие операторы?

Ваше редактирование не совсем понятно, но я предполагаю, что вам нужно реализовать эквивалент

a ? b : c

гдеa, b а такжеc целые числа. Это в свою очередь эквивалентно

a != 0 ? b : c

Один из способов добиться этого - найти способ превратить ненулевое значениеa в единый битовый шаблон, используя только побитовые операторы. Если мы выясним, как это сделать, остальное будет легко. Теперь я не сразу помню какие-то хитрые трюки, которые бы это делали (я думаю, они существуют), и я точно не знаю, какие операторы разрешены, а какие нет, поэтому сейчас я просто буду использовать что-то вроде

a |= a >> 1; a |= a >> 2; a |= a >> 4; a |= a >> 8; a |= a >> 16;
a |= a << 1; a |= a << 2; a |= a << 4; a |= a << 8; a |= a << 16;

Для 32-битного целочисленного типа, если (и только если) был установлен хотя бы один бит в оригиналеaвышеуказанное должно привести ко всем битамa установите в 1. (Предположим, мы работаем с целыми числами без знака, чтобы избежать проблем, связанных со смещением значений со знаком). Опять же, должен быть более умный способ сделать это, я уверен. Например:a = !a - 1но я не знаю,! а также- разрешены.

После того, как мы это сделали, исходный условный оператор становится эквивалентным

(a & b) | (~a & c)

Готово.

 Matt26 сент. 2010 г., 19:44
Чтобы создать битовый паттерн, могу ли я просто использовать: a =! A; а = ~ а. Что если бы ноль был?
 Todd Lehman07 июн. 2015 г., 00:46
@Matt -~a не меняет ненулевойa в единый битовый паттерн; скорее то, что он делает, это карты0x00000001 в0xFFFFFFFE, Что вы хотите-aкакие карты0x00000000 в0x00000000 и карты0x00000001 в0xFFFFFFFF.
 AnT26 сент. 2010 г., 19:51
@Matt: я не понимаю Что такоеa = !a; a = ~a? Во-первых,! не является побитовым оператором. Вы можете использовать это? Во-вторых, весь смысл в том, чтобы превратить ненулевойa в единичной битовой комбинации и оставьте нольa без изменений (т. е. шаблон с нулевым битом).
 Matt26 сент. 2010 г., 19:59
Я не понимал, что это изменит ненулевое значение a в битовую комбинацию со всеми единицами, оставив ноль в одиночку. Это работает отлично. Большое спасибо!

Ваш ответ на вопрос