Что такое «Дополнение 2»?

434

Я в компьютерных системах и , конечно, были изо всех сил , в частности, с дополнением до двух . Я хочу понять это, но все, что я прочитал, не принесло мне картину. Я прочитал статью в Википедии и другие статьи, включая мой учебник .

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

Я надеюсь на четкое и краткое определение , которое легко понять программисту.

Frank V
источник

Ответы:

628

Дополнение Two - это умный способ хранения целых чисел, поэтому общие математические задачи очень просты для реализации.

Чтобы понять, вы должны думать о числах в двоичном виде.

Это в основном говорит,

  • для нуля используйте все 0.
  • для целых положительных чисел начните отсчет максимум с 2 (количество битов - 1) -1.
  • для отрицательных целых чисел сделайте то же самое, но поменяйте местами 0 и 1 (поэтому вместо того, чтобы начинать с 0000, начните с 1111 - это часть «дополнения»).

Давайте попробуем это с мини-байтом в 4 бита (назовем это клоком - 1/2 байта).

  • 0000 - нуль
  • 0001 - один
  • 0010 - два
  • 0011 - три
  • 0100до 0111четырех до семи

Это так далеко, как мы можем пойти в позитивах. 2 3 -1 = 7.

Для негативов:

  • 1111 - отрицательный
  • 1110 - отрицательный два
  • 1101 - отрицательная тройка
  • 1100до 1000- отрицательный четыре до отрицательного восемь

Обратите внимание, что вы получаете одно дополнительное значение для негативов ( 1000= -8), которое вы не получаете для позитивов. Это потому, что 0000используется для нуля. Это можно считать числовой линией компьютеров.

Различение положительных и отрицательных чисел

При этом первый бит получает роль «знакового» бита, поскольку его можно использовать для различения неотрицательных и отрицательных десятичных значений. Если старшим значащим битом является 1двоичный, то можно сказать, что двоичный бит является отрицательным, а если, как если бы старший значащий бит (самый левый) был 0, можно сказать, что десятичное значение неотрицательно.

Отрицательные числа «одного дополнения» просто переворачивают знаковый бит, а затем отсчитывают от 0. Но этот подход имеет дело с интерпретацией 1000«отрицательного нуля», что сбивает с толку. Обычно вам приходится беспокоиться об этом только при работе с оборудованием.

lavinio
источник
148
Вероятно, лучшая часть дополнения двух состоит в том, как это упрощает математику. Попробуйте сложить 2 (0010) и -2 (1110) вместе, и вы получите 10000. Наиболее значимый бит - это переполнение, поэтому результат на самом деле равен 0000. Почти как магия, 2 + -2 = 0.
Наафф
96
Другое преимущество, кроме простого сложения и вычитания, состоит в том, что дополнение 2s имеет только один ноль. Если бы вы использовали простой знаковый бит, скажем, используя 0001 для представления +1 и 1001 для представления -1, у вас было бы два нуля: 0000 ("+0") и 1000 ("-0"). Это настоящая боль сзади.
Йорг Миттаг
26
Признательность за это, а также за объяснение того, почему отрицательные значения имеют больший диапазон положительных. Я искал причину разницы в дальности.
Эшвин
2
Разве вы не должны сказать «для отрицательных целых чисел, делайте то же самое, но делайте обратный отсчет и меняйте роль 0 и 1»
Корай Тугай
1
Удивительно. Добавлены дополнительные части преобразования битов в отрицательное целое число.
Сурадж Джейн
340

Интересно, можно ли объяснить это лучше, чем статья в Википедии?

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

Сначала рассмотрим целое число без знака, хранящееся в 4 битах. Вы можете иметь следующее

0000 = 0
0001 = 1
0010 = 2
...
1111 = 15

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

Величина знака и избыточное обозначение

Для хранения отрицательных чисел вы можете попробовать несколько вещей. Во-первых, вы можете использовать обозначение величины знака, которое назначает первый бит как знаковый бит для представления +/-, а оставшиеся биты для представления величины. Таким образом, снова используя 4 бита и предполагая, что 1 означает - и 0 означает +, тогда у вас есть

0000 = +0
0001 = +1
0010 = +2
...
1000 = -0
1001 = -1
1111 = -7

Итак, вы видите проблему там? У нас есть положительные и отрицательные 0. Большая проблема сложения и вычитания двоичных чисел. Схемы сложения и вычитания с использованием величины знака будут очень сложными.

