Не могу вернуть правильное значение после сдвига битов - PullRequest
0 голосов
/ 17 ноября 2018

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

Я объявил переменную как Integer, потому что 32 бита - это наименьший размер переменной, в котором достаточно битов для хранения одного значения от 1 до 12, одного значения от 1 до 31 и одного значения от 1 до 9999.

Затем я беру с консоли ввод для части «день» переменной Integer и присваиваю ее указанной переменной.После этого я сдвигаю биты на 4 позиции влево, что оставляет мне 4 свободных бита справа для сохранения части «месяц».Затем я беру с консоли ввод значения месяца и присваиваю переменной значение (переменная ИЛИ console_input).После этого я сдвигаю все 14 мест вправо, чтобы разрешить значение от 1 до 9999 для года, и выполняю еще одну операцию ИЛИ, чтобы присвоить значение 14 битам, освобождаемым сдвигом.

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

Извините, если я не был слишком ясен в своем описании, но вы, надеюсь, получите то, что я говорю, посмотрев наприкрепленный код.У меня проблема в том, что значения дня и месяца отображаются правильно, но я всегда получаю неправильный год назад, и я просто не могу понять, почему.Любая помощь очень ценится!

Dim inputDate As Integer
    Console.WriteLine("Day: ")
    inputDate = Console.ReadLine()

    inputDate = (inputDate << 4)

    Console.WriteLine("Month: ")
    inputDate = (inputDate Or Console.ReadLine())

    inputDate = (inputDate << 14)

    Console.WriteLine("Year: ")
    inputDate = (inputDate Or Console.ReadLine())

    Console.WriteLine("Day: {0}. Month: {1}. Year: {2}", ((inputDate >> 18) And 31), ((inputDate >> 14) And 15), (inputDate And 9999))

1 Ответ

0 голосов
/ 17 ноября 2018

Я думаю, что ваша проблема лежит на вашей последней строке.
Вы маскируете свои Day и Month значениями, которые выдают все 1 в двоичном виде.
Однако вы неправильно маскируете свой год.

9,999 - это 10 0111 0000 1111 в двоичном формате, что означает, что вы гарантируете, что определенные биты останутся 0, когда AND будут объединены.
Это приведет к тому, что год даст неверные результаты. Если вы ищете 14-битный формат года, вам нужно замаскировать 2^14 - 1, то есть 16,383, то есть 11 1111 1111 1111 в двоичном формате.

Обратите внимание, что 31 и 15 следуют одним и тем же принципам:
15 = 1111 и 31 = 11111

Надеюсь, это поможет!

...