как использовать инверсию в C - PullRequest
18 голосов
/ 28 июня 2011

[как использовать ~ оператор]

У меня есть структура, скажем Alpha. Я знаю значение элемента внутри Alpha (скажем, a), которое может быть 0 или 1 - я хочу, чтобы другой элемент той же структуры принял обратное значение Alpha.a. Например:

if Alpha.a = 1
then Alpha.b = 0

и наоборот

Я пытался:

Alpha.b = ~ (Alpha.a)

Но, к сожалению, это не работает - когда Alpha.a равен 1, Alpha.b устанавливается на 254

Есть идеи?

Спасибо и всего наилучшего,

SamPrat

Ответы [ 7 ]

40 голосов
/ 28 июня 2011

В C true представлен 1, а false - 0. Однако при сравнении любое неверное значение обрабатывается как true.

Оператор ! делает логическое инверсия, поэтому! 0 равно 1, а! 1 равно 0.

Оператор ~, однако, производит побитовое обращение, где каждый бит в значениизаменено на обратное.Так что ~ 0 равно 0xffffffff (-1).~ 1 равно 0xfffffffe (-2).(И оба -1 и -2 считаются истинными, что, вероятно, вас смущает.)

То, что вы хотите, это ! вместо ~.

30 голосов
/ 28 июня 2011

Используйте оператор XOR:

Alpha.b = Alpha.a ^ 1;
3 голосов
/ 05 июля 2013

Хорошим межплатформенным кросс-языковым решением этой распространенной проблемы является:

Alpha.b = 1 - Alpha.a;
3 голосов
/ 28 июня 2011

Оператор ~ отменяет каждый отдельный бит. Например, предположим, что Alpha.a является unsigned char. Тогда ~1 будет читать, в двоичном виде как ~ 00000001, и результат будет 11111110 (опять же, в двоичном виде), что равно 254 в десятичном и 0xFE в шестнадцатеричном.

Как предлагали другие, используйте !Alpha.a или Alpha.a ^ 1.

1 голос
/ 19 декабря 2013

А как насчет послеоперационной битовой маски?

с использованием неподписанных символов, ищущих бит 0:

b = 0x01u & ( ~a );

или даже

b = a ^ 0x01u;

или для "логических мыслителей" (имейте в виду, что ИСТИНА и ЛОЖЬ могут отличаться от 0/1! если вы хотите, чтобы это был «настоящий логический», вы должны использовать ИСТИНА и ЛОЖЬ, если они определены.)

b = (1 != a)?(0u):(1u);

Приветствия

1 голос
/ 28 июня 2011

Вы не можете использовать ~, поскольку это превратит 00000000 в 11111111 вместо 00000001, как я думаю, вы ожидаете.

Если у вас есть bools, вы можете использовать:

Alpha.b = !(Alpha.a)

, но если нет, то вам, возможно, придется использовать логику if / else:

if (Alpha.a == 0)
{
    Alpha.b = 1;
}
else
{
    Alpha.b = 0;
}
0 голосов
/ 28 июня 2011

Вы хотите использовать другой оператор. В частности!

Alpha.b = !Alpha.a

Поскольку значения равны нулю или единице, это намного проще.

...