Подтвердить что ты не робот

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

Мне просто интересно, есть ли причина, по которой для представления -1 в двоичном формате используется два дополнения: переворачивание бит и добавление 1?

-1 представлен 11111111 (два дополнения), а не (для меня более интуитивно понятным) 10000001, который двоичный 1 с первым битом как отрицательный флаг.

Отказ от ответственности: я не полагаюсь на двоичную арифметику для моей работы!

4b9b3361

Ответ 1

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

Скажем, у вас есть два числа, 2 и -1. В вашем "интуитивном" способе представления чисел они будут 0010 и 1001 соответственно (я придерживаюсь 4 битов для размера). В двух дополняющих способах они являются 0010 и 1111. Теперь, допустим, я хочу добавить их.

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

  0010
+ 1111
=10001
= 0001 (discard the carry)

0001 равно 1, что является ожидаемым результатом "2+ (-1)".

Но в вашем "интуитивном" методе добавление сложнее:

  0010
+ 1001
= 1011

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

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

Кроме того, в "интуитивном" методе хранения есть два нуля:

0000  "zero"
1000  "negative zero"

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

Есть еще один бонус с хранением целочисленных значений таким образом, и когда вам нужно увеличить ширину регистра, в котором хранится значение. С двумя дополнениями сохранение 4-битного числа в 8-битном регистре является вопросом повторения его самый важный бит:

    0001 (one, in four bits)
00000001 (one, in eight bits)
    1110 (negative two, in four bits)
11111110 (negative two, in eight bits)

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

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

    0001 (one, in four bits)
00000001 (one, in eight bits)
    1010 (negative two, in four bits)
10000010 (negative two, in eight bits)

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

Ответ 2

Wikipedia говорит все:

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

Другими словами, добавление одного и того же, более или менее число отрицательно.

Ответ 3

Несмотря на то, что этот вопрос старый, позвольте мне поставить мои 2 цента.

Прежде чем я объясню это, вернемся к основам. 2 'дополняет 1 дополнение + 1. Теперь что такое 1 дополнение и каково его значение в дополнение.

Сумма любого n-битового числа и его 1 дополнение дает вам максимально возможное число, которое может быть представлено этими n-битами. Пример:

 0010 (2 in 4 bit system)
+1101 (1 complement of 2)
___________________________
 1111  (the highest number that we can represent by 4 bits)

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

