Почему смещение бит?

Недавно я просмотрел файл конфигурации, который сохранял некоторые загадочные значения. У меня был источник, доступный, поэтому я взглянул на то, что он делал, и это спасло кучу разных значений и бит, смещая их друг в друга. Меня озадачило, почему кто-то это сделает. Поэтому мой вопрос заключается в следующем: существует ли очевидное преимущество для хранения числовых данных таким образом? Я могу видеть, как это может сделать для немного меньшего значения для хранения, байт-мудрый, но, похоже, много работы по сохранению нескольких байтов памяти. Также кажется, что это будет значительно медленнее.

Другая возможность, которая возникла для меня, заключается в том, что она используется для обфускации. это обычное использование смещения битов?

Ответ 1

Сдвиг битов кажется более распространенным в языках системного уровня, таких как C, С++ и сборка, но я видел его здесь и там на С#. Это не часто используется так много, чтобы сэкономить место, хотя, как и для одного (или обоих) двух типичных причин:

  • Вы разговариваете с существующей системой (или используя установленный протокол или создаете файл в известном формате), который требует, чтобы материал был очень точно выложен; и/или
  • Комбинация битов содержит значение, которое само по себе полезно для тестирования.

Любой, кто использует его на высокоуровневом языке, исключительно для экономии места или обфускации своего кода, почти всегда преждевременно оптимизирует (и/или является идиотом). Экономия пространства редко оправдывает дополнительную сложность, и бит-сдвиги действительно недостаточно сложны, чтобы остановить кого-то, кто решил понять ваш код.

Ответ 2

Это одно из общих способов смещения бит. Есть несколько преимуществ:

1) Операции бит-сдвига выполняются быстро.

2) Вы можете хранить несколько флагов в одном значении.

Если у вас есть приложение с несколькими функциями, но вы хотите, чтобы определенные (настраиваемые) были включены, вы могли бы сделать что-то вроде:

[Flags]
public enum Features
{
    Profile = 1,
    Messaging = 1 << 1,
    Signing = 1 << 2,
    Advanced = 1 << 3
}

И ваше единственное значение для включения Messaging и Advanced:

(1 << 1) + (1 << 3) = 2 + 16 = 18

<add name="EnabledFeatures" value="18" />

И затем, чтобы выяснить, включена ли данная функция, вы просто выполните простую побитную математику:

var AdvancedEnabled = 
    EnabledFeatures & Features.Advanced == Features.Advanced;

Ответ 3

У меня есть проект, в котором хранится дневная/часовая матрица доступных часов в течение одной недели. Таким образом, он имеет значения 24x7, которые необходимо каким-то образом сохранить.

Я решил сохранить его как 7 ints, поэтому каждый день представлен одним целым числом и каждый час в нем как один бит. Просто пример, где это может быть полезно.

enter image description here

Ответ 4

Иногда (особенно в более раннем программировании Windows), информация будет закодирована в битах "высокого порядка" и "младшего порядка" значения... и иногда необходимо перейти, чтобы получить информацию. Я не уверен на 100% по причинам, стоящим за этим, кроме этого, может быть удобно вернуть 64-битное значение с двумя 32-битными значениями, закодированными в нем (чтобы вы могли обрабатывать его с единственным возвращаемым значением из метода называют).

Я согласен с вашими утверждениями о ненужной сложности, хотя я не вижу много приложений за пределами действительно тяжелого количества хрустящих/криптографических материалов, где это было бы необходимо.