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

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

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

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


person Community    schedule 26.06.2009    source источник
comment
Я думаю, что комментарий, который был мне полезен, заключается в том, что дополнение похоже на обратное, но вместо того, чтобы давать 0, оно дает 2^N (по определению), например. с 3 битами для числа A мы хотим A+~A=2^N, поэтому 010 + 110 = 1000 = 8, что равно 2^3. По крайней мере, это проясняет, что должно означать здесь слово «дополнение», поскольку это не просто инверсия значений 0 и 1. Полезное видео MIT: youtube.com/watch?v=RbJV-g9Lob8   -  person Charlie Parker    schedule 15.09.2020


Ответы (24)


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

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

В основном это говорит:

  • для нуля используйте все нули.
  • для положительных целых чисел начать отсчет с максимальным значением 2 (количество бит - 1) -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, вы можете сказать, что десятичное значение неотрицательно.

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

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

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

person Community    schedule 26.06.2009
comment
Вероятно, лучшая часть двойного дополнения - это то, как оно упрощает математику. Попробуйте сложить 2 (0010) и -2 (1110) вместе, и вы получите 10000. Самый старший бит - это переполнение, поэтому результат на самом деле 0000. Почти как по волшебству, 2 + -2 = 0. - person Naaff; 26.06.2009
comment
Еще одно преимущество, помимо простого сложения и вычитания, состоит в том, что дополнение до двух имеет только один ноль. Если бы вы использовали простой знаковый бит, скажем, используя 0001 для представления +1 и 1001 для представления -1, у вас было бы два нуля: 0000 (+0) и 1000 (-0). Это настоящая боль в спине. - person Jörg W Mittag; 26.06.2009
comment
Проголосуйте за то, чтобы это было по существу, а также за объяснение, почему отрицательные значения имеют больший диапазон, чем положительные. Я пришел искать причину разницы в дальности. - person Ashwin; 26.12.2014
comment
Разве вы не говорите для отрицательных целых чисел, сделайте то же самое, но обратный отсчет и переключите роль нулей и единиц - person Koray Tugay; 27.01.2015
comment
Потрясающе. Добавлены лишние части преобразования битов в отрицательное целое число. - person Suraj Jain; 23.08.2016
comment
Я думаю, что концепцию целочисленного переполнения можно было бы лучше объяснить, если бы мы начали считать отрицательные значения с наименьшего числа. (То есть: минус восемь и снова сосчитать). Таким образом, ученик может увидеть, почему целочисленное переполнение приводит к таким произвольным числам. - person Xunie; 30.08.2016
comment
Итак, неужели дополнение до 2 вообще не использует знаковый бит? - person MarcusJ; 30.03.2017
comment
Знаковый бит все еще действителен (за исключением, возможно, случая 0, который не является положительным или отрицательным), но вы не просто меняете знаковый бит, чтобы отрицать число (см. ниже для опровержения). - person NH.; 12.07.2017
comment
Для меня это похоже на двоичные значения. Дополнение до двух обычно включает поразрядную инверсию и сложение. Так что это не совсем объяснение, кроме объяснения двоичного кода? Для 32-битного «полного слова» 8000 up - это конечно -ve. Но какова цель ALU POV? - person mckenzm; 11.12.2017
comment
Но как компьютер, например, узнает, является ли 1101 отрицательным числом три, а не 13? - person Rain; 18.02.2018
comment
@FatalError Это зависит от того, сколько бит представлено числом. 1101 = -3 (4 бита), но 00001101 = 13 (8 бит). - person mgagnon; 13.04.2018
comment
Отличное объяснение того, как 0 и 1 меняются ролями для представления отрицательных чисел. - person Geremia; 30.11.2018
comment
Обратите внимание, что дополнение 2 не используется для чисел с плавающей запятой. Простое представление чисел с плавающей запятой - IEEE 754. - person CJay; 11.05.2019
comment
Я думаю, что полезный комментарий к ответу: почему дополнение не означает обратное. Кроме того, начало отсчета с 1111 и то, что было -1, но затем начало отсчета с 0000, и то, что не было 1, странно. Почему бы не начать отсчет с 1111 и не дать ему равняться нулю? Поскольку наиболее естественное дополнение значения цифр означало бы, что 1110 равно -1, но это не так и действительно сбивает с толку. - person Charlie Parker; 15.09.2020
comment
Я думаю, что это лучшее объяснение того, что означает дополнение: я думаю, что комментарий, который был мне полезен, заключается в том, что дополнение похоже на обратное, но вместо того, чтобы давать 0, оно дает 2^N (по определению), например. с 3 битами для числа A мы хотим A+~A=2^N, поэтому 010 + 110 = 1000 = 8, что равно 2^3. По крайней мере, это проясняет, что должно означать здесь слово «дополнение», поскольку это не просто инверсия значений 0 и 1. - person Charlie Parker; 15.09.2020
comment
Я собираюсь проголосовать за это, основываясь исключительно на том факте, что он получил апострофы в нужном месте относительно ones' complement и two's complement :-) Как указывает сам Кнут, первый дополняет на основе серия единиц, последнее дополняющее на основе одной степени двойки. Дополнение до двоек существует, но я думаю, что это для чисел с основанием 3 (или 4?), А не для двоичных. - person paxdiablo; 12.06.2021
comment
Следует также отметить, что оба комитета по стандартам C и C ++ в настоящее время находятся в процессе принятия дополнения до двух в качестве единого истинного кольца, отказа от знака / величины и дополнения единиц в качестве благословенных альтернатив. - person paxdiablo; 12.06.2021

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

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

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

