Я предполагаю, что вы работаете с int
32-битными, подписанными и использующими нотацию дополнения 2. Уникальность числа 0 состоит в том, что ни 0, ни его отрицание не имеют 1 для знаковых битов. Этот код будет работать, если вам будет разрешено использовать оператор отрицания (-):
int not(int x)
{
return (-x | x) >> 31 & 1 ^ 1;
}
Вы не можете использовать минус, но это нормально, потому что для всех x мы знаем, что -x
равно ~x + 1
, что равно (x ^ -1) + 1
. Вот как работает нотация дополнения 2. Итак, окончательный ответ:
int not(int x)
{
return ( (x^-1)+1 | x ) >> 31 & 1 ^ 1;
}
РЕДАКТ. 1:
Хорошо, вот версия «ANSI» функции, которая не делает никаких предположений о размере int и не полагается на неопределенное поведение смещения вправо подписанного int. У меня это работает в MinGW:
int not(int x)
{
unsigned int y = x;
return (( ((y^-1)+1) | y ) >> (sizeof(x)*8-1)) ^ 1;
}