Пример дополнения 2, почему бы не унести?

Я смотрю отличные лекции Дэвида Малана (здесь), то есть переходя на двоичный. Он говорил о представлениях подписанный / неподписанный, комплимент 1 и дополнение 2. Было добавлено 4 + (-3), которые выстроились следующим образом:

0100
1101 (flip 0011 to 1100, then add "1" to the end)
----
0001

Но он махнул волшебными руками и выбросил последний керри. Я провел небольшое исследование википедии, но не совсем понял, может ли кто-нибудь объяснить мне, почему этот конкретный перенос (в столбцах 8 -> 16) был отброшен, но он сохранил тот, который был перед ним?

Спасибо!


person Alex Mcp    schedule 02.11.2009    source источник
comment
Обратите внимание: это не переворот, тогда добавьте 1 в конец. Это переверните биты и добавьте 1. Это важное различие. То, как вы это написали, подразумевает, что вы просто установили конечный бит на 1, но это неправильно. Вы добавляете 1, поэтому керри и такие будут применяться. Таким образом, -4 будет 0100 преобразовано в 1011, а затем прибавить 1, чтобы получить 1100.   -  person Herms    schedule 03.11.2009
comment
Полезно знать, спасибо. Я даже признаю, что когда я впервые услышал его переворот, в примере было 3 (0011), и он превратился в (1100), который выглядит так же, как переворот L-R, чем переключение каждого бита. Это было у меня какое-то время ...   -  person Alex Mcp    schedule 03.11.2009


Ответы (10)


Последний перенос был сброшен, потому что он не помещается в целевое пространство. Это будет пятый бит.

Если бы он выполнил такое же добавление, но, например, с 8-битным хранилищем, это выглядело бы так:

00000100
11111101
--------
00000001

В этой ситуации мы также застряли бы с «неиспользованным» керри.

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


x86-процессоры хранят такой дополнительный перенос во флаге переноса (CF), который можно протестировать с помощью определенных инструкций.

person Magnus Hoff    schedule 02.11.2009

Перенос - это не то же самое, что переполнение

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

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

person DigitalRoss    schedule 02.11.2009
comment
Интересный результат. Я всегда думал, что переполнение происходит всякий раз, когда результат операции требует большего количества битов, чем предусмотрено, что приводит к отбрасыванию более высоких битов. Запись в википедии, кажется, согласна с этим (en.wikipedia.org/wiki/Arithmetic_overflow). - person MAK; 03.11.2009
comment
Некоторые переносы являются переполнением, некоторые - нет. Все сложно. - person DigitalRoss; 03.11.2009

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

 ...000100
+...111101
----------
....000001
person David R Tribble    schedule 02.11.2009

В какой-то момент вам нужно установить количество бит для представления чисел. Он выбрал 4 бита. Любой перенос в 5-й бит теряется. Но это нормально, потому что он решил представить число всего в 4 битах.

Если бы он решил использовать 5 бит для представления чисел, он бы получил тот же результат.

person Robert    schedule 02.11.2009

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

В дополнении до 2 вы используете бит переноса, чтобы сигнализировать, было ли переполнение в последней операции.

Вы должны посмотреть на ПОСЛЕДНИЕ два бита переноса, чтобы увидеть, было ли переполнение. В вашем примере последние два бита переноса были 11, что означает отсутствие переполнения.

Если последние два бита переноса равны 11 или 00, то переполнения не произошло. Если последние два бита переноса равны 10 или 01, то произошло переполнение. Вот почему он иногда заботился о переносе, а иногда игнорировал его.

Первый ряд ниже - это ряд переноса. Крайние левые биты в этой строке используются, чтобы определить, было ли переполнение.

1100
 0100
 1101
 ----
 0001
person Polaris878    schedule 02.11.2009

Похоже, вы используете только 4 бита, поэтому столбца 16 нет.

Если бы вы использовали более 4 битов, то представление -3 было бы другим, и перенос математических вычислений все равно был бы отброшен. Например, с 6 битами у вас будет:

 000100
 111101
 ------
1000001

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

person Herms    schedule 02.11.2009

Рассмотрим 25 + 15:

5 + 5 = 10, мы оставляем 0 и позволяем 1 перейти в столбец десятков. Тогда это 2 + 1 (+ 1) = 4. Значит, результат 40 :)

То же самое и с двоичными файлами. 0 + 1 = 1, 0 + 0 = 0, 1 + 1 = 10 => отправить 1 в 8-столбец, 0 + 1 (+ 1) = 10 => отправить 1 в следующий столбец - вот переполнение и почему мы просто выбрасываем 1.

Вот почему дополнение 2 так здорово. Это позволяет вам добавлять / вычитать так же, как вы делаете с base-10, потому что вы (ab) используете тот факт, что бит знака - это MSB, который будет каскадировать операции вплоть до переполнения, когда это необходимо.

Надеюсь, я понял. Сложно это объяснить, когда английский для тебя не родной язык :)

person cwap    schedule 02.11.2009

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

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

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

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

person Michael Burr    schedule 02.11.2009
comment
единственный раз, когда перенос указывает на проблему, - это когда есть условие переполнения. Я не верю, что это правильно (при различении флагов OVERFLOW и CARRY). Перенос используется для беззнаковой математики, переполнение используется для знаковой математики. На самом деле это разные биты на машине с двумя комплиментами, а не один и тот же бит, который используется повторно. - person jww; 19.06.2011

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

person Mark Ransom    schedule 02.11.2009

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

Теперь, учитывая это, мы можем видеть из повседневной математики, что 4 + (-3) = 1, что и есть у вас.

person Matthew Scharley    schedule 02.11.2009