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

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

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

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

24 ответа

Решение

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Сначала рассмотрим целое число без знака, хранящееся в 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.

Тада!

Как и большинство объяснений, которые я видел, приведенные выше ясно показывают, как работать с дополнением 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 везде. Соответствующее положительное число не будет соответствовать количеству используемых битов.

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

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

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

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

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

Что я понял:

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

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

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

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

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

Представьте, что у вас есть конечное число бит / триц / цифр / что угодно. Вы определяете 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.

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

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

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

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

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

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

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

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

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

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

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

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

00001010
11110100
-----------------
11111110  

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

Пример: 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 с обеих сторон, чтобы получить х, это базовая алгебра.

Многие ответы до сих пор хорошо объясняют, почему дополнение двух используется для представления отрицательного числа, но не говорят нам, что такое число дополнения до двух, в частности, не то, почему добавляется "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.

Слово дополнение происходит от полноты. В десятичном мире цифры от 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.

ура

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

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

 1 1 1
 ----------
   1 0 1
 1 0 1 1 ---> additive inverse
  ---------
   0 0 0

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

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

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

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

У меня была такая же проблема пару недель назад. Я закончил тем, что читал об этом онлайн из различных источников, пытаясь соединить кусочки, и сам писал об этом, просто чтобы убедиться, что я правильно понял. Мы используем два дополнения в основном по двум причинам:

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

Если вы хотите получить более подробное объяснение вопроса, попробуйте статью, написанную мной здесь. Надеюсь, поможет!

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

Рассмотрим этот пример,

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

x = 5;

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

x = -5;

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

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

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

СПРАВКА: 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;

Вопрос в том, «Что такое« Дополнение 2 »?» Простой ответ для тех, кто хочет понять это теоретически (и я пытаюсь дополнить другие более практичные ответы): дополнение 2 - это представление отрицательных целых чисел в двойной системе, которое не требует дополнительных символов, таких как + и -.

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

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

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

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

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

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

Вы также можете использовать онлайн-калькулятор для вычисления двоичного представления двоичного числа в виде двоичного числа: http://www.convertforfree.com/twos-complement-calculator/

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

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

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

Другие вопросы по тегам