Что такое

0010
1001 +
----

?

Другая система лишние обозначения . Вы можете хранить отрицательные числа, вы избавляетесь от проблемы двух нулей, но сложение и вычитание остаются трудными.

Таким образом, приходит два дополнения. Теперь вы можете хранить положительные и отрицательные целые числа и выполнять арифметику с относительной легкостью. Существует ряд методов для преобразования числа в дополнение к двум. Вот один

Преобразовать десятичное число в дополнение к двум

  1. Преобразуйте число в двоичное (пока игнорируйте знак), например, 5 - 0101, а -5 - 0101

  2. Если число является положительным числом, то все готово. Например, 5 - это 0101 в двоичном виде с использованием двойного дополнения.

  3. Если число отрицательное, то

    3.1 найти дополнение (инвертировать 0 и 1), например, -5 это 0101, поэтому поиск дополнения равен 1010

    3.2 Добавьте 1 к дополнению 1010 + 1 = 1011. Следовательно, -5 в дополнении к двум равен 1011.

Итак, что если вы хотите сделать 2 + (-3) в двоичном формате? 2 + (-3) равно -1. Что бы вы сделали, если бы вы использовали величину знака для добавления этих чисел? 0010 + 1101 =?

Используя два дополнения, подумайте, насколько это будет легко.

 2  =  0010
 -3 =  1101 +
 -------------
 -1 =  1111

Преобразование дополнения до двух в десятичный

Преобразование 1111 в десятичное число:

  1. Число начинается с 1, поэтому оно отрицательное, поэтому мы находим дополнение к 1111, то есть 0000.

  2. Добавьте 1 к 0000, и мы получим 0001.

  3. Преобразуйте 0001 в десятичное число, равное 1.

  4. Примените знак = -1.

Тада!

Vincent Ramdhanie
источник
45
Лучший ответ на мой взгляд.
Корай Тугай
5
да, этот довольно простой и очень хорошо объясняет дело
Макс Корецкий
3
Я не понимаю, как добавление одного при преобразовании обоих способов всегда приводит к одному и тому же числу. На мой взгляд, вы бы поменяли шаги или вычли что-то или что-то еще.
Маркос Перейра
2
Зачем добавлять 1 в дополнение?
Зинан Син
4
Этот ответ следует использовать в Википедии.
Хироки
119

Как и большинство объяснений, которые я видел, приведенные выше ясно показывают, как работать с дополнением 2, но на самом деле не объясняют, что это такое математически. Я постараюсь сделать это, по крайней мере, для целых чисел, и расскажу о некоторой предыстории, которая, вероятно, будет знакома первой.

Вспомните, как работает десятичное число:
  2345
- это способ записи
  2 × 10 3 + 3 × 10 2 + 4 × 10 1 + 5 × 10 0 .

Таким же образом, двоичный код - это способ записи чисел, использующий только 0 и 1, следуя той же общей идее, но заменяя те 10, которые указаны выше, на 2. Затем в двоичном коде
  1111
является способом записи
  1 × 2 3 + 1 × 2 2 + 1 × 2 1 + 1 × 2 0,
и если вы решите это, получится равным 15 (основание 10). Это потому что
  8 + 4 + 2 + 1 = 15.

Это все хорошо и хорошо для положительных чисел. Это даже работает для отрицательных чисел, если вы хотите просто поставить знак минус перед ними, как люди делают с десятичными числами. Это даже можно сделать с помощью компьютеров, но я не видел такого компьютера с начала 1970-х годов. Я оставлю причины для другого обсуждения.

Для компьютеров оказывается более эффективным использовать дополнение для отрицательных чисел. И вот кое-что, что часто упускается из виду. Обозначения дополнения включают в себя некоторый вид обращения цифр числа, даже подразумеваемых нулей, которые предшествуют нормальному положительному числу. Это неловко, потому что возникает вопрос: все они? Это может быть бесконечное количество цифр для рассмотрения.

К счастью, компьютеры не представляют бесконечности. Числа ограничены определенной длиной (или шириной, если вы предпочитаете). Итак, давайте вернемся к положительным двоичным числам, но с определенным размером. Я буду использовать 8 цифр («бит») для этих примеров. Таким образом, наше двоичное число будет действительно
  00001111
