Как в этом примере выполняются операции if-statement и побитовые операции?
Я читал этот ответ и упоминается, что этот код;
if (data[c] >= 128)
sum += data[c];
можно заменить на это:
int t = (data[c] - 128) >> 31;
sum += ~t & data[c];
Мне трудно это схватить. Может ли кто-нибудь объяснить, как побитовые операторы достигают того, что делает оператор?
Ответы
Ответ 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 раз дает вам только бит знака.
Извините за плохой английский