Потому что они фундаментальные операции.
Таким же образом можно утверждать, что сложение имеет мало реальных применений, поскольку оно может быть полностью заменено вычитанием (и отрицанием) и умножением. Но мы продолжаем сложение, потому что это фундаментальная операция.
И не думайте, что если вы не видели особой необходимости в побитовых операциях, это не означает, что они используются не очень часто. Действительно, я использовал битовые операции почти на каждом языке, который использовал для таких вещей, как битовая маскировка.
Вдобавок ко всему, я использовал побитовые операции для обработки изображений, битовых полей и флагов, обработки текста (например, все символы определенного класса часто имеют общую битовую комбинацию), кодирования и декодирования сериализованных данных, декодирования ВМ или ЦП. коды операций и так далее. Без побитовых операций большинству этих задач потребовались бы во много раз более сложные операции, чтобы выполнить задачу менее надежно или с меньшей читаемостью.
Например:
// Given a 30-bit RGB color value as a 32-bit int
// A lot of image sensors spit out 10- or 12-bit data
// and some LVDS panels have a 10- or 12-bit format
b = (color & 0x000003ff);
g = (color & 0x000ffc00) >> 10;
r = (color & 0x3ff00000) >> 20;
// Going the other way:
color = ((r << 20) & 0x3ff00000) | ((g << 10) & 0x000ffc00) | (b & 0x000003ff);
Для декодирования инструкций ЦП для ЦП типа RISC (например, при эмуляции другой платформы) требуется извлечь части большого значения, как указано выше. Иногда выполнение этих операций с умножением и делением, а также по модулю и т. Д. Может быть в десять раз медленнее, чем эквивалентные побитовые операции.