Да.
Мы хотим исправить ситуацию, чтобы, если offset
больше или равно 64, результат был равен нулю.
Стратегия:
- Сдвиг вправо на 6 бит, назовите это
temp
. - Если
temp
равно нулю, мы хотим инициализировать маску для всех 1 бит, в противном случае для всех 0 бит. Мы можем достичь sh этого, установив mask = !!temp - 1
. - Теперь просто побитовое и
v
и offset
с mask
.
Реализация:
uint64_t shift(uint64_t value, uint64_t offset) {
uint64_t temp = offset >> 6;
uint64_t mask = (!!temp) - 1;
return (value & mask) << (offset & mask);
}
Вместо смещения offset
вы также можете просто побитовое - и это с ~0x3F
, вероятно, будет быстрее.
uint64_t shift(uint64_t value, uint64_t offset) {
uint64_t mask = (!!(offset & ~0x3F)) - 1;
return (value & mask) << (offset & mask);
}