EssayAI
Блог
Блог
Математика и алгоритмы

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

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

Обратный код (ones complement) - один из трёх школьных и вузовских способов хранить знак целого числа в двоичной записи, наряду с прямым и дополнительным кодом. Идея простая: положительные числа записываются как обычно, а у отрицательного числа инвертируют (меняют на противоположные) все разряды, кроме знакового. Это промежуточный шаг к дополнительному коду, которым реально пользуются процессоры, но именно на обратном коде удобнее всего понять, откуда берётся правило «прибавить единицу» и почему у нуля в такой арифметике целых два представления. Ниже разберём точную формулу перевода, диапазон значений и то, как в обратном коде складывают числа - через циклический (end-around) перенос. Покрути калькулятор ниже: он показывает прямой и обратный код по разрядам, а в режиме сложения - сам перенос из знакового разряда обратно в младший.

Зачем нужен обратный код

Самый наивный способ хранить знак - прямой код: взять двоичную запись модуля числа и добавить впереди один разряд-флаг (0 - плюс, 1 - минус). У прямого кода сразу два неудобства. Во-первых, ноль получает два разных представления: 00000000200000000_2 (+0) и 10000000210000000_2 (−0), которые формально различаются, хотя по смыслу это одно и то же число. Во-вторых, для сложения разнознаковых чисел в прямом коде нужна отдельная схема вычитания - нельзя просто сложить разряды столбиком, как для положительных чисел.

Обратный код решает вторую проблему лишь частично: сложение уже можно делать обычным двоичным сложением, но с оговоркой про перенос из старшего разряда (см. ниже), а два представления нуля остаются. Именно поэтому в реальных процессорах используется дополнительный код - но обратный код исторически и методически важен: он показывает, что «отрицательное число» - это просто другой двоичный узор, полученный по чёткому правилу, а не какая-то особая сущность.

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

Правило перевода короткое. Пусть разрядность слова - NN бит, старший разряд - знаковый.

  • Если число X0X \ge 0, обратный код совпадает с прямым: знаковый разряд 0, а остальные N1N-1 разрядов - обычная двоичная запись XX.
  • Если X<0X < 0, знаковый разряд становится 1, а все N1N-1 разрядов модуля инвертируются: каждый 0 меняется на 1, а каждая 1 - на 0.
Число проходит от положительного значения через ноль к отрицательному: пока X ≥ 0, обратный код совпадает с прямым, а как только знак меняется на минус, все разряды модуля инвертируются и знаковый разряд становится 1

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

U=(2N1)X(X<0).U = (2^N - 1) - |X| \qquad (X < 0).

Возьмём X=47X = -47 при N=8N = 8: модуль X=47|X| = 47, а 281=2552^8 - 1 = 255. Тогда U=25547=208U = 255 - 47 = 208, что в двоичной записи даёт 11010000211010000_2 - это и есть обратный код числа 47-47 в 8 битах. Прямой код того же числа - 10101111210101111_2: сравните разряды и увидите, что все семь младших разрядов действительно инвертированы, а знаковый остался 1.

Диапазон значений и два нуля

Обратный код с NN-битным словом хранит только N1N - 1 разряд под модуль числа, поэтому диапазон значений симметричный:

(2N11)    X    2N11.-(2^{N-1} - 1) \;\le\; X \;\le\; 2^{N-1} - 1.

Для 8 бит это от 127-127 до +127+127, для 4 бит - от 7-7 до +7+7, для 16 бит - от 32767-32767 до +32767+32767. Симметрия - прямое следствие того, что оба крайних кода, 00000\ldots0 и 11111\ldots1, кодируют одно и то же значение - ноль: «плюс ноль» и «минус ноль».

Числовая ось обратного кода для 8 бит: коды 00000000 и 11111111 совпадают в точке 0, а фигурная скобка измеряет диапазон от -127 до +127
Числовая ось обратного кода для 8 бит: коды 00000000 и 11111111 совпадают в точке 0, а фигурная скобка измеряет диапазон от -127 до +127

Наличие двух нулей - не просто теоретическая странность: при сравнении кодов на равенство нулю схема должна проверять оба варианта, а свободный код 11111\ldots1 означает, что из 2N2^N возможных комбинаций разрядов используется только 2N12^N - 1 различное значение. Это одна из причин, по которой обратный код не стал стандартом для процессоров.

Сложение чисел в обратном коде: циклический перенос

Главное практическое умение с обратным кодом - сложение с учётом циклического (по-другому - «сквозного», end-around) переноса. Алгоритм такой:

  1. Перевести оба числа в обратный код разрядностью NN бит.
  2. Сложить оба кода как обычные беззнаковые двоичные числа разрядностью NN бит.
  3. Если при сложении возник перенос из старшего (знакового) разряда за пределы разрядной сетки - этот перенос не отбрасывается, а прибавляется обратно к младшему разряду результата.
  4. Полученные NN разрядов - обратный код суммы; декодировать его обратно в десятичное число можно по той же формуле, что и одиночное число.
Сложение -5 и -3 в 8-битном обратном коде: биты складываются как обычное число, перенос выходит за девятый разряд и по кольцевой стрелке возвращается в младший разряд результата