или
  0 × 2 7 + 0 × 2 6 + 0 × 2 5 + 0 × 2 4 + 1 × 2 3 + 1 × 2 2 + 1 × 2 1 + 1 × 2 0

Чтобы сформировать отрицание дополнения 2, мы сначала добавляем все (двоичные) цифры в форму
  11110000
и добавляем 1 к форме
  11110001
но как нам понять, что это означает -15?

Ответ в том, что мы меняем значение старшего бита (самого левого). Этот бит будет 1 для всех отрицательных чисел. Изменение будет состоять в том, чтобы изменить знак своего вклада в значение числа, в котором он появляется. Итак, теперь наш 11110001, как предполагается , представляет
  - 1 × 2 7 + 1 × 2 6 + 1 × 2 5 + 1 × 2 4 + 0 × 2 3 + 0 × 2 2 + 0 × 2 1 + 1 × 2 0
Заметьте, что "-" перед этим выражением? Это означает, что знаковый бит имеет вес -2 7 , то есть -128 (основание 10). Все остальные позиции сохраняют тот же вес, что и в двоичных числах без знака.

Выработка нашего -15, это
  -128 + 64 + 32 + 16 + 1
Попробуйте на своем калькуляторе. это -15.

Из трех основных способов, с помощью которых я видел отрицательные числа, представленные в компьютерах, дополнение 2 выигрывает для удобства в общем использовании. Это странно, хотя. Поскольку это двоичный код, должно быть четное количество возможных битовых комбинаций. Каждое положительное число может быть соединено с его отрицательным, но есть только один ноль. Отрицание нуля дает вам ноль. Так что есть еще одна комбинация, число с 1 в знаковый бит и 0 везде. Соответствующее положительное число не будет соответствовать количеству используемых битов.

Что еще более странно в этом числе, так это то, что если вы попытаетесь сформировать его положительное число, дополнив и добавив одно, вы получите то же отрицательное число обратно. Кажется естественным, что ноль сделал бы это, но это неожиданное и совсем не то поведение, к которому мы привыкли, поскольку помимо компьютеров мы обычно думаем о неограниченном количестве цифр, а не об этой арифметике фиксированной длины.

Это как верхушка айсберга странностей. Под поверхностью еще больше подстерегает, но этого достаточно для обсуждения. Возможно, вы найдете больше, если исследуете «переполнение» для арифметики с фиксированной точкой. Если вы действительно хотите войти в это, вы можете также исследовать «модульную арифметику».

ForDummies
источник
1
Мне нравится этот ответ! Объясняет, как работает дополнение 2s и добавление одного.
SJ.
Мне также нравится этот ответ. Особенно там, где вы показываете, как фигурирует отрицательное число. Здесь я подумал, что было перевернуто целое число, а не только MSB, а затем добавил другие взвешенные значения. Спасибо, это решило мой мозговой блок
user188757
Хорошая работа с упоминанием номера чудака, у которого нет обратного числа. Но что нам делать с этим? Мы просто устанавливаем флаг переполнения, если кто-то пытается инвертировать его?
НХ.
В то время как другие ответы сосредоточены на «как», этот ответ мягко подводит нас к «почему». Это помогло мне. Спасибо!
Абхишек Патхак
Если число заканчивается на 11000 ... 000, инвертирование приведет к 01000 ... 000. Обозначение, дополняющее два, основано на идее, что все цифры слева от самой левой представленной цифры должны иметь то же значение, что и эта цифра, но при инвертировании числа, представление которого составляет 1000 ... 000, это не будет правдой.
суперкат
20

Дополнение 2 очень полезно для нахождения значения двоичного файла, однако я подумал о гораздо более кратком способе решения такой проблемы (никто никогда не видел его):

возьмем двоичный файл, например: 1101, который [при условии, что пробел «1» является знаком] равен -3 .

используя дополнение 2, мы сделаем это ... переверните 1101 на 0010 ... добавьте 0001 + 0010 ===> и получите 0011. 0011 в положительном двоичном = 3. поэтому 1101 = -3 !

Что я понял:

вместо того, чтобы все переворачивать и добавлять, вы можете просто сделать основной метод решения для положительного двоичного кода (скажем, 0101): (2 3 * 0) + (2 2 * 1) + (2 1 * 0) + (2 0 * 1) = 5.

Сделайте точно такую ​​же концепцию с негативом! (С небольшим поворотом)