Тада!

person Community    schedule 26.06.2009
comment
На мой взгляд, лучший ответ. - person Koray Tugay; 27.01.2015
comment
да, это довольно просто и очень хорошо объясняет суть - person Max Koretskyi; 27.09.2015
comment
Я не понимаю, как добавление одного при преобразовании в обе стороны всегда приводит к одному и тому же числу. На мой взгляд, вы бы изменили шаги или вычли бы один или что-то в этом роде. - person Marcos Pereira; 13.04.2016
comment
Зачем добавлять 1 к дополнению? - person AsyncMoksha; 26.06.2017
comment
Этот ответ следует использовать в Википедии. - person Hiroki; 11.11.2017
comment
@Zinan Xing подумай о керри. Это хороший ответ. Что может сбить с толку многих студентов, понимающих это, так это то, что отрицание отрицания также включает тот же процесс, побитовое инверсию и добавление единицы, а не вычитание единицы и последующее инвертирование. В основном потому, что мы хотим повторно использовать ту же операцию. - person mckenzm; 12.12.2017

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

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

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

person Community    schedule 18.08.2012
comment
Мне нравится этот ответ! Объясняет, как работает добавление двойки и добавление единицы. - person jonsno; 07.06.2017
comment
Мне тоже нравится этот ответ. Особенно там, где вы показываете, как вычисляется отрицательное число. Здесь я думал, что все число было инвертировано, а не только MSB, а затем добавлены другие взвешенные значения. Спасибо, это разрешило мой мозговой блок - person user188757; 09.07.2017
comment
Отлично упомянул странное число, у которого нет обратного. Но что нам с этим делать? Мы просто устанавливаем флаг переполнения, если кто-то пытается его инвертировать? - person NH.; 12.07.2017
comment
В то время как другие ответы сосредоточены на том, как, этот ответ мягко подводит нас к вопросу почему. Мне это помогло. Спасибо! - person Abhishek Pathak; 21.10.2018
comment
Если число заканчивается на 11000 ... 000, его инвертирование даст 01000 ... 000. Обозначение с дополнением до двух основано на идее, что все цифры слева от самой левой представленной цифры должны иметь то же значение, что и эта цифра, но при инвертировании числа, представление которого равно 1000 ... 000, это не будет правдой. - person supercat; 06.08.2019

Дополнение 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

person Community    schedule 22.06.2013
comment
Лучше всего я мог понять дополнение 2. Прочитав это, я смог понять все ответы на поставленный выше вопрос. - person SSC; 17.04.2015
comment
Этот метод упоминается в книге «Компьютерные системы: взгляд программиста». - person jimo; 04.08.2015
comment
Это гораздо более быстрый способ! - person chanzerre; 29.08.2015

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

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