Результат будет 1 0000, который равен 0 (поскольку мы работаем с 4-битными номерами (1 слева - переполнение)

Итак,

Any n-bit number + its 1 complement = max n-bit number
Any n-bit number + its 1'complement + 1 = 0 ( as explained above, overflow will occur as we are adding 1 to max n-bit number)

Затем кто-то решил назвать 1 дополнение + 1 как 2'комплемент. Таким образом, вышеприведенное утверждение становится следующим: Любое число n'bit + его 2 дополнение = 0 что означает 2 дополнение числа = - (этого числа)

Все это дает еще один вопрос: почему мы можем использовать только (n-1) из n бит для представления положительного числа и почему левый наибольший n-й бит представляет знак (0 на самом левом бите означает + ve число, и 1 означает номер -ve). например, почему мы используем только первые 31 бит int в java для представления положительного числа, если 32-й бит равен 1, его номер a -ve.

 1100 (lets assume 12 in 4 bit system)
+0100(2 complement of 12)
___________________________

1 0000 (результат равен нулю, при переполнении переноса 1)

Таким образом, система (n + 2'комплементации n) = 0 все еще работает. Единственная двусмысленность здесь - это 2 дополнения к 12, это 0100, которые неоднозначно также представляют +8, кроме представления -12 в системе дополнений 2s.

Эта проблема будет решена, если положительные числа всегда имеют 0 в их левом большинстве. В этом случае их 2 дополнения всегда будут иметь 1 в их левом большинстве бит, и мы не будем иметь двусмысленность одного и того же набора бит, представляющих 2 номера дополнения, а также число + ve.

Ответ 4

Два дополнения позволяют выполнять сложение и вычитание обычным способом (например, вы наносили на беззнаковые числа). Он также предотвращает -0 (отдельный способ представления 0, который не будет равен 0 с обычным побитовым методом сравнения чисел).

Ответ 5

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

Ответ 6

Обычная реализация операции - "перевернуть биты и добавить 1", но есть другой способ ее определения, что, вероятно, делает логическое обоснование более ясным. 2 - это форма, которую вы получаете, если вы берете обычное беззнаковое представление, где каждый бит управляет следующей мощностью 2 и просто делает наиболее значимый термин отрицательным.

Взяв 8-битное значение a 7 a 6 a 5 a 4 a 3 a 2 a 1 a 0

Обычная двоичная интерпретация без знака:
2 7 * a 7 + 2 6 * a 6 + 2 5 * a 5 + 2 4 * a 4 + 2 3 * a 3 + 2 2 * a 2 + 2 1 * a 1 + 2 0 * а <суб > 0суб >
11111111 = 128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 = 255

Двухкомпонентная интерпретация:
-2 7 * a 7 + 2 6 * a 6 + 2 5 * a 5 + 2 4 * a 4 + 2 3 * a 3 + 2 2 * a 2 + 2 1 * a 1 + 2 0 * а <суб > 0суб >
11111111 = -128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 = -1

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

Ответ 7

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

Если вы попытались добавить 1 и -1, используя свой метод
 10000001 (-1)
+00000001 (1)
вы получаете  10000010 (-2)

Вместо этого, используя два дополнения, мы можем добавить

11111111 (-1)
+00000001 (1) вы получаете  00000000 (0)

То же самое верно для вычитания.

Кроме того, если вы попытаетесь вычесть 4 из 6 (два положительных числа), вы можете добавить 2 дополнения и добавить их вместе 6 + (-4) = 6 - 4 = 2

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

Ответ 8

Чтобы расширить остальные ответы:

В двух дополнениях

  • Добавление - это тот же механизм, что и добавление простых положительных целых чисел.
  • Вычитание тоже не изменяется
  • Умножение тоже!

Для разделения требуется другой механизм.

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

Ответ 9

Читая ответы на этот вопрос, я наткнулся на этот комментарий [отредактирован].

2 дополнение к 0100 (4) будет 1100. Теперь 1100 равно 12, если я говорю нормально. Так, когда я говорю нормальный 1100, тогда это 12, но когда я говорю 2 дополнения 1100, тогда это -4? Кроме того, в Java, когда 1100 (позволяет считать 4 бита на данный момент), сохраняется как он определяется, если он равен +12 или -4?? - hagrawal Jul 2 at 16:53

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

ВОПРОС - Как система может установить, как нужно интерпретировать один или несколько смежных байтов? В частности, как система может установить, является ли заданная последовательность байтов равным двоичным числом или 2-мя дополнительными номерами?

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

  • сколько байтов необходимо учитывать
  • как эти байты должны быть интерпретированы

ПРИМЕР - Ниже мы предполагаем, что

  • char длиной 1 байт
  • short длиной 2 байта
  • int и float имеют длину 4 байта

Обратите внимание, что эти размеры относятся к моей системе. Хотя они довольно распространены, они могут отличаться от системы к системе. Если вам интересно, что они в вашей системе, используйте оператор sizeof.

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

// BD(hexadecimal) = 10111101 (binary)
unsigned char   l_Just4Bytes[ 4 ]   =   { 0xBD, 0xBD, 0xBD, 0xBD };

Затем мы читаем содержимое массива с использованием разных типов.

unsigned char и signed char

// 10111101 as a PLAIN BINARY number equals 189
printf( "l_Just4Bytes as unsigned char  -> %hi\n", *( ( unsigned char* )l_Just4Bytes ) );

// 10111101 as a 2 COMPLEMENT number equals -67
printf( "l_Just4Bytes as signed char    -> %i\n", *( ( signed char* )l_Just4Bytes ) );

unsigned short и short

// 1011110110111101 as a PLAIN BINARY number equals 48573
printf( "l_Just4Bytes as unsigned short -> %hu\n", *( ( unsigned short* )l_Just4Bytes ) );

// 1011110110111101 as a 2 COMPLEMENT number equals -16963
printf( "l_Just4Bytes as short          -> %hi\n", *( ( short* )l_Just4Bytes ) );

unsigned int, int и float

// 10111101101111011011110110111101 as a PLAIN BINARY number equals 3183328701
printf( "l_Just4Bytes as unsigned int   -> %u\n", *( ( unsigned int* )l_Just4Bytes ) );

// 10111101101111011011110110111101 as a 2 COMPLEMENT number equals -1111638595
printf( "l_Just4Bytes as int            -> %i\n", *( ( int* )l_Just4Bytes ) );

// 10111101101111011011110110111101 as a IEEE 754 SINGLE-PRECISION number equals -0.092647
printf( "l_Just4Bytes as float          -> %f\n", *( ( float* )l_Just4Bytes ) );

4 байта в ОЗУ (l_Just4Bytes[ 0..3 ]) всегда остаются одинаковыми. Единственное, что меняется, это то, как мы их интерпретируем.

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

Например, выше мы использовали следующие типы для интерпретации содержимого массива l_Just4Bytes

  • unsigned char: 1 байт в обычном двоичном формате
  • signed char: 1 байт в 2 дополнениях
  • unsigned short: 2 байта в простой двоичной нотации
  • short: 2 байта в 2 дополнениях
  • unsigned int: 4 байта в простой двоичной нотации
  • int: 4 байта в 2 дополнениях
  • float: 4 байта в одноточечной нотации IEEE 754

[EDIT] Это сообщение отредактировано после комментария пользователя4581301. Спасибо, что нашли время, чтобы отбросить эти полезные строки!

Ответ 10

Вы можете посмотреть на профессора Джерри Каина из Стэнфорда, объяснив два дополнения, во второй лекции (пояснение относительно 2-х дополнений начинается около 13:00) в серии лекций под названием "Программирование парадигм", доступных для просмотра на канале Standford YouTube. Здесь ссылка на лекционную серию: http://www.youtube.com/view_play_list?p=9D558D49CA734A02.

Ответ 11

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

Если есть x бит, два дополнения будут варьироваться от + (2 ^ x/2 + 1) до - (2 ^ x/2). Одно дополнение будет работать от + (2 ^ x/2) до - (2 ^ x/2), но даст отрицательный нуль (0000 равно 1000 в системе с 4 битами 1).

Ответ 12

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

Но почему вы находите разницу в цифрах от 1? Ну, это не так. Ваше фактическое намерение состоит в том, чтобы вычислить данную двоичную разницу чисел из другого двоичного числа, которое имеет одинаковое количество цифр, но содержит только 1. Например, если ваш номер 10110001, когда вы переворачиваете все эти биты, вы эффективно вычисляете (11111111 - 10110001).

Это объясняет первый шаг в вычислении Two Complement. Теперь включите второй шаг - добавление 1 - также на картинке.

Добавьте 1 к приведенному выше двоичному уравнению:

11111111 - 10110001 + 1

Что вы получаете? Это:

100000000 - 10110001

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

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

Ответ 13

Мы выполняем только операцию добавления для сложения и вычитания. Мы добавляем второй операнд к первому операнду для добавления. Для вычитания мы добавляем 2 дополнения второго операнда к первому операнду.

С представлением из 2-х экземпляров нам не нужны отдельные цифровые компоненты для вычитания &mdash, используются только сумматоры и дополнения.

Ответ 14

Стоит отметить, что на некоторых ранних машинах с добавлением, до дней цифровых компьютеров, вычитание будет выполняться путем того, чтобы оператор вводил значения с использованием разных цветных наборов легенд на каждой клавише (чтобы каждый ключ вводил девять минус номер, подлежащий вычитанию), и нажмите специальную кнопку, чтобы принять перенос в расчет. Таким образом, на шестизначной машине, чтобы вычесть 1234 из значения, оператор ударил бы клавиши, которые обычно указывают "998 765", и нажмите кнопку, чтобы добавить это значение плюс одно к текущему расчету. Арифметика с двумя дополнениями - это просто бинарный эквивалент той более ранней арифметики "десятого дополнения".

Ответ 15

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

Ответ 16

Основным преимуществом представления двух дополнений, которое еще не было упомянуто здесь, является то, что младшие биты суммы, разности или произведения двух дополнений зависят только от соответствующих битов операндов. Причиной того, что 8-битовое знаковое значение для -1 является 11111111, является то, что вычитание любого целого числа, младшие 8 бит которого 00000001 из любого другого целого числа, младшие 8 бит которого 0000000, даст целое число, младшие 8 бит которого 11111111. Математически значение -1 было бы бесконечной строкой из 1, но все значения в диапазоне определенного целочисленного типа будут либо все 1, либо все 0 за определенную точку, поэтому для компьютеров удобно "подписывать-расширять" самый старший бит числа, как если бы он представлял бесконечное число 1 или 0.

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

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

Ответ 17

Один удовлетворительный ответ на вопрос, почему Two2 Complement используется для представления отрицательных чисел, а не для системы одного дополнения,                       Две системы дополнений решают проблему множественных представлений 0 и необходимость end-around-carry, которые существуют в системе с одним дополнением, представляющей отрицательные числа.

Для получения дополнительной информации посетите https://en.wikipedia.org/wiki/Signed_number_representations

Для посещения с бесконечным переносом https://en.wikipedia.org/wiki/End-around_carry

Ответ 18

потому что производители процессоров ленивы!