Почему вы не используете встроенную функцию swab
, которая, вероятно, оптимизирована лучше, чем ваш код?
Кроме того, обычные операции сдвига битов должны начинаться быстро и настолько широко использоваться, что могут распознаваться оптимизатором и заменяться еще более качественным кодом.
Поскольку у других ответов есть серьезные ошибки, я опубликую более лучшую реализацию:
int16_t changeEndianness16(int16_t val)
{
return (val << 8) | // left-shift always fills with zeros
((val >> 8) & 0x00ff); // right-shift sign-extends, so force to zero
}
Ни один из протестированных мной компиляторов не сгенерировал rolw
для этого кода, я думаю, что более длинная последовательность (с точки зрения количества команд) на самом деле быстрее. Тесты были бы интересны.
Для 32-битных операций возможны несколько порядков:
//version 1
int32_t changeEndianness32(int32_t val)
{
return (val << 24) |
((val << 8) & 0x00ff0000) |
((val >> 8) & 0x0000ff00) |
((val >> 24) & 0x000000ff);
}
//version 2, one less OR, but has data dependencies
int32_t changeEndianness32(int32_t val)
{
int32_t tmp = (val << 16) |
((val >> 16) & 0x00ffff);
return ((tmp >> 8) & 0x00ff00ff) | ((tmp & 0x00ff00ff) << 8);
}