возьмите 1101, например:

для первого числа вместо 2 3 * 1 = 8 сделать - (2 3 * 1) = -8 .

затем продолжайте как обычно, выполнив -8 + (2 2 * 1) + (2 1 * 0) + (2 0 * 1) = -3

Симон Юндов
источник
1
Наилучшим образом я мог понять 2-е дополнение. Прочитав это, я смог понять все ответы на поставленный выше вопрос.
Шакил Шахзад
1
Этот метод упоминается в книге «Компьютерные системы: взгляд программиста».
Джимо
1
Это намного быстрее!
chanzerre
14

Представьте, что у вас есть конечное число бит / триц / цифр / что угодно. Вы определяете 0 как все цифры, равные 0, и, естественно, рассчитываете вверх:

00
01
02
..

В конце концов вы будете переполнены.

98
99
00

У нас есть две цифры и мы можем представлять все числа от 0 до 100. Все эти числа являются положительными! Предположим, мы тоже хотим представлять отрицательные числа?

То, что у нас действительно есть, это цикл. Число до 2 равно 1. Число до 1 равно 0. Число до 0 равно ... 99 .

Итак, для простоты, допустим, что любое число свыше 50 является отрицательным. «0» - «49» означают от 0 до 49. «99» - это -1, «98» - это -2, ... «50» - это -50.

Это представление является дополнением к десяти . Компьютеры обычно используют два дополнения , которые являются одинаковыми, за исключением использования битов вместо цифр.

Хорошая вещь о дополнении десятки - то, что дополнение просто работает . Вам не нужно делать ничего особенного, чтобы добавлять положительные и отрицательные числа!

Капитан сегфо
источник
9

Я прочитал фантастическое объяснение на Reddit jng, используя одометр в качестве аналогии.

введите описание изображения здесь

Это полезное соглашение. Те же схемы и логические операции, которые добавляют / вычитают положительные числа в двоичном виде, по-прежнему работают как с положительными, так и с отрицательными числами, если использовать соглашение, поэтому оно так полезно и вездесуще.

Представьте себе одометр автомобиля, он катится на (скажем) 99999. Если вы увеличиваете 00000, вы получаете 00001. Если вы уменьшаете 00000, вы получаете 99999 (из-за оборота). Если вы добавите один обратно к 99999, он вернется к 00000. Поэтому полезно решить, что 99999 представляет -1. Кроме того, очень полезно решить, что 99998 представляет -2 и так далее. Вы должны где-то остановиться, и, как правило, верхняя половина чисел считается отрицательной (50000-99999), а нижняя половина положительной означает только себя (00000-49999). В результате, верхняя цифра 5-9 означает, что представленное число является отрицательным, а 0-4 означает, что представленное является положительным - точно так же, как верхний бит, представляющий знак в двоичном двоичном числе дополнения.

Понимать это было сложно и для меня. Как только я получил его и вернулся, чтобы перечитать статьи и объяснения книг (тогда еще не было интернета), оказалось, что многие из тех, кто описывал это, не понимали этого. После этого я написал книгу, обучающую языку ассемблера (которая неплохо продавалась в течение 10 лет).

Алистер
источник
5

Два дополнения выясняются путем добавления одного к первому дополнению данного числа. Допустим, мы должны найти два дополнения, а 10101затем найти его дополнение, то есть 01010добавить 1к этому результат, то есть 01010+1=01011, который является окончательным ответом.

evaa
источник
4

Давайте получим ответ 10 - 12 в двоичной форме, используя 8 бит: что мы действительно сделаем, это 10 + (-12)

Нам нужно получить часть 12 комплимента, чтобы вычесть ее из 10. 12 в двоичном виде - 00001100. 10 в двоичном - 00001010.

Чтобы получить часть 12 комплимента, мы просто инвертируем все биты, а затем добавляем 1. 12 в двоичном реверсированном виде - это 11110011. Это также обратный код (дополнение). Теперь нам нужно добавить один, который сейчас 11110100.

Так что 11110100 это комплимент 12! Легко, когда ты думаешь об этом таким образом.

Теперь вы можете решить вышеуказанный вопрос 10 - 12 в двоичном виде.

00001010
11110100
-----------------
11111110  
NightSky
источник
3

