Почему дополнение до двух по-прежнему работает при работе с большими числами?

Недавно я читал о дополнении до двух и заметил, что при работе с целыми числами без знака, очень близкими к пределу (в основном числами, достаточно большими, чтобы MSB был равен 1), вычитание, похоже, все еще работает, даже когда бит со знаком все еще должен быть заполнен фактическим информация о номере. Например, возьмите 254 и 252, представленные как 0b11111110 и 0b11111100 в 8-битном формате соответственно. Вычитание потребует дополнения 2 до 252, так что 0b11111110 + 0b00000100 дает правильный результат 0b00000010 = 2. Почему именно это работает так, как задумано?

PS: Я также заметил, что если бы я взял беззнаковые числа и посмотрел на них, как если бы они были в форме дополнения до двух, я бы получил -2 и -4, которые вычитаются до 2. Может быть, это следствие того, как система была создана и в конечном итоге использовалась при проектировании?


person Carmo    schedule 06.03.2021    source источник
comment
Как 0b11111110 - 0b00000100 = 0b00000010? Ооо, вы говорите, -252 это то же самое, что + (- 252). Думаю, у вас тогда опечатка. То, что меня смутило, должно быть + не - в вашем посте.   -  person JohnFilleau    schedule 06.03.2021
comment
(Игнорируя опечатку в знаке) Почему не работает?   -  person Thomas Jager    schedule 06.03.2021
comment
Если это два дополнения к 8-битному числу, N будет (256 - N). И если 8-битное сложение и вычитание производится по модулю 256, то это N1 - N2 = (N1 - N2)%256. Если вы замените вычитание N2 сложением его двойного дополнения, вы получите (N1 - N2) = (N1 + (256 - N2))%256. Операция по модулю является распределительной и 256%256 = 0, поэтому вы обнаружите, что для любых значений N1 и N2 добавление двух дополнений к N2 эквивалентно вычитанию N2.   -  person JohnFilleau    schedule 06.03.2021
comment
@JohnFilleau действительно, это была опечатка с моей стороны. Сразу поправлю, извините.   -  person Carmo    schedule 06.03.2021
comment
@ThomasJager Я имею в виду, что в моем понимании, поскольку большинство ресурсов, которые я нашел, анализируют два дополнительных числа как подписанные, операция не будет работать с беззнаковыми числами за пределами диапазона, в котором обычно находятся подписанные числа.   -  person Carmo    schedule 06.03.2021
comment
Вышесказанное было упрощением. Дополнение до двух - это операция над набором битов, а не над значением, а для отображений, где значение битов является суммой степеней 2 индексов всех установленных битов (N = b0 * 1 + b1 * 2 + b2 * 4 ... + b7 * 128), как в 8-битном целом числе без знака, тогда работает упрощение дополнения до двух до (256 - N).   -  person JohnFilleau    schedule 06.03.2021
comment
Я никогда не делал этого раньше, но если вы начнете разрабатывать свое сопоставление (состояние разряда в значение) на основе требований вашей системы, а пролистывание - это простой способ реализовать схему сложения, и вы хотели бы минимизировать избыточные значения, и вы хотите, чтобы ваши сопоставления были монотонно разнесены, тогда конечным результатом должно быть (я думаю) сопоставление, в котором отрицательное значение значения оказывается двумя дополнениями его битового представления.   -  person JohnFilleau    schedule 06.03.2021
comment
@JohnFilleau, спасибо за подробное объяснение. Я не думал, что можно представить операцию по модулю, но это имеет смысл, поскольку значения переносятся в этих системах. Я думаю, что мое главное замешательство в понимании этого состоит в том, что я все время думал, что компьютеру нужно будет преобразовать неподписанные целые числа в подписанные, чтобы иметь возможность выполнять эти операции, но, как вы указали, операция отлично работает без знака. Можете ли вы добавить свое объяснение в качестве ответа?   -  person Carmo    schedule 06.03.2021
comment
@Carmo невозможно, потому что сегодня субботнее утро, а я еще не пил кофе. Скопируйте и вставьте в свой ответ и примите его, если это применимо.   -  person JohnFilleau    schedule 06.03.2021
comment
@JohnFilleau ха-ха, все в порядке, подойдет. еще раз, спасибо.   -  person Carmo    schedule 06.03.2021


Ответы (1)


После комментария Джона Филло:

Если два дополнения 8-битного числа N равно (256 - N), и если 8-битное сложение и вычитание по модулю 256, то это N1 - N2 = (N1 - N2)%256. Если вы замените вычитание N2 сложением его двух дополнений, вы получите (N1 - N2) = (N1 + (256 - N2))%256. Операция по модулю является распределительной и 256%256 = 0, поэтому вы обнаружите, что для любых значений N1 и N2 добавление двойного дополнения N2 эквивалентно вычитанию N2.

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

person Carmo    schedule 06.03.2021