Перевод числа в двоичную систему, используя побитовый сдвиг

Тема побитового сдвига для меня абсолютно нова, пытаюсь разобраться.

Я делю на 2, используя побитовый сдвиг, но не могу понять, как проверить наличие остатка при делении. &1 не даёт результата, вернее дает 0, потому что работает с уже округлённым вниз числом.

def ten_to_bi(n):
    ans = '0b'
    ans_add = ''
    while n != 1:
        n = n >> 1
        ans_add += n & 1  # эта операция проверяет число на чётность, и ошибка тут
    return ans + ans_add[::-1]

А вот так бы я решал без побитового сдвига:

def ten_to(n):
    ans = '0b'
    ans_add = ''
    while n != 1:
        ans_add += str(n % 2)
        n = int(n/2)
    ans_add += str(n % 2)
    return ans + ans_add[::-1]

Но у меня задание по курсу сделать это именно с помощью побитовых операций.


Ответы (2 шт):

Автор решения: Кирилл Малышев

Вам нужно сначала получать младший бит числа, а только потом его откусывать от числа.

В варианте без побитовых операций вы так и делаете

ans_add += str(n % 2) 
n = int(n/2)

С побитовыми операциями вам нужно поступать аналогично.

ans_add += str(n & 1)  # Получаем младший бит числа
n >>= 1  # Сдвигаем число на 1 бит вправо. То же самое, что и деление на 2.

Вы делаете наоборот. Из-за этого теряете бит.

P.S. В Python 3 целочисленное деление выполняется операцией //

n //= 2

Чтобы не делать в конце реверс строки, можно сразу записывать цифры в правильном порядке

ans_add = str(n & 1) + ans_add
→ Ссылка
Автор решения: nomnoms12

Задачу можно решать по аналогии:

def ten_to_bi(n):
    ans = '0b'
    ans_add = ''
    while n > 1:
        ans_add += str(n & 1)
        n >>= 1
    ans_add += str(n & 1)
    return ans + ans_add[::-1]

Ваша ошибки:

  1. Складывали число со строкой:
    str(n & 1)
    
  2. Делали сдвиг ещё до того, как брали остаток:
    ans_add += str(n & 1)
    n >>= 1
    
  3. Забыли добавить последний остаток:
    ans_add += str(n & 1)
    
  4. Не учли крайний случай в обоих решениях (0):
    while n > 1:
    
→ Ссылка