Разберём на числах A=5A = -5 и B=3B = -3 при N=8N = 8. Обратный код AA - 11111010211111010_2, обратный код BB - 11111100211111100_2. Их сумма как беззнаковых 8-битных чисел даёт девять значащих разрядов: 11111011021\,11110110_2. Девятый (лишний) разряд - это и есть циклический перенос: его отбрасываем из разрядной сетки, но прибавляем единицей к оставшимся восьми разрядам:

111101102+1=111101112.11110110_2 + 1 = 11110111_2.

Декодируем результат: знаковый разряд 1, значит это отрицательное число, а беззнаковое значение всей строки 11110111211110111_2 равно 247247. По формуле X=U(2N1)=247255=8X = U - (2^N - 1) = 247 - 255 = -8 - ровно то, что мы и ожидали от 5+(3)-5 + (-3).

Важная оговорка: если оба слагаемых одного знака, а знак результата после переноса получился другим - это переполнение, а не корректный ответ. Обратный код (как и любой NN-битный формат) не может представить сумму, которая по модулю превышает 2N112^{N-1} - 1.

Точно так же, только по другому правилу переноса, устроено сложение в дополнительном коде - там лишний перенос из старшего разряда просто отбрасывается без обратного прибавления, а диапазон уже несимметричный (2N1-2^{N-1} до 2N112^{N-1}-1), потому что у нуля остаётся только одно представление.

Обратный код и дополнительный код: в чём разница

Обратный код и дополнительный код почти всегда путают, потому что дополнительный код получается из обратного добавлением единицы: Xдоп=Xобр+1X_{доп} = X_{обр} + 1 (для отрицательных чисел). Из-за этой единицы у дополнительного кода нет второго представления нуля, а перенос из старшего разряда при сложении можно просто отбрасывать - никакого циклического возврата не требуется. Обратный код проще для понимания «инвертировали разряды - и готово», но платит за эту простоту двумя нулями и дополнительным шагом при сложении.

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

  • Инвертирование знакового разряда. В обратном коде знаковый разряд отрицательного числа остаётся 1, инвертируются только оставшиеся N1N-1 разрядов модуля.
  • Забытый циклический перенос. Если при сложении обратных кодов возник перенос из старшего разряда, его нельзя просто отбросить - он обязан вернуться в младший разряд результата.
  • Путаница с дополнительным кодом. Правило переноса разное: в обратном коде перенос прибавляется обратно, в дополнительном - отбрасывается без остатка.
  • Игнорирование двух нулей. Код 11111\ldots1 - это тоже ноль (−0), а не «минус самое маленькое число».
  • Проверка на переполнение по знакам. Если оба слагаемых одного знака, а знак суммы после переноса получился другим - это переполнение, результат недостоверен.

FAQ

Чем обратный код отличается от прямого? В прямом коде отрицательное число - это просто модуль с флагом знака 1 в старшем разряде, остальные разряды не меняются. В обратном коде дополнительно инвертируются все разряды модуля, кроме знакового.

Как декодировать обратный код без ручного инвертирования битов? Прочитайте все NN разрядов как беззнаковое число UU. Если U<2N1U < 2^{N-1} - это и есть искомое число. Если U2N1U \ge 2^{N-1} - искомое число равно U(2N1)U - (2^N - 1) и оно отрицательное.

Почему у нуля два представления именно в обратном коде? Код из одних нулей даёт U=0U = 0, то есть X=0X = 0 («плюс ноль»). Код из одних единиц даёт U=2N1U = 2^N - 1, а по формуле X=U(2N1)X = U - (2^N-1) это тоже X=0X = 0 («минус ноль»). Оба кода законны по правилу перевода и оба декодируются в один и тот же ноль - отсюда и двойственность. Дополнительный код убирает её за счёт добавленной единицы.

Коротко

Обратный код хранит отрицательное число как дополнение его модуля до «всех единиц» разрядной сетки: U=(2N1)XU = (2^N-1) - |X|, знаковый разряд при этом равен 1, а остальные разряды модуля инвертированы. Диапазон значений симметричен - от (2N11)-(2^{N-1}-1) до 2N112^{N-1}-1, а ноль представлен двумя разными кодами. При сложении чисел в обратном коде перенос из старшего разряда не отбрасывается, а возвращается в младший разряд - это и называют циклическим переносом. Именно ради избавления от двух нулей и лишнего шага сложения на практике перешли на дополнительный код.

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

Открыть EssayAI

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

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

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

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

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

11 июня 20267 минут
Формула Хартли: как посчитать количество информации

Формула Хартли: как посчитать количество информации

Формула Хартли простыми словами: как посчитать количество информации через число равновероятных исходов, зачем округлять log2(N) вверх и как найти объём сообщения по мощности алфавита.

11 июня 20267 минут
Построение логической схемы по выражению: алгоритм

Построение логической схемы по выражению: алгоритм

Как построить логическую схему по логическому выражению: порядок сборки элементов И, ИЛИ, НЕ по приоритету операций, обозначения ГОСТ и разбор частых ошибок студентов.

11 июня 20268 минут
Кодирование текста в ASCII: коды, биты и объём

Кодирование текста в ASCII: коды, биты и объём

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

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

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

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

11 июня 20267 минут
Атрибуты сущности в ER-модели: пять типов и примеры

Атрибуты сущности в ER-модели: пять типов и примеры

Разбираем пять типов атрибутов сущности в ER-модели: простой, составной, ключевой, многозначный, производный, с примерами и переходом к столбцам и таблицам реляционной схемы.

7 июля 20269 минут