Выполнение логического нет! используя только побитовые операции

Возможный дубликат:
Проверить, является ли число отличным от нуля, используя побитовые операторы в C.

Всем привет,

Я работаю над проектом, и мне нужна небольшая помощь с функцией. Нам нужно написать функцию, которая выполняет логическое НЕ, !, используя только следующие побитовые операторы:

~ & ^ | + << >>

Я даже не знаю, с чего начать.


person NotAround    schedule 28.10.2010    source источник
comment
@GWW Либо это, либо очень странный ведущий разработчик. :)   -  person Firoze Lafeer    schedule 28.10.2010
comment
В описании я указал, что это проект. :)   -  person NotAround    schedule 28.10.2010
comment
Да, но проект может означать домашнее задание :P   -  person GWW    schedule 28.10.2010
comment
stackoverflow.com/questions/3912112/   -  person ruslik    schedule 28.10.2010
comment
Какая спецификация проекта явно требует повторной реализации логического оператора?!   -  person dreamlax    schedule 28.10.2010


Ответы (3)


Если вы можете предположить, что true = 1 и false = 0, то это может помочь:

bool
not(bool x) {
    bool not_x = x ^ true;
    return not_x;
}
person Jeremy W. Sherman    schedule 28.10.2010

Логическое не возвращает 0, если значение не равно нулю, иначе 1. Предполагая 32-битный int:

int not_func(int v) {
    /* compress value to single bit */
    int p = (v >> 16) | v;
    p = (p >> 8) | p;
    p = (p >> 4) | p;
    p = (p >> 2) | p;
    p = (p >> 1) | p;

    p ^= 1;
    return (p & 1);
}
person blaze    schedule 28.10.2010

Я думаю, для начала вы хотите уточнить вопрос. Похоже, вам нужна функция, которая вернет 0, если какой-либо из битов в слове равен «1», и что-то отличное от 0, если все биты равны нулю. Предполагая 32-битное слово "a", вы можете сделать что-то вроде:

na1 = ~a;
shifted_na1 = na1 >> 1;
na2 = shifted_na1 & na1; /* any sequence of zeros is now 2 bits long */
shifted_na2 = na2 >> 2;
na3 = shifted_na2 & na2; /* any sequence of zeros is now 4 bits long */
shifted_na3 = na3 >> 4;
na4 = shifted_na3 & na3; /* any sequence of zeros is now 8 bits long */
shifted_na4 = na4 >> 8;
na5 = shifted_na4 & na4; /* any sequence of zeros is now 16 bits long */
shifted_na5 = na5 >> 16;
final = shifted_na5 & na5; /* any sequence of zeros is now 32 bits long */
really_final = final & 1;
person mjhm    schedule 28.10.2010
comment
логично! должен возвращать 1, а не 0xffffffff для 0 аргумента. - person blaze; 28.10.2010
comment
верно, у меня была еще одна ошибка. - person mjhm; 28.10.2010