Сдвиг битов должен работать, а также будет заботиться о знаковых битах на многих архитектурах. В случае отрицательных чисел, большее число будет сдвинуто, но вы будете либо использовать только младшие 5 битов, либо выполнять арифметику в Си, где вам нужны эти дополнительные, чтобы сформировать правильное дополнение к двум.
Принимая целые числа, код будет просто:
int q4 = q8 >> 4;
Возможно, вы хотели бы округлить:
int ahalf = q8 >= 0 ? (1<<3) : (1<<3)-1;
int q4 = (q8+ahalf) >> 4;
Хорошо, я слушаю Оли и представляю решение для архитектур, которые не меняют знак-правильность:
int q4 = q8 / (1<<4);
Оптимизатор должен преобразовать деление в сдвиг, если это возможно.
При округлении первое решение будет
int ahalf = q8 >= 0 ? (1<<3) : -(1<<3);
int q4 = (q8+ahalf) / (1<<4);
Благодаря настойчивости R .. я наконец протестировал все версии, и теперь они дают правильные результаты с 32-битными целыми числами, подписанными Intel, под Linux.