Как представить число в двоичной системе средствами Python
Перевод чисел в двоичный вид в Python
В Python для перевода целого числа в двоичную строку есть несколько путей. Выбор зависит от задачи: быстрое преобразование, форматирование с ведущими нулями, обучение алгоритму, работа с отрицательными числами или IEEE 754. Ниже приведены основной вариант и альтернативы с примерами.
Основной вариант: функция bin
Встроенная функция bin принимает целое число и возвращает строку с префиксом 0b. Для положительных чисел результат содержит двоичные цифры без ведущих нулей, кроме нуля. Для отрицательных чисел знак выносится перед префиксом.
number = 42
binary = bin(number)
print(binary)
print(binary[2:])
print(bin(0))
print(bin(-42))
print(bin(255))
16 система счисления python (перевод в шестнадцатеричную систему в python)
0b101010 101010 0b0 -0b101010 0b11111111
перевод в 2 систему python (перевод числа в двоичную систему в python)
Функция bin работает только с целыми числами. Для float появляется TypeError. Префикс 0b удобен для обратного преобразования через int(..., 2).
Как получить двоичную строку без префикса через format и f-строки?
Функция format и f-строки принимают спецификатор b. Этот способ дает строку без префикса и позволяет задавать ширину, выравнивание и ведущие нули.
n = 42
print(format(n, 'b'))
print(f'{n:b}')
print(f'{n:08b}')
print(format(n, '>10b'))
print(format(-42, 'b'))
перевод в десятичную систему счисления python (перевод числа в десятичную систему счисления в python)
101010
101010
00101010
101010
-101010
перевод в троичную систему python (перевод числа в троичную систему в python)
Спецификатор 08b означает ширину 8 и заполнение нулями слева. Если число не помещается, ширина увеличивается. Для отрицательных чисел знак занимает отдельную позицию, а двоичные цифры не становятся дополнительным кодом.
Как перевести число в двоичную систему с помощью ручного деления на 2?
Алгоритм повторяет школьный метод: число делится на 2, остатки записываются, затем последовательность остатков переворачивается. Такой вариант полезен для понимания связи между десятичной и двоичной системами.
def to_binary_division(number):
if number == 0:
return '0'
sign = '-' if number < 0 else ''
n = abs(number)
bits = []
while n > 0:
bits.append(str(n % 2))
n //= 2
return sign + ''.join(reversed(bits))
print(to_binary_division(42))
print(to_binary_division(255))
print(to_binary_division(-42))
print(to_binary_division(0))
функция перевода систем счисления python (функция перевода в любую систему счисления в python)
101010 11111111 -101010 0
Ключевые моменты: отдельная обработка нуля, работа с модулем числа для знака, обратный порядок остатков. Без переворота получается инвертированная строка.
Как выполнить перевод через битовые операции и сдвиг вправо?
Битовый сдвиг n >> 1 делит число на 2, а n & 1 извлекает младший бит. Этот метод ближе к низкоуровневым операциям и часто применяется в задачах с битовыми масками.
def to_binary_bitshift(number):
if number == 0:
return '0'
sign = '-' if number < 0 else ''
n = abs(number)
bits = []
while n:
bits.append(str(n & 1))
n >>= 1
return sign + ''.join(reversed(bits))
print(to_binary_bitshift(42))
print(to_binary_bitshift(255))
print(to_binary_bitshift(-42))
print(to_binary_bitshift(0))
101010 11111111 -101010 0
Для отрицательных чисел в Python бесконечное знаковое расширение, поэтому прямое применение сдвига без abs дает неожиданные результаты. Модуль числа и отдельный знак решают эту задачу.
Как получить двоичное представление фиксированной длины с ведущими нулями?
Фиксированная длина нужна для протоколов, дампов, таблиц и битовых полей. В Python ширина задается в спецификаторе формата, например 08b или 016b.
values = [0, 5, 42, 255, 256]
for n in values:
print(f'{n:08b}')
00000000 00000101 00101010 11111111 100000000
Если число требует больше битов, чем указанная ширина, строка становится длиннее. Для отрицательных чисел формат 08b не создает дополнительный код, а добавляет знак. Дополнительный код получается через маску.
def twos_complement(value, bits=8):
mask = (1 << bits) - 1
return format(value & mask, f'0{bits}b')
print(twos_complement(5))
print(twos_complement(-5))
print(twos_complement(-1))
00000101 11111011 11111111
Как перевести вещественное число в двоичный вид?
Для float встроенная функция bin не работает. Один из вариантов - разложить число на целую и дробную части. Другой вариант - получить биты IEEE 754 через модуль struct.
def float_to_binary_manual(value, precision=12):
if value == 0:
return '0.0'
sign = '-' if value < 0 else ''
value = abs(value)
integer = int(value)
fraction = value - integer
int_part = bin(integer)[2:]
frac_bits = []
for _ in range(precision):
fraction *= 2
bit = int(fraction)
frac_bits.append(str(bit))
fraction -= bit
if fraction == 0:
break
if frac_bits:
frac_str = ''.join(frac_bits)
return f'{sign}{int_part}.{frac_str}'
return f'{sign}{int_part}.0'
print(float_to_binary_manual(10.25))
print(float_to_binary_manual(0.1, 20))
print(float_to_binary_manual(-3.75))
1010.01 0.00011001100110011001 -11.11
Дробная часть часто не имеет конечной двоичной записи. Например, 0.1 в двоичном виде является периодической дробью. Параметр precision ограничивает количество битов после точки.
import struct
def float_to_bin64(value):
packed = struct.pack('>d', value)
integer = int.from_bytes(packed, 'big')
return format(integer, '064b')
print(float_to_bin64(10.25))
print(float_to_bin64(-0.5))
0100000000100100100000000000000000000000000000000000000000000000 1011111111100000000000000000000000000000000000000000000000000000
Как перевести массив чисел в двоичные строки?
Для списков и других последовательностей удобны списковые включения и функция map. Результат можно сразу форматировать с нужной шириной.
numbers = [0, 1, 2, 3, 5, 8, 13]
binaries = [bin(n)[2:] for n in numbers]
print(binaries)
padded = [f'{n:08b}' for n in numbers]
print(padded)
mapped = list(map(lambda n: format(n, 'b'), numbers))
print(mapped)
['0', '1', '10', '11', '101', '1000', '1101'] ['00000000', '00000001', '00000010', '00000011', '00000101', '00001000', '00001101'] ['0', '1', '10', '11', '101', '1000', '1101']
Для отрицательных чисел списковое включение с bin сохраняет знак, а формат с шириной также сохраняет знак. Дополнительный код требует отдельной функции с маской.
Типичные ошибки и затруднения
- Лишний префикс 0b: результат
binсодержит0b, для чистой двоичной строки применяется срез[2:]. - Отрицательные числа:
bin(-5)возвращает'-0b101', а не'11111011'. Дополнительный код появляется только при явной маске. - Пропуск нуля: циклы
while n > 0иwhile nне выполняются для нуля, поэтому нужна отдельная ветка. - Обратный порядок: остатки от деления на 2 и младшие биты сначала идут в обратном порядке, затем строка переворачивается.
- Бесконечная дробь: многие десятичные дроби не имеют конечной двоичной записи, ограничение точности обязательно.
- Тип float:
binиformat(..., 'b')не принимаютfloat, для них нужныstructили ручное разложение. - Ширина меньше числа: спецификатор
04bне обрезает число, а только задает минимальную ширину.
Расширенные примеры перевода чисел в двоичный формат
Пример 1. Вывод bin для разных чисел
numbers = [0, 1, 2, 7, 255, 256, -1, -42]
for n in numbers:
print(n, bin(n), bin(n)[2:])
0 0b0 0 1 0b1 1 2 0b10 10 7 0b111 111 255 0b11111111 11111111 256 0b100000000 100000000 -1 -0b1 -1 -42 -0b101010 -101010
Пример 2. Спецификаторы формата для ширины и выравнивания
n = 42
print(f'{n:b}')
print(f'{n:#b}')
print(f'{n:08b}')
print(f'{n:>12b}')
print(f'{n:0>12b}')
print(f'{n:0<12b}')
101010
0b101010
00101010
101010
000000101010
101010000000
Пример 3. Длина через bit_length
n = 42
bits = n.bit_length()
print(bits)
print(f'{n:0{bits}b}')
print(f'{n:016b}')
6 101010 0000000000101010
Пример 4. Дополнительный код для диапазона значений
def to_twos_complement(value, bits=8):
mask = (1 << bits) - 1
return format(value & mask, f'0{bits}b')
for v in [5, -5, 0, -1, 127, -128, 128]:
print(v, to_twos_complement(v))
5 00000101 -5 11111011 0 00000000 -1 11111111 127 01111111 -128 10000000 128 10000000
Пример 5. Ручное преобразование через divmod
def to_binary_divmod(number):
if number == 0:
return '0'
sign = '-' if number < 0 else ''
n = abs(number)
parts = []
while n:
n, remainder = divmod(n, 2)
parts.append(str(remainder))
return sign + ''.join(reversed(parts))
for n in [42, 255, 256, -42, 0]:
print(n, to_binary_divmod(n))
42 101010 255 11111111 256 100000000 -42 -101010 0 0
Пример 6. Рекурсивный перевод в двоичную строку
def to_binary_recursive(n):
if n == 0:
return '0'
if n < 0:
return '-' + to_binary_recursive(-n)
if n == 1:
return '1'
return to_binary_recursive(n // 2) + str(n % 2)
for n in [0, 1, 2, 42, -42]:
print(n, to_binary_recursive(n))
0 0 1 1 2 10 42 101010 -42 -101010
Пример 7. Перевод через сдвиг и маску
def to_binary_shift(n):
if n == 0:
return '0'
sign = '-' if n < 0 else ''
n = abs(n)
bits = []
while n:
bits.append(str(n & 1))
n >>= 1
return sign + ''.join(reversed(bits))
for n in [1, 2, 3, 42, -42, 0]:
print(n, to_binary_shift(n))
1 1 2 10 3 11 42 101010 -42 -101010 0 0
Пример 8. IEEE 754 для 64-битных float
import struct
def float_to_bin64(value):
packed = struct.pack('>d', value)
integer = int.from_bytes(packed, 'big')
return format(integer, '064b')
for v in [10.25, -0.5, 0.0, 1.0]:
print(v, float_to_bin64(v))
10.25 0100000000100100100000000000000000000000000000000000000000000000 -0.5 1011111111100000000000000000000000000000000000000000000000000000 0.0 0000000000000000000000000000000000000000000000000000000000000000 1.0 0011111111110000000000000000000000000000000000000000000000000000
Пример 9. Разложение float на целую и дробную части
def float_to_binary_manual(value, precision=12):
if value == 0:
return '0.0'
sign = '-' if value < 0 else ''
value = abs(value)
integer = int(value)
fraction = value - integer
int_part = bin(integer)[2:]
frac_bits = []
for _ in range(precision):
fraction *= 2
bit = int(fraction)
frac_bits.append(str(bit))
fraction -= bit
if fraction == 0:
break
if frac_bits:
frac_str = ''.join(frac_bits)
return f'{sign}{int_part}.{frac_str}'
return f'{sign}{int_part}.0'
for v in [10.25, 0.1, 0.5, -3.75]:
print(v, float_to_binary_manual(v))
10.25 1010.01 0.1 0.000110011001 0.5 0.1 -3.75 -11.11
Пример 10. numpy.binary_repr
import numpy as np
values = [0, 5, -5, 42]
for v in values:
print(v, np.binary_repr(v))
print(np.binary_repr(-5, width=8))
print(np.binary_repr(5, width=8))
0 0 5 101 -5 -101 42 101010 11111011 00000101
Пример 11. Обратное преобразование из двоичной строки
binary_strings = ['0', '1', '10', '101010', '11111111']
for s in binary_strings:
print(s, int(s, 2))
0 0 1 1 10 2 101010 42 11111111 255
Пример 12. Байты в двоичные строки
data = b'\x00\x0f\x10\xff'
for byte in data:
print(byte, format(byte, '08b'))
0 00000000 15 00001111 16 00010000 255 11111111
Пример 13. Группировка битов через подчеркивание
n = 0b1111000011110000
print(format(n, 'b'))
print(format(n, '_b'))
print(format(n, '#_b'))
1111000011110000 1111_0000_1111_0000 0b1111_0000_1111_0000
Пример 14. Извлечение битов по индексам
n = 42
bits = []
for i in range(n.bit_length() - 1, -1, -1):
bits.append(str((n >> i) & 1))
print(''.join(bits))
101010
Пример 15. Таблица чисел от 0 до 15
numbers = list(range(16))
for n in numbers:
print(f'{n:>3}: {n:04b}')
0: 0000 1: 0001 2: 0010 3: 0011 4: 0100 5: 0101 6: 0110 7: 0111 8: 1000 9: 1001 10: 1010 11: 1011 12: 1100 13: 1101 14: 1110 15: 1111
Пример 16. Пользовательская функция с проверкой типа
def int_to_binary(value, width=0, prefix=False):
if not isinstance(value, int):
raise TypeError('value must be int')
if value < 0:
raise ValueError('negative values are not supported in this example')
result = format(value, 'b')
if width:
result = result.zfill(width)
if prefix:
result = '0b' + result
return result
print(int_to_binary(42))
print(int_to_binary(42, width=8))
print(int_to_binary(42, width=8, prefix=True))
101010 00101010 0b00101010