← Назад к вопросам
Перевод в двоичную систему
1.0 Junior🔥 221 комментариев
#Python Core
Условие
Напишите функцию, которая преобразует десятичное число в двоичное представление (без использования встроенной функции bin()).
Пример
to_binary(10) → "1010" to_binary(255) → "11111111" to_binary(1) → "1"
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Перевод в двоичную систему
Задача: Преобразовать десятичное число в двоичное представление без встроенной функции bin().
Решение 1: Итеративный подход (классический)
Это наиболее прямолинейный способ — последовательно делим число на 2 и собираем остатки в обратном порядке:
def to_binary(n):
"""
Преобразует десятичное число в двоичное представление.
Алгоритм:
1. Пока число > 0:
- Берём остаток от деления на 2 (0 или 1)
- Добавляем его в начало строки результата
- Делим число на 2 (целочисленно)
2. Возвращаем результат
"""
if n == 0:
return "0"
binary = ""
while n > 0:
binary = str(n % 2) + binary # Остаток от деления на 2
n = n // 2 # Целочисленное деление на 2
return binary
# Примеры
print(to_binary(10)) # "1010"
print(to_binary(255)) # "11111111"
print(to_binary(1)) # "1"
print(to_binary(0)) # "0"
print(to_binary(127)) # "1111111"
Как это работает на примере to_binary(10):
n = 10
Итерация 1: 10 % 2 = 0, 10 // 2 = 5, binary = "0"
Итерация 2: 5 % 2 = 1, 5 // 2 = 2, binary = "10"
Итерация 3: 2 % 2 = 0, 2 // 2 = 1, binary = "010"
Итерация 4: 1 % 2 = 1, 1 // 2 = 0, binary = "1010"
Результат: "1010"
Решение 2: С использованием списка (более эффективно)
Замена строк на список быстрее, так как строки неизменяемы в Python:
def to_binary_optimized(n):
"""
Оптимизированная версия с использованием списка.
Быстрее, так как не создаёт новые строки при каждой итерации.
"""
if n == 0:
return "0"
binary_list = []
while n > 0:
binary_list.append(str(n % 2))
n = n // 2
return "".join(reversed(binary_list))
print(to_binary_optimized(10)) # "1010"
print(to_binary_optimized(255)) # "11111111"
Решение 3: Рекурсивный подход
def to_binary_recursive(n):
"""
Рекурсивное решение.
Базовый случай: n == 0 → возвращаем пустую строку
Рекурсивный случай: остаток(n, 2) + to_binary(n // 2)
"""
if n == 0:
return ""
else:
return to_binary_recursive(n // 2) + str(n % 2)
print(to_binary_recursive(10)) # "1010"
print(to_binary_recursive(255)) # "11111111"
# Обработка крайнего случая
def to_binary_recursive_safe(n):
"""Версия, которая корректно обрабатывает 0."""
if n == 0:
return "0"
def helper(n):
if n == 0:
return ""
return helper(n // 2) + str(n % 2)
return helper(n)
print(to_binary_recursive_safe(0)) # "0"
print(to_binary_recursive_safe(10)) # "1010"
Решение 4: Используя побитовые операции
def to_binary_bitwise(n):
"""
Альтернативный подход с побитовыми операциями.
Проверяем каждый бит числа с помощью побитового И (&).
"""
if n == 0:
return "0"
binary = ""
# Находим количество битов
bit_length = n.bit_length() # Встроенный метод
# Проходим по всем битам справа налево
for i in range(bit_length - 1, -1, -1):
# Проверяем бит на позиции i
if n & (1 << i):
binary += "1"
else:
binary += "0"
return binary
print(to_binary_bitwise(10)) # "1010"
print(to_binary_bitwise(255)) # "11111111"
Решение 5: Используя divmod() для изящности
def to_binary_divmod(n):
"""
Использует divmod() для одновременного получения
частного и остатка.
"""
if n == 0:
return "0"
binary = ""
while n > 0:
n, remainder = divmod(n, 2) # (quotient, remainder)
binary = str(remainder) + binary
return binary
print(to_binary_divmod(10)) # "1010"
print(to_binary_divmod(255)) # "11111111"
Сравнение решений
import time
def benchmark(func, n, iterations=100000):
start = time.time()
for _ in range(iterations):
func(n)
end = time.time()
return end - start
n = 1000
print(f"Итеративный (строка): {benchmark(to_binary, n):.4f}s")
print(f"Оптимизированный (список): {benchmark(to_binary_optimized, n):.4f}s")
print(f"Рекурсивный: {benchmark(to_binary_recursive_safe, n):.4f}s")
print(f"divmod: {benchmark(to_binary_divmod, n):.4f}s")
# Результат: версия со списком обычно быстрее строковой версии
Полное решение с тестами
def to_binary(n):
"""Преобразует десятичное число в двоичную строку."""
if n == 0:
return "0"
if n < 0:
# Для отрицательных чисел можно добавить знак
return "-" + to_binary(-n)
binary = ""
while n > 0:
binary = str(n % 2) + binary
n = n // 2
return binary
# Тесты
test_cases = [
(0, "0"),
(1, "1"),
(2, "10"),
(10, "1010"),
(255, "11111111"),
(256, "100000000"),
(1024, "10000000000"),
(-10, "-1010"),
]
for num, expected in test_cases:
result = to_binary(num)
status = "✓" if result == expected else "✗"
print(f"{status} to_binary({num:4}) = {result:12} (ожидается {expected})")
Анализ сложности
Временная сложность:
- O(log n) — количество операций равно количеству битов в числе
- Для числа n нужно ~log₂(n) операций деления
Пространственная сложность:
- O(log n) — длина результирующей строки (~log₂(n) символов)
Рекомендация
Для практического использования выбираю Решение 2 (со списком), так как оно:
- Читаемо и понятно
- Эффективнее строковой версии (O(log n) вместо O((log n)²) из-за конкатенации строк)
- Не требует рекурсии (нет риска StackOverflow)
- Проще для отладки