2014-01-31 1 views
3

Я разрабатываю простой комплект игрушек и сопровождающий эмулятор, и я пытаюсь выяснить, какие инструкции следует поддерживать. На пути арифметики у меня в настоящее время есть unsigned add, subtract, multiply и divide. Тем не менее, я не могу найти окончательного ответа на следующий вопрос: кому из арифметических операторов нужны подписанные версии и для которых эквивалентны подписанные версии без знака и двух?Какие арифметические операции одинаковы для неподписанных и двух дополняемых номеров?

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

Спасибо!

ответ

2

Добавление и вычитание одинаковых для дополнений с подписью и без знака 2s, предполагая, что вы будете обрабатывать переполнение/недополнение в обычном режиме для большинства процессоров, т. Е. Просто обернуть. Умножение и деление разные. Таким образом, вам нужна только одна процедура сложения и одна процедура вычитания независимо от подписанности, но вам нужно разделить раздельное и беззнаковое умножение и разделить.

+2

[Non увеличивающийся результат умножения одинакова для обоих подписанных и неподписанных типов] (http://stackoverflow.com/q/14063599/995714) –

0

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

+1

Поскольку это набор команд эмулятор, я бы ожидать, что целочисленное переполнение/underflow будет вести себя обычным способом, т. е. обернуть по модулю 2^N, поэтому сложение и вычитание будут одинаковыми как для подписанных, так и для unsigned. –

+0

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

0

сложение, вычитание и умножение являются такими же, если:

  1. Ваши входы и выходы имеют одинаковый размер
  2. Ваше поведение при переполнении оберточного типа по модулю 2 п

Отдел другой.

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

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

  1. Переполнение подписанной арифметики в C является неопределенным поведением. Чтобы получить надежный modulo 2 n Арифметика поведения должна выполняться с использованием неподписанных типов.
  2. C будет продвигать типы, меньшие, чем int to int. Чтобы избежать таких рекламных акций, необходимо проявлять большую осторожность (добавление 0u или умножение на 1u в начале вашего расчета - один из способов).
  3. Преобразование от неподписанных типов к подписанным типам является реализацией, реализация, которую я видел, делает разумную вещь, но могут быть и такие, которые этого не делают.
Смежные вопросы