Дополнения 2: Когда мы добавляем дополнительный с дополнениями 1 к числу, мы получим дополнения 2. Например: 100101 это дополнение 1 к 011010, а дополнение 2 к 011010 + 1 = 011011 (добавляя один с дополнением к 1). Для получения дополнительной информации эта статья объясняет это графически.

Милон
источник
плюс1 за ссылку, которая имеет объяснение с кружком
Манохар Редди Поредди
3

Глядя на систему дополнения двух с математической точки зрения, это действительно имеет смысл. Идея состоит в том, чтобы в дополнение к десятке «изолировать» разницу.

Пример: 63 - 24 = х

Мы добавляем дополнение 24, которое действительно просто (100 - 24). Так что на самом деле все, что мы делаем, это добавляем 100 по обе стороны уравнения.

Теперь уравнение: 100 + 63 - 24 = x + 100, поэтому мы удаляем 100 (или 10 или 1000 или что-то еще).

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

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

Пример: 99999 - 03275 = 96724

По этой причине после дополнения девяти мы добавляем 1. Как вы, наверное, знаете из математики детства, 9 превращается в 10 путем «кражи» 1. Так что в основном это всего лишь десять дополнений, которые берут 1 из разницы.

В двоичном коде два дополняются до десятого, а одно - до девяти. Основное отличие состоит в том, что вместо того, чтобы пытаться выделить разницу степенями десять (прибавляя 10, 100 и т. Д. В уравнение), мы пытаемся выделить разницу степенями два.

Именно по этой причине мы инвертируем биты. Точно так же, как то, что наш minuend представляет собой цепочку девяток в десятичном формате, наш minuend является цепочкой единиц в двоичном виде.

Пример: 111111 - 101001 = 010110

Поскольку цепочки единиц на 1 ниже милой степени двойки, они «крадут» 1 из разницы, как девятки в десятичной.

Когда мы используем отрицательные двоичные числа, мы на самом деле просто говорим:

0000 - 0101 = х

1111 - 0101 = 1010

1111 + 0000 - 0101 = х + 1111

Чтобы «изолировать» x, нам нужно добавить 1, потому что 1111 отстает от 10000, и мы удаляем ведущую 1, потому что мы просто добавили ее к исходной разнице.

1111 + 1 + 0000 - 0101 = x + 1111 + 1

10000 + 0000 - 0101 = х + 10000

Просто удалите 10000 с обеих сторон, чтобы получить х, это базовая алгебра.

KyBrooks
источник
3

Многие ответы до сих пор хорошо объясняют, почему дополнение 2 используется для представления отрицательного числа, но не говорят нам, что такое число дополнения до двух, в частности, не то, почему добавляется «1», а фактически часто добавляется неправильно.

Путаница возникает из-за плохого понимания определения числа дополнения. Дополнением является недостающая часть, которая сделает что-то завершенным.

Основное дополнение n-значного числа x в основании b, по определению, b ^ nx. В двоичном 4 представляет 100, который имеет 3 цифры (n = 3) и основание 2 (b = 2). Таким образом, его основное дополнение - b ^ nx = 2 ^ 3-4 = 8-4 = 4 (или 100 в двоичном виде).

Однако в двоичном коде получение дополнения радиуса не так просто, как получение его уменьшенного дополнения радиуса, которое определяется как (b ^ n-1) -y, всего на 1 меньше, чем у дополнения радиуса. Чтобы получить уменьшенное дополнение корня, вы просто переворачиваете все цифры.

100 -> 011 (уменьшенное (свое) дополнение к основанию)

чтобы получить основание (два), мы просто добавляем 1, как определено определение.

011 +1 -> 100 (дополнение до двух).

Теперь, с этим новым пониманием, давайте взглянем на пример, данный Винсентом Рамдхани (см. Второй ответ выше)

/ * начало Винсента

Преобразование 1111 в десятичное число:

Число начинается с 1, поэтому оно отрицательное, поэтому мы находим дополнение к 1111, что равно 0000. Добавьте 1 к 0000, и мы получим 0001. Преобразование 0001 в десятичное число, которое равно 1. Примените знак = -1. Тада!

конец Винсента * /

Следует понимать как

Номер начинается с 1, поэтому он отрицательный. Итак, мы знаем, что это дополнение к двум значениям х. Чтобы найти x, представленный дополнением к двум, сначала нужно найти дополнение к его 1.

дополнение двух к x: 1111 дополнение к двум x: 1111-1 -> 1110; х = 0001, (перевернуть все цифры)