Преимущество десятичного дополнения в том, что оно просто работает. Для сложения положительных и отрицательных чисел ничего особенного делать не нужно!

person Community    schedule 26.06.2009

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

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

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

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

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

person Community    schedule 21.08.2018
comment
Ух ты, уже давно я не видел спидометр, разгоняющий как миль / ч, так и км / ч. Австралия перешла на другую сторону до того, как мне исполнилось 10 лет, и я все еще помню, что мне приходилось напоминать старику (сленг: отец) об основных преобразованиях, когда он пытался разогнаться до 100 миль в час в зоне 100 км / ч :-) - person paxdiablo; 12.06.2021
comment
В любом случае, я думаю, что в какой-то момент они перестали разрешать откат одо. Отсоединение его от машины и использование дрели для отката было излюбленным приемом (некоторых довольно изворотливых) людей, пытающихся продать свои автомобили с меньшим пробегом (забавно, как мы все еще используем этот термин, предполагаемый километраж так и не прижился). - person paxdiablo; 12.06.2021

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

person Community    schedule 13.09.2010

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

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

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

Итак, 11110100 - это комплимент 12! Легко, когда ты так думаешь.

Теперь вы можете решить поставленный выше вопрос от 10 до 12 в двоичной форме.

00001010
11110100
-----------------
11111110  
person Community    schedule 28.08.2013

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

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

Мы добавляем 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 = x

1111 - 0101 = 1010

1111 + 0000 - 0101 = x + 1111

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

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

10000 + 0000 - 0101 = x + 10000

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

person Community    schedule 26.08.2015

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

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

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

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

100 -> 011 (уменьшенное (единичное) дополнение)

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

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

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

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

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

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

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

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

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

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

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

person Community    schedule 14.10.2016

Слово «дополнение» происходит от полноты. В десятичном мире цифры от 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 - отрицательное. Дополнение до двух не означает отрицание. Это означает количество со знаком. Как и в десятичной системе счисления, величина представляется как положительная величина. В структуре используется знаковое расширение для сохранения количества при переходе в регистр [] с большим количеством битов:

       [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

Эта способность позволяет эффективно выполнять двоичное вычитание, используя отрицание и сложение. а - б = а + (-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 Перенести 111110 Перенести 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.

Ваше здоровье

person Community    schedule 13.04.2019

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

 1 1 1
 ----------
   1 0 1
 1 0 1 1 ---> additive inverse
  ---------
   0 0 0
person Community    schedule 08.08.2019

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

person Community    schedule 26.06.2009

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

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

person Community    schedule 20.06.2012

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

person Community    schedule 26.11.2014
comment
плюс1 для ссылки с пояснением в кружке - person Manohar Reddy Poreddy; 31.12.2015

Проще говоря, 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.
person Community    schedule 26.10.2019

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

person Community    schedule 13.12.2019
comment
Это ничего не добавляет к информации, предоставленной другими ответами. - person Adrian Mole; 13.12.2019

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

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

ССЫЛКА: 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;
person Community    schedule 30.12.2016
comment
Даже ассемблер оказался бы на слишком высоком уровне. Необходимо увидеть схему логики сложения на уровне ворот. С Т-циклами. Вы алгоритмически правы. - person mckenzm; 12.12.2017

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

person Community    schedule 07.01.2019

Поразрядное дополнение числа означает перевернуть все биты в нем. Чтобы дополнить его двумя, мы переворачиваем все биты и добавляем единицу.

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

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

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

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

person Community    schedule 15.02.2019

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

person Community    schedule 09.05.2021

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

person Community    schedule 22.09.2016

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

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

Мне идеально все это понять.

person Community    schedule 25.09.2015
comment
Это не дает ответа на вопрос. Чтобы критиковать или запрашивать разъяснения у автора, оставьте комментарий под его сообщением. - person Codor; 05.10.2015
comment
Это ответ. Простейший. Для меня - лучший. - person Dmitry; 07.10.2015