#c
#c
Вопрос:
У меня довольно простой вопрос. Есть ли способ динамического побитового сдвига влево ИЛИ вправо, например, в зависимости от знака int .
signed int n = 3;
signed int m = -2;
int number1 = 8;
int number2 = 8;
//number1 shift n;
//number2 shift m;
В этом случае я хочу сдвинуть number1 на 3 бита влево и number2 на 2 бита вправо. Есть ли способ без if else
этого?
Комментарии:
1. Вы должны сдвигать только целые числа без знака.
Ответ №1:
Для 32-разрядных:
x = (((длинный длинный)x) << 32) >> (32 — n)
Комментарии:
1. Мне нравится элегантность этого подхода, но это также должно работать для 64-битных целых чисел и может привести ко многим переполнениям.
2. Для 64-разрядной версии:
(__int128)x << 64 >> (64 - n)
. Работает только с компиляторами с поддержкой __int128 (gcc, clang). Вы можете динамически определять длину в битах с помощьюCHAR_BIT*sizeof x
, но гораздо сложнее получить тип для динамического приведения
Ответ №2:
#include <stdio.h>
typedef unsigned (*fx_t)(unsigned, int);
unsigned shiftleft(unsigned val, int bits) {
return val << bits;
}
unsigned shiftright(unsigned val, int bits) {
return val >> (-bits);
}
unsigned shift(unsigned val, int bits) {
static fx_t sshift[2] = {shiftright, shiftleft};
return sshift[bits >= 0](val, bits);
}
int main(void) {
signed int n = 3;
signed int m = -2;
unsigned number1 = 8;
unsigned number2 = 8;
printf("%un", shift(number1, n));
printf("%un", shift(number2, m));
return 0;
}
Вы можете «увидеть, как выполняется код» в ideone: http://ideone.com/F2vAB http://ideone.com/x1RbQ
Комментарии:
1.
shiftright
Иshiftleft
должно быть определено сstatic
помощью, но я не хочу редактировать ответ и выводить его из синхронизации с ideone.2. Это все еще использует условный (
bits >= 0
) , так что там скрытоif
.3. вы можете использовать
-(bits >> (CHAR_BIT*sizeof bits - 1))
или(unsigned)bits >> (CHAR_BIT*sizeof bits - 1))
удалить, если
Ответ №3:
?:
Считается ли как if-else
?
int x = (n > 0) ? (number1 << n) : (number1 >> (-n));
int y = (m > 0) ? (number2 << n) : (number2 >> (-m));
Комментарии:
1. ‘?:’ считается как ‘if-else’, но я нахожу этот ответ удовлетворяющим моим потребностям, поскольку он короткий и надежный. Это не означает, что другие ответы неверны. Спасибо всем.
Ответ №4:
Нет, вам понадобится условие.
Операторы побитового сдвига имеют неопределенное поведение, если вы используете отрицательное значение справа от них.
Ответ №5:
Если значение числа сдвигаемых битов отрицательное, результат не определен. Однако вы можете поэкспериментировать со своим компилятором, может случиться так, что ваш компилятор сместится в противоположном направлении. И, конечно, вы могли бы использовать ?:
, но это просто другой способ выражения if-else.