Целочисленная арифметика при переполнении

0

Два 32-битных целочисленных значения A и B обрабатываются для получения 32-битных целых чисел C и D в соответствии со следующими правилами. Какое из правил (-ов) является (обратимым)? т.е. можно ли получить A и B, заданные c и D во всех условиях?

A. C = (int32) (A+ B), D = (int32) (AB)

B. C = (int32) (A+ B), D = (int32) ((AB) >> 1)

C. C = (int32) (A+ B), D = B

D. C = (int32) (A+ B), D = (int32) (A+ 2 * B)

E. C = (int32) (A * B), D = (int32) (A/B)

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

Учитывая, что целочисленное сложение является коммутативным и ассоциативным, C, по-видимому, истинно, потому что мы можем получить A по (A+ (BB)). Как насчет D? Можно ли считать, что 2 * B = B + B st. B = A+B+B-(A+B)?

И умножение сложнее, но я знаю, что он не может получить A, если есть переполнение.

Теги:
integer-arithmetic

1 ответ

7

Это цитата из 5 [expr], пункт 4:

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

То, что делает переполнение для целых чисел без знака, определено в пункте 3.9.1 [basic.fundamental] пункта 4:

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

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

  • 0
    Но подписанное дополнение является коммутативным и ассоциативным. Этого недостаточно для формирования абелевой группы? И какие-либо предложения по конкретной проблеме выше (2-й вопрос)?
  • 0
    @zoujyjs: правила должны применяться к любому значению в группе. Однако они явно не применяются, например, для A == std::numeric_limits<int>::max() и B == 2 поскольку A + B и A * B оба переполняются, что приводит к неопределенному поведению.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню