Подтвердить что ты не робот

Как в этом примере выполняются операции if-statement и побитовые операции?

Я читал этот ответ и упоминается, что этот код;

if (data[c] >= 128)
    sum += data[c];

можно заменить на это:

int t = (data[c] - 128) >> 31;
sum += ~t & data[c];

Мне трудно это схватить. Может ли кто-нибудь объяснить, как побитовые операторы достигают того, что делает оператор?

4b9b3361

Ответ 1

if (data[c] >= 128)
    sum += data[c];

Ясно добавляет data[c] в sum тогда и только тогда, когда data[c] больше или равно 128. Легко показать, что

int t = (data[c] - 128) >> 31;
sum += ~t & data[c];

Является эквивалентным (когда data содержит только положительные значения, которые он делает):

data[c] - 128 является положительным тогда и только тогда, когда data[c] больше или равно 128. Сдвинутое арифметически право на 31, оно становится либо все (если оно меньше 128), либо все нули (если оно было больше или равным 128).

Вторая строка добавляет к sum либо 0 & data[c] (так ноль) в случае, если data[c] < 128 или 0xFFFFFFFF & data[c] (so data[c]) в случае, если data[c] >= 128.

Ответ 2

int t = (data[c] - 128) >> 31; sum += ~t & data[c];

(Обратите внимание, что этот хак не является строго эквивалентным оригиналу Условный оператор. Но в этом случае оно справедливо для всех входных значений Данные [].)

(data[c] - 128) >> 31;//это пытается извлечь только знаковый бит данных [c], когда данные [c] больше или равны 128, если оно меньше 128, тогда (данные [c] - 128) автоматически переместится на некоторое отрицательное число, тем самым установив бит знака.

и sum += ~t & data[c]; будет И данные значения [c] с 1 или 0 в зависимости от дополняемого значения знакового бита. Значит, ничего не будет добавлено к sum, если значение ((data[c] - 128)) отрицательно.

Ответ 3

if (data[c] >= 128)
    sum += data[c];

равно

if (data[c] - 128 >= 0)
    sum += data[c];

что означает, что add data[c] для суммирования, если data[c] - 128 не является отрицательным. Поэтому нам нужно извлечь знак data[c] - 128. Поскольку данные представляют собой 32-битный массив int. Поэтому для получения знака нам необходимо арифметически сдвинуть его 32 - 1 = 31 раз. Так

int t = (data[c] - 128) >> 31; //where t is the sign of data[c] - 128, 0 for positive and 1 for negative
sum += ~t & data[c]; //Add data[c] in sum if t = 0 i.e when the sign of data[c] - 128 is positive

Ответ 4

int t = (данные [c] - 128) → 31; Здесь данные [c] - это тип данных int и тип данных int 4 байта .if(данные [c] - 128) положительны, а 31-й бит - знаковый бит, а значение будет равно 0.if(данные [c] - 128) отрицательный, тогда 31-й бит будет равен 1. Затем правый сдвиг 31 раз дает вам только бит знака. Извините за плохой английский