примените знак -, и ответ = -x = -1.

user779764
источник
3

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

                  35=035=000000035.

В хранилище компьютера нет пустого места. Все биты (двоичные цифры) должны быть либо 0, либо 1. Для эффективного использования числа памяти могут храниться как 8-битные, 16-битные, 32-битные, 64-битные, 128-битные представления. Когда число, которое сохраняется как 8-битное число, передается в 16-битное местоположение, знак и величина (абсолютное значение) должны оставаться неизменными. Оба дополнения 1 и 2 дополняют представления облегчают это. Как существительное: как дополнение 1, так и дополнение 2 являются двоичными представлениями знаковых величин, где старший значащий бит (слева) является знаковым битом. 0 для положительного и 1 для отрицательного. 2s дополнение не означает отрицательный, Это означает подписанное количество. Как и в десятичном виде, величина представлена ​​в виде положительной величины. Структура использует расширение знака для сохранения количества при переходе в регистр [] с большим количеством битов:

       [0101]=[00101]=[00000000000101]=5 (base 10)
       [1011]=[11011]=[11111111111011]=-5(base 10)

Как глагол: дополнение 2 означает отрицание . Это не значит сделать негатив. Это означает, что если негатив делает позитивом; если положительный, то отрицательный. Величина является абсолютной величиной:

        if a >= 0 then |a| = a
        if a < 0 then |a| = -a = 2scomplement of a

Эта способность позволяет эффективно вычитать двоичные числа, используя отрицание, а затем добавление. a - b = a + (-b)

Официальный способ взять дополнение 1 - для каждой цифры вычесть ее значение из 1.

        1'scomp(0101) = 1010.

Это то же самое, что переключать или инвертировать каждый бит по отдельности. Это приводит к отрицательному нулю, который не очень нравится, поэтому добавление единицы к дополнению te 1 избавляет от проблемы. Чтобы отменить или взять дополнение 2s, сначала возьмите дополнение 1s, затем добавьте 1.

        Example 1                             Example 2
         0101  --original number              1101
         1's comp  1010                       0010
         add 1     0001                       0001
         2's comp  1011  --negated number     0011

В примерах отрицание также работает со знаками расширенных чисел.

Добавление:
1110 Carry 111110 Carry 0110 совпадает с 000110 1111 111111 сумма 0101 сумма 000101

вычитание:

    1110  Carry                      00000   Carry
     0110          is the same as     00110
    -0111                            +11001
  ----------                        ----------
sum  0101                       sum   11111

Обратите внимание, что при работе с дополнением 2 пустое пространство слева от числа заполняется нулями для положительных чисел, но заполняется нулями для отрицательных чисел. Керри всегда добавляется и должно быть 1 или 0.

ура

Русь
источник
3

Дополнение 2 по существу является способом придумать аддитивную инверсию двоичного числа. Задайте себе вопрос: учитывая число в двоичной форме, какая битовая комбинация, если добавить ее к исходному числу, сделает результат нулевым? Если вы можете придумать эту битовую комбинацию, то эта битовая комбинация является представлением -ve (аддитивная обратная) исходного числа; так как по определению добавление числа к его аддитивному обратному всегда должно приводить к нулю. Пример: возьмите 101, который является десятичным 5. Теперь задача состоит в том, чтобы создать битовую комбинацию, которая при добавлении к данной битовой комбинации (101) приведет к нулю. Для этого начните с самого правого бита 101 и для каждого отдельного бита снова задайте тот же вопрос: какой бит следует добавить к биту «this», чтобы результат был нулевым? продолжать делать это с учетом обычного переноса. После того, как мы закончили с тремя самыми правыми местами (цифры, которые определяют исходное число безотносительно к ведущим нулям), последний перенос переносится в битовой комбинации аддитивного обратного. Кроме того, поскольку мы могли бы хранить в исходном числе, скажем, один байт, все остальные старшие биты в аддитивном инверсии также должны быть равны единице, так что, когда компьютер добавляет число и его аддитивную инверсию, используя «тот» тип хранения (char) результат в этом символе будет все нули.

 1 1 1
 ----------
   1 0 1
 1 0 1 1 ---> additive inverse
  ---------
   0 0 0
н-мам
источник
2

Мне понравился ответ Лавинио, но сдвиг битов добавляет сложности. Часто есть выбор движущихся битов, соблюдая знаковый бит или не соблюдая знаковый бит. Это выбор между обработкой чисел со знаком (от -8 до 7 для полубайта, от -128 до 127 для байтов) или для полных диапазонов чисел без знака (от 0 до 15 для полубайтов, от 0 до 255 для байтов).

Nosredna
источник
2

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

Таким образом, в дополнении 2, если один равен 0x0001, то -1 равно 0x1111, потому что это приведет к объединенной сумме 0x0000 (с переполнением 1).

Эдвин Бак
источник
1

Дополнение к двум является одним из способов выражения отрицательного числа, и большинство контроллеров и процессоров хранят отрицательное число в форме дополнения к 2

Денис Рузвельт
источник
1
Это ничего не добавляет к информации, предоставленной другими ответами.
Адриан Крот
1

Дополнение Two в основном используется по следующим причинам:

  1. Чтобы избежать нескольких представлений 0
  2. Избегать слежения за битом переноса (как в дополнении) в случае переполнения.
  3. Выполнение простых операций, таких как сложение и вычитание, становится легким.
К.Н. Bhargav
источник
0

СПРАВКА: https://www.cs.cornell.edu/~tomf/notes/cps104/twoscomp.html

Я инвертирую все биты и добавляю 1. Программно:

  // in C++11
  int _powers[] = {
      1,
      2,
      4,
      8,
      16,
      32,
      64,
      128
  };

  int value=3;
  int n_bits=4;
  int twos_complement = (value ^ ( _powers[n_bits]-1)) + 1;
Чарльз Томас
источник
Даже ассемблер будет слишком высокого уровня. Необходимо увидеть схему уровня логики дополнения логики. С Т циклами. Вы алгоритмически верны.
mckenzm
0

2 дополнением данного числа является нет. получил добавлением 1 с дополнением 1 к нет. Предположим, у нас есть двоичный номер: 10111001101 Это дополнение 1: 01000110010 И дополнение 2 будет: 01000110011

оборота user10862846
источник
0

Побитовое дополнение числа означает переворачивание всех битов в нем. В дополнение к двум мы переворачиваем все биты и добавляем один.

Используя представление дополнения 2 для целых чисел со знаком, мы применяем операцию дополнения 2, чтобы преобразовать положительное число в его отрицательный эквивалент и наоборот. Таким образом, используя в качестве примера клочья, 0001(1) становится 1111(-1) и снова применяя операцию, возвращается к 0001.

Поведение операции в нуле выгодно в том, чтобы дать одно представление для ноля без специальной обработки положительных и отрицательных нулей. 0000дополняет 1111, который при добавлении 1. переполняется на0000 , давая нам один ноль, а не положительный и отрицательный.

Основным преимуществом этого представления является то, что стандартные схемы сложения для целых чисел без знака дают правильные результаты при их применении. Например, добавляя 1 и -1 в nibbles:, 0001 + 1111биты переполняются из регистра, оставляя позади 0000.

Для мягкого введения замечательный Computerphile выпустил видео на эту тему .

ahcox
источник
0

Проще 2's Complementговоря, это способ хранения отрицательного числа в памяти компьютера. В то время как положительные числа хранятся как обычные двоичные числа.

Давайте рассмотрим этот пример,

Компьютер использует Binary Number Systemдля представления любого числа.

x = 5;

Это представляется как 0101.

x = -5;

Когда компьютер запрашивает -подпись, он вычисляет дополнение 2 и сохраняет его. i.e5 = 0101 и это дополнение 2 1011.

Важные правила, которые компьютер использует для обработки чисел,

  1. Если первый бит, 1то это должен быть negativeномер.
  2. Если все биты, кроме первого, равны первому, 0то это положительное число, поскольку -0в системе счисления его нет ( 1000 is not -0вместо этого оно положительное 8).
  3. Если все биты, 0то это так 0.
  4. Остальное это positive number.
Рагу
источник
-6

Самый простой ответ:

1111 + 1 = (1) 0000. Так что 1111 должно быть -1. Тогда -1 + 1 = 0.

Это прекрасно, чтобы понять это все для меня.

Дмитрий
источник
Это не дает ответа на вопрос. Чтобы критиковать или запросить разъяснения у автора, оставьте комментарий под своим постом.
Кодор
Это ответ. Простейший. Для меня - лучший.
Дмитрий