Ответ 1
Искав хороший ответ, я наткнулся на это и смог получить рабочий фрагмент. Позвольте мне объяснить это другим, которые могут найти это в будущем.
(x + ((x >> 31) & ((1 << n) + ~0))) >> n
Этот фрагмент кода - это то, что вы ищете, как опубликовано Sotelo. Причина, по которой она работает, очень важна, особенно для вас, чтобы понять вашу домашнюю работу. Сначала вы должны полностью понимать представление 2-х долей. Это когда самый старший бит используется для смещения всего двоичного представления на соответствующую мощность 2. Если мы изображаем только 32 бита (стандартный в большинстве процессоров), то мы можем использовать правый сдвиг ( → ), чтобы переместить самый старший бит в младший значащий бит. При этом вы будете делать арифметический сдвиг вправо, который скопирует этот самый старший бит (a 1, если он отрицательный) во всем представлении уровня бит. В 6-битном двоичном представлении это приведет к тому, что
000000
111111
Это позволяет нам далее работать с целым числом для определения некоторых свойств. Сначала нам нужно найти степень 2, которую мы собираемся разделить на (в этом случае n) и сдвинуть двоичный код на эту позицию, затем минус 1. Например, пусть используется мощность 3 или 8.
(000001 << 3) -1
000111
теперь, когда у нас есть оба этих двоичных представления, мы будем вместе их вместе
111111 & 000111 = 000111 (case 1)
000000 & 000111 = 000000 (case 2)
теперь задано, что x нечетно или четно (случай 1 и случай 2 соответственно), мы можем добавить x к этому и получить число, которое является совершенной степенью 2 (если мы делим на степень по два, мы получим правильное ответ). Ниже приведено несколько примеров с x = 8, 10, -8, -12 соответственно.
001000 + 000000 = 001000
001010 + 000000 = 001010
now for the negatives that plague you
111000 + 000111 = 111111
110100 + 000111 = 111011
Теперь последний шаг состоит в том, чтобы разделить эти числа на нашу силу n. Для деления на 8 это будет 3, как указано выше.
001000 >> 3 = 000001 or 1 in decimal (8/8 = 1)
001010 >> 3 = 000001 or 1 in decimal (10/8 = 1 because of truncation)
111111 >> 3 = 111111 or -1 in decimal (-8/8 = -1)
111011 >> 3 = 111111 or -1 in decimal (-12/8 = -1 because of truncation)
Итак, у вас это есть. Сначала вы должны определить, является ли он отрицательным или положительным, а затем получить бит от отрицательного значения, соответствующего вашей мощности 2 -1. Добавьте это в свой x, чтобы получить свою силу из 2 делимых чисел в двоичном формате. Затем, наконец, разделите вас на правый сдвиг вашей силы на два.