Бинарная (двоичная) система — это позиционная система счисления с основанием 2: любое число записывается двумя цифрами, 0 и 1. Бинарное представление данных — это запись любой информации (чисел, текста, изображений, звука) в виде последовательности таких нулей и единиц, то есть битов.
Содержание
- Четыре термина, которые часто смешивают
- Преимущества двоичной системы для представления информации
- Один пример: шесть видов данных в битах
- Целые числа
- Отрицательные числа: дополнительный код
- Вещественные числа: IEEE 754
- Текст
- Изображения
- Звук
- Биты не знают, что они значат
- Выводы
- Где применяется / связь с практикой
- FAQ
Основные преимущества двоичной системы для представления информации: два состояния проще и надежнее различать в электронике, чем десять; арифметика и логика сводятся к нескольким простым правилам; одним и тем же способом кодируются данные любого вида. Ниже — коротко о каждом преимуществе, а затем разбор того, как именно разные данные превращаются в биты. Код проверен на Python 3.14.
Четыре термина, которые часто смешивают
| Термин | Что это | Пример |
|---|---|---|
| Двоичная система счисления | Способ записи чисел двумя цифрами | 77 = 1001101 |
| Бит | Один двоичный разряд, значение 0 или 1 | 1 |
| Байт | Группа из 8 битов, 256 разных значений | 01001101 |
| Двоичный код (формат) | Договоренность, что означают биты | UTF-8, IEEE 754, RGB |
Главное различие: система счисления отвечает только за запись чисел. Чтобы записать в битах букву или цвет, нужна еще договоренность — формат, который сопоставляет объекту число, а числу байты. Цепочка всегда одна: объект -> число -> биты.
Преимущества двоичной системы для представления информации
- Надежное различение состояний. Элементу памяти или линии связи достаточно отличать «низкий уровень» от «высокого». Между ними остается большой запас, поэтому небольшая помеха не превращает 0 в 1. При десяти уровнях на том же диапазоне запас был бы в разы меньше.
- Простые элементы. Устройство с двумя устойчивыми состояниями сделать проще и дешевле, чем с десятью: на этом построены и процессоры, и память, и накопители.
- Простая арифметика. Таблица сложения одного разряда — четыре строки (0+0, 0+1, 1+0, 1+1), таблица умножения — тоже четыре. Схемы для таких операций компактны.
- Прямая связь с логикой. 0 и 1 естественно читаются как «ложь» и «истина», поэтому вычисления строятся из логических операций И, ИЛИ, НЕ.
- Универсальность. Число, буква, пиксель и отсчет звука хранятся одинаково — байтами. Одно и то же устройство хранит и передает любые данные.
Главный недостаток касается человека: двоичная запись длинная. Число 255 — это восемь единиц подряд. Поэтому люди читают биты в шестнадцатеричной записи, где одна цифра заменяет четыре бита: 11111111 = FF.
Двоичная система — инженерный выбор, а не единственно возможный: в 1958 году в МГУ построили троичную ЭВМ «Сетунь». Массовой двоичная техника стала именно из-за простоты и надежности элементов.
Один пример: шесть видов данных в битах
Скрипт ниже берет число, отрицательное число, дробь, две буквы, пиксель и отсчет звука и печатает их байты. Его можно скопировать и запустить целиком.
import struct
def bits(data: bytes) -> str:
return " ".join(f"{byte:08b}" for byte in data)
# 1. Целое без знака, 1 байт
print("77 ->", bits((77).to_bytes(1, "big")))
# 2. Отрицательное целое, 1 байт, дополнительный код
print("-77 ->", bits((-77).to_bytes(1, "big", signed=True)))
# 3. Вещественное число, 8 байт, формат IEEE 754 binary64
print("0.1 ->", bits(struct.pack(">d", 0.1)))
# 4. Текст в кодировке UTF-8
print("A ->", bits("A".encode("utf-8")))
print("Я ->", bits("Я".encode("utf-8")))
# 5. Один пиксель: оранжевый цвет в RGB, по байту на канал
print("пиксель ->", bits(bytes([255, 165, 0])))
# 6. Один отсчет звука: 16 бит со знаком
print("отсчет ->", bits(struct.pack(">h", -12345)))
Вывод:
77 -> 01001101
-77 -> 10110011
0.1 -> 00111111 10111001 10011001 10011001 10011001 10011001 10011001 10011010
A -> 01000001
Я -> 11010000 10101111
пиксель -> 11111111 10100101 00000000
отсчет -> 11001111 11000111
В примере байты идут от старшего к младшему: это задают аргумент "big" и знак > в struct.pack. В памяти большинства современных процессоров порядок байтов многобайтного числа обратный, поэтому без явного указания результат зависит от платформы. Дальше — разбор каждой строки.
Целые числа
Каждый разряд двоичного числа — степень двойки. 01001101 = 64 + 8 + 4 + 1 = 77. В одном байте без знака помещаются значения от 0 до 255, в n битах — от 0 до 2^n — 1. Пошаговый перевод между системами разобран в статье о двоичной системе счисления.
Размер хранилища ограничен, и число в него может не поместиться.
print((300).to_bytes(1, "big"))
OverflowError: int too big to convert
Исправление — посчитать нужное число байтов по длине числа в битах:
value = 300
size = max(1, (value.bit_length() + 7) // 8) # для неотрицательного числа; нулю тоже нужен байт
print(size, "байта:", " ".join(f"{b:08b}" for b in value.to_bytes(size, "big")))
2 байта: 00000001 00101100
Python сообщает об ошибке. В языках с целыми фиксированной ширины (C, Java, C#) поведение другое и зависит от языка и типа: значение может молча «завернуться» по модулю 2^n, поэтому диапазон типа проверяют заранее.
Отрицательные числа: дополнительный код
Знака «минус» в битах нет, поэтому отрицательные целые почти везде хранят в дополнительном коде. Чтобы получить -77 в 8 битах, нужно:
- Записать 77: 01001101.
- Инвертировать все биты: 10110010.
- Прибавить единицу: 10110011.
Результат совпадает с выводом скрипта. Старший бит у отрицательных чисел равен 1, а диапазон байта со знаком — от -128 до 127. Удобство этого кода в том, что сложение и вычитание выполняет одна и та же схема: 77 + (-77) дает 00000000 с отброшенным переносом.
Вещественные числа: IEEE 754
Дробные числа хранятся по стандарту IEEE 754. Тип float в Python — это 64-битный формат binary64: 1 бит знака, 11 битов порядка и 52 бита дробной части мантиссы. По сути это запись вида «мантисса, умноженная на степень двойки».
В выводе скрипта для 0.1 виден повторяющийся узор 1001 1001: дробь 0.1 в двоичной системе бесконечная периодическая, как 1/3 в десятичной. В 52 бита помещается только ее округление.
from decimal import Decimal
print(0.1 + 0.2)
print(0.1 + 0.2 == 0.3)
print(Decimal(0.1))
print(0.5 + 0.25 == 0.75)
0.30000000000000004
False
0.1000000000000000055511151231257827021181583404541015625
True
Третья строка — точное значение, которое реально хранится вместо 0.1. Последняя строка показывает границу: дроби, которые раскладываются в сумму степеней двойки (0.5, 0.25, 0.75), хранятся точно. Отсюда практика: вещественные числа сравнивают с допуском, а деньги считают в целых копейках или десятичным типом.
Текст
Текст проходит два шага. Сначала символу сопоставляется номер в наборе Unicode — кодовая точка. Затем кодировка превращает этот номер в байты.
- A -> U+0041 (65) -> 01000001, один байт в UTF-8.
- Я -> U+042F (1071) -> 11010000 10101111, два байта в UTF-8.
Число байтов на символ в UTF-8 переменное, от одного до четырех. Базовая латиница (ASCII) занимает один байт, кириллица — два, большинство эмодзи — четыре. Подробнее об устройстве кодировок — в статье о кодировках символов и UTF-8.
Изображения
Растровое изображение — это сетка пикселей. В распространенной модели RGB с глубиной 8 бит на канал цвет пикселя — три байта: доля красного, зеленого и синего от 0 до 255. Оранжевый из примера — это (255, 165, 0).
Три байта дают 2^24 = 16 777 216 цветов. Кадр 1920×1080 без сжатия занимает 1920 * 1080 * 3 = 6 220 800 байт, около 5,93 МиБ. Форматы вроде PNG и JPEG хранят изображение в сжатом виде, поэтому файлы заметно меньше: PNG сжимает без потерь, JPEG — с потерями, и пиксели после распаковки лишь близки к исходным; бывают и другие глубины цвета и четвертый канал прозрачности.
Звук
Звук — непрерывное колебание, и перед записью его превращают в числа. Устройство много раз в секунду измеряет уровень сигнала (дискретизация) и округляет каждое измерение до целого (квантование). Одно такое число называется отсчетом.
В формате аудио-CD это 44 100 отсчетов в секунду, 16 бит на отсчет, два канала. Секунда звука без сжатия — 44 100 * 2 * 2 = 176 400 байт, минута — около 10,09 МиБ. Отсчет -12345 из примера хранится как целое со знаком в дополнительном коде — так же, как -77, только в двух байтах.
Видео объединяет оба способа: последовательность кадров плюс звуковая дорожка. Без сжатия оно занимало бы слишком много места, поэтому кодеки хранят часть кадров целиком, а остальные — как отличия от соседних.
Биты не знают, что они значат
Одни и те же два байта можно прочитать по-разному.
raw = bytes([0b11010000, 0b10101111])
print(int.from_bytes(raw, "big")) # целое без знака
print(int.from_bytes(raw, "big", signed=True)) # целое со знаком
print(raw.decode("utf-8")) # текст в UTF-8
print(raw.hex(" ")) # те же биты в шестнадцатеричной записи
53423
-12113
Я
d0 af
Смысл байтам придает формат, а не сами биты. Поэтому у файлов есть расширения и заголовки, у переменных — типы, а текст, открытый не в той кодировке, превращается в «кракозябры».
Выводы
- Бинарная система — позиционная система счисления с основанием 2; бинарное представление данных — запись любой информации битами по правилам конкретного формата.
- Преимущества двоичной системы: надежное различение двух состояний, простые элементы, простая арифметика, прямая связь с логикой, единый способ хранения для любых данных. Недостаток — длинная запись, которую люди сокращают шестнадцатеричной.
- Целые числа хранятся как суммы степеней двойки, отрицательные — в дополнительном коде, вещественные — по IEEE 754 с округлением.
- Текст кодируется цепочкой «символ -> кодовая точка -> байты», изображение — числами яркости каналов каждого пикселя, звук — последовательностью отсчетов.
- Одни и те же биты означают разное в разных форматах, поэтому данные всегда читают вместе с их типом или форматом.
Где применяется / связь с практикой
Понимание двоичного представления нужно в повседневных задачах программиста: выбрать тип данных под диапазон значений, объяснить «странный» результат 0.1 + 0.2, прочитать файл в правильной кодировке, разобрать бинарный формат или сетевой пакет, оценить объем данных без сжатия.
Освойте тему на практике
Типы данных, работа с числами, строками, байтами и файлами последовательно разбираются на курсе «Python-разработчик. Базовый уровень». Познакомиться с форматом занятий можно на открытых уроках Otus.
FAQ
Бинарный файл и текстовый файл — в чем разница, если все хранится в битах?
Оба состоят из байтов. Текстовым называют файл, байты которого целиком читаются как символы в некоторой кодировке; в бинарном байты означают числа, пиксели или структуры формата, и текстовый редактор покажет их бессмысленным набором знаков.
Сколько значений помещается в n битов?
Ровно 2^n разных комбинаций: 8 битов — 256, 16 битов — 65 536, 32 бита — 4 294 967 296. Как эти комбинации распределены между положительными и отрицательными числами, зависит от формата.
Килобайт — это 1000 или 1024 байта?
По стандарту приставка «кило» означает 1000, а для 1024 байт введена единица кибибайт (КиБ). На практике часть программ и систем по-прежнему называет килобайтом 1024 байта, поэтому объемы в разных источниках расходятся.



