C# - дата упаковки, месяц, год
В разделе "Программирование на ключе C#" автор приводит пример (с исходным кодом) того, как дата (год, месяц, день - в числах) может быть упакована в 32-разрядное целое число. В этом примере автор упаковывает информацию следующим образом:
int iDate = (iYear << 9) | (iMonth << 5) | iDay;
Если я правильно понимаю, сдвиг влево на 9 дает нам значение 512 (или 1023, если считать каждую битовую позицию). Тем не менее, я заметил, что при запуске программы такие значения, как 2014 (год) могут быть сохранены. Как это возможно с таким небольшим значением? Я неправильно понимаю часть этого кода? Никакое количество чтения, просмотра или игры с кодом не помогло мне очистить воздух.
2 ответа
Сдвиг не отражает максимальное значение, которое может принять год (даже если вы допустили ошибку в своих расчетах, это не причина, по которой мы смещаем 9 слева). Сдвиг позволяет определить диапазоны, которые будут использоваться для каждого значения. Ниже ascii, который показывает, как значения будут организованы в Int32
после того, как значения сдвинуты
11111111111111111111111 1111 11111
-----------yyyyyyyyyyyY mmmM ddddD
Поскольку дневное значение может быть не более 31, будет достаточно 5 бит (32 возможных значения). В этом месяце нам понадобятся 4 бита (16 возможных значений), которые будут соответствовать нашим 12 возможностям. Году нужно как минимум 12 битов, если мы хотим, чтобы наша схема умных дат продолжалась после 2048 года. У нас все еще есть место слева, чтобы продержаться долго.
Вот почему мы смещаем значение месяца в 5 раз, а значение года - в 9 раз. Также, поэтому Int16 недостаточно, нам нужно больше битов, чем 16, чтобы сохранить нашу дату
Сдвиг влево на 9 может дать 512, если вы начали с 1. Тем не менее, я думаю, что здесь происходит, что предполагается, что младшие 9 бит используются для хранения числа, тогда как на самом деле младшие 9 бит не используются сохранить это значение. Сдвиг влево на 9 перемещает "использованные биты" влево на 9, освобождая 9 младших битов. В этой части из 9 битов вы можете хранить только 512 различных значений (от 0 до 511), но это не та часть, которую вы используете годами.
Чтобы представить его как рисунок, он заканчивается примерно так, если предположить, что значения не "перекрываются" (не должны, если у вас вдруг не будет 16 или более месяцев или 32 или более дней)
syyy yyyy yyyy yyyy yyyy yyym mmmd dddd
Много места на годы в обозримом будущем.