EssayAI
Блог
Блог
Естественные науки

Дополнительный код: представление отрицательных чисел

11 июня 2026Время чтения: 7 минут
#дополнительный код#отрицательные числа#двоичная система#переполнение#разрядность

Дополнительный код (two's complement) - это способ записывать целые числа со знаком в двоичной системе так, чтобы вычитание превращалось в обычное сложение, а одна и та же схема сумматора работала и с положительными, и с отрицательными числами. Именно поэтому почти все процессоры хранят знаковые целые именно в дополнительном коде, а не в прямом или обратном. Ниже разберём, как записать отрицательное число в фиксированной разрядности, почему старший разряд получает отрицательный вес, как переводить число в код и обратно тремя способами и где в задачах возникает переполнение. Чтобы сразу почувствовать связь между числом и его битами, покрути калькулятор ниже: он показывает дополнительный код в двоичном и шестнадцатеричном виде, вклад каждого разряда и положение числа на кольце кодов.

Зачем нужен дополнительный код

В прямом коде знак числа хранится в старшем бите: 0 - плюс, 1 - минус, а остальные разряды задают модуль. Просто, но неудобно: появляются два нуля (положительный и отрицательный), а вычитание требует отдельной логики сравнения знаков. Дополнительный код избавляется от обоих недостатков. В нём отрицательное число записывается так, что его сложение с положительным даёт правильный результат на том же сумматоре, который складывает беззнаковые числа. Ноль остаётся единственным, а диапазон используется полностью.

Главная идея: при фиксированной разрядности NN бит все коды живут по модулю 2N2^N. Отрицательное число xx представляется тем же кодом, что и беззнаковое 2N+x2^N + x. Например, в 8 битах число −1-1 кодируется как 28−1=2552^8 - 1 = 255, то есть все восемь единиц. Поэтому при переборе кодов от 00 вверх мы доходим до максимума, а затем «переваливаем» в отрицательную область - отсюда и образ кольца.

Счётчик идёт по 4-битному кольцу кодов: 0, 1, 2 ... 7, а затем 1000 переключается на значение -8 и счёт продолжается -7, -6 ... -1, после чего возвращается к 0. Видно, как старший бит переключает знак

Как старший бит получает отрицательный вес

Самое короткое определение дополнительного кода: это обычное позиционное двоичное представление, в котором вес старшего разряда взят со знаком минус. Для NN бит значение числа равно

x=−bN−1⋅2N−1+∑k=0N−2bk⋅2k,x = -b_{N-1}\cdot 2^{N-1} + \sum_{k=0}^{N-2} b_k\cdot 2^{k},

где bkb_k - значение kk-го бита. Все младшие разряды дают привычные положительные веса 20,21,…,2N−22^0, 2^1, \dots, 2^{N-2}, и только старший разряд bN−1b_{N-1} весит −2N−1-2^{N-1}. Если он равен нулю, число положительно и совпадает с беззнаковым; если единице - к сумме добавляется большое отрицательное слагаемое, и число уходит в минус.

Возьмём канонический пример: 8-битный код 1101001111010011. Старший бит равен 1, значит вклад старшего разряда −27=−128-2^7 = -128. Остальные единицы стоят в разрядах 6, 4, 1 и 0, давая 64+16+2+1=8364 + 16 + 2 + 1 = 83. Итог: −128+83=−45-128 + 83 = -45. Тот же код, прочитанный как беззнаковое число, равен 211211, а в шестнадцатеричной записи это 0xD30xD3.

Веса разрядов 8-битного числа: старший разряд подписан как минус 128, остальные как 64, 32, 16, 8, 4, 2, 1, активные биты выделены
Веса разрядов 8-битного числа: старший разряд подписан как минус 128, остальные как 64, 32, 16, 8, 4, 2, 1, активные биты выделены

На схеме весов хорошо видно, почему дополнительный код «самосогласован»: чтение по весам и есть обратное преобразование. Не нужно отдельно смотреть на знак - достаточно просуммировать вклады разрядов, помня, что самый левый из них отрицательный.

Как перевести число в дополнительный код

Для отрицательного числа есть три эквивалентных пути, и в калькуляторе они дают один и тот же результат.

Первый - по формуле остатка. Код отрицательного числа xx равен беззнаковому представлению величины 2N−∣x∣2^N - |x|. Для x=−45x = -45 и N=8N = 8 это 256−45=211256 - 45 = 211, то есть 11010011211010011_2.

Второй - инверсия и плюс единица, самый удобный «ручной» способ. Записываем модуль числа в обычном двоичном виде, инвертируем все биты (получаем обратный код), затем прибавляем единицу:

45=001011012  →инверсия  110100102  →+1  110100112.45 = 00101101_2 \;\xrightarrow{\text{инверсия}}\; 11010010_2 \;\xrightarrow{+1}\; 11010011_2.

Третий - через подбор по весам: подобрать единицы в разрядах так, чтобы их веса (с отрицательным старшим) дали нужное число. На практике им пользуются для проверки, а не для расчёта.

Перевод -45 в дополнительный код: модуль 00101101, инверсия 11010010, прибавление единицы дает 11010011
Перевод -45 в дополнительный код: модуль 00101101, инверсия 11010010, прибавление единицы дает 11010011

Чтобы перевести любое своё число в код и обратно, задай разрядность и подвинь ползунок в калькуляторе выше: он покажет двоичную и шестнадцатеричную запись, разложение по весам и положение числа на кольце кодов.

Диапазон представимых чисел и его несимметричность

При NN битах в дополнительном коде помещаются числа от −2N−1-2^{N-1} до 2N−1−12^{N-1}-1:

−2N−1≤x≤2N−1−1.-2^{N-1} \le x \le 2^{N-1}-1.

Для 8 бит это от −128-128 до 127127, для 16 бит - от −32768-32768 до 3276732767. Диапазон несимметричен: отрицательных чисел на одно больше, чем положительных. Причина проста - один из 2N2^N кодов занят нулём, и он лежит в «положительной» половине, поэтому самому большому по модулю отрицательному числу −2N−1-2^{N-1} нет положительной пары. Отсюда известная ловушка: модуль числа −128-128 в 8 битах нельзя представить как +128+128, а попытка взять −(−128)-(-128) снова даёт −128-128.

Сложение, вычитание и переполнение

Главная награда за дополнительный код - арифметика. Чтобы вычесть, достаточно прибавить дополнительный код вычитаемого: a−b=a+(код(−b))a - b = a + (\text{код}(-b)). Перенос из старшего разряда просто отбрасывается, потому что вычисления идут по модулю 2N2^N. Это и позволяет одному сумматору обслуживать оба знака.

Опасность одна - переполнение. Оно возникает, когда истинный результат выходит за диапазон [−2N−1, 2N−1−1][-2^{N-1},\, 2^{N-1}-1]. Признак переполнения: при сложении двух чисел одного знака получился результат противоположного знака. Например, в 8 битах 100+50=150100 + 50 = 150, но 150>127150 > 127, поэтому код «перескакивает» через границу и читается как 150−256=−106150 - 256 = -106. Программный или аппаратный флаг переполнения как раз ловит ситуацию, когда перенос в старший разряд и перенос из него не совпадают.

Частые ошибки

  • Инверсия без прибавления единицы. После инвертирования битов получается обратный код, а не дополнительный. Единицу прибавлять обязательно, иначе число будет меньше на единицу.
  • Игнорирование разрядности. Дополнительный код не существует «вообще»: −1-1 - это 11111111 в 4 битах и 1111111111111111 в 8 битах. Без указания NN запись бессмысленна.
  • Перевод старшего бита как обычного. Старший разряд весит −2N−1-2^{N-1}, а не +2N−1+2^{N-1}. Если прочитать его с плюсом, отрицательные числа превратятся в большие положительные.
  • Симметричный диапазон. Граница не ±2N−1\pm 2^{N-1}, а от −2N−1-2^{N-1} до 2N−1−12^{N-1}-1. Число −2N−1-2^{N-1} есть, а его положительной пары нет.
  • Незамеченное переполнение. Отброшенный перенос - это норма, а вот смена знака при сложении одинаковых знаков - сигнал, что результат недостоверен.

FAQ

Как перевести отрицательное число в дополнительный код вручную? Запишите модуль числа в двоичном виде в нужной разрядности, инвертируйте все биты и прибавьте единицу. Для −45-45 в 8 битах: 45=0010110145 = 00101101, инверсия 1101001011010010, плюс единица - 1101001111010011.

Почему старший бит называют знаковым, если у него есть и вес? Потому что он одновременно указывает знак и вносит вклад −2N−1-2^{N-1} в значение. У положительных чисел он равен нулю, у отрицательных - единице, но это не отдельный флаг, а полноценный разряд с отрицательным весом.

Чем дополнительный код лучше прямого и обратного? В нём единственный ноль и не нужна отдельная логика для вычитания: оно сводится к сложению. Прямой и обратный коды дают два нуля и требуют коррекции при переносе, поэтому в процессорах прижился именно дополнительный код.

Коротко

Дополнительный код представляет знаковые целые так, что вычитание становится сложением, а старший разряд весит −2N−1-2^{N-1}. Отрицательное число получают по формуле 2N−∣x∣2^N - |x| или инверсией битов модуля с прибавлением единицы; обратное чтение - это сумма по весам разрядов. Диапазон при NN битах равен от −2N−1-2^{N-1} до 2N−1−12^{N-1}-1 и несимметричен, а выход за него даёт переполнение, заметное по неожиданной смене знака.

Доверьте текст нейросети EssayAI

Открыть EssayAI

Бесплатно, на русском языке и без VPN

Читайте также

Кодирование звука: частота дискретизации и теорема Найквиста

Кодирование звука: частота дискретизации и теорема Найквиста

Как работает кодирование звуковой информации: частота дискретизации, теорема Найквиста-Шеннона, разрядность, алиасинг и расчёт размера аудиофайла с примерами.

11 июня 20267 минут
Представление чисел в обратном коде: перевод и формула

Представление чисел в обратном коде: перевод и формула

Как перевести число в обратный код: правило инвертирования разрядов, формула через дополнение до всех единиц, диапазон значений, два нуля и сложение с циклическим переносом.

11 июня 20268 минут
Дополнительный код: представление отрицательных чисел

Дополнительный код: представление отрицательных чисел

Как работает дополнительный код в двоичных системах: диапазон значений, перевод отрицательного числа, разбор по весам разрядов, переполнение и типичные ошибки в задачах.

11 июня 20267 минут
Адаптивная радиация: как предок даёт множество видов

Адаптивная радиация: как предок даёт множество видов

Адаптивная радиация: почему одна линия быстро расходится по экологическим нишам, примеры вьюрков и цихлид, условия процесса, таблица и отличия от простого расселения.

1 октября 20268 минут
Активные формы кислорода: виды, источники и защита

Активные формы кислорода: виды, источники и защита

Активные формы кислорода: супероксид, пероксид водорода, гидроксильный радикал и синглетный кислород. Источники АФК, реакция Фентона, ферменты защиты и редокс-сигналинг.

1 октября 20269 минут
Аминоацил-тРНК-синтетаза: как заряжается тРНК

Аминоацил-тРНК-синтетаза: как заряжается тРНК

Как аминоацил-тРНК-синтетаза выбирает аминокислоту и тРНК, зачем реакция идёт в два этапа, почему тратятся две макроэргические связи и как работает редактирование.

1 октября 20268 минут