Вопрос

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

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

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

Спасибо!

Это было полезно?

Решение

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

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

00000100
11111101
--------
00000001

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

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


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

Другие советы

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

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

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

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

 ...000100
+...111101
----------
....000001

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

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

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

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

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

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

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

1100
 0100
 1101
 ----
 0001

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

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

 000100
 111101
 ------
1000001

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

Рассмотрим 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 так здорово.Он позволяет вам складывать/вычитать так же, как вы делаете это с базой 10, потому что вы (ab) используете тот факт, что знаковый бит - это старший бит, который будет каскадировать операции вплоть до переполнения, когда это необходимо.

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

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top