Внедрение/применение циклической арифметики в C

Стандарт C говорит, что переполнение в арифметике не определено.

Я хотел бы знать, как реализовать циклическую арифметику с точки зрения производительности. Это означает, что решения для проверки переполнения, подобные представленным здесь не подходят (поскольку они замедляют работу примерно на порядок).

Я предполагаю, что решение будет включать в себя написание процедуры сборки для этого. Есть ли доступная библиотека, которая делает это (предпочтительно для нескольких архитектур, хотя x86 является обязательным)?

В качестве альтернативы, есть ли флаг компилятора (для gcc и clang), который заставляет компилятор применять циклическую семантику для целочисленной арифметики?


person Norswap    schedule 21.11.2016    source источник
comment
Стандарт C говорит, что переполнение в арифметике не определено. - Это очень неправильно!   -  person too honest for this site    schedule 22.11.2016
comment
Используйте unsigned целые числа, где переполнение всегда определено, или компилируйте с -fwrapv, чтобы получить надежное циклическое переполнение для целых чисел со знаком.   -  person PSkocik    schedule 22.11.2016


Ответы (1)


Переполнение Signed не определено. Неподписанные переносы переполнения. Реализация циклической арифметики со знаком в основном заключается в том, чтобы делать все в беззнаковой математике. Тем не менее, есть несколько вещей, о которых нужно быть осторожным:

  1. Арифметика unsigned short и unsigned char работает путем преобразования операндов либо в int, либо в unsigned int. Обычно int, если только вы не используете странную настройку, когда int не имеет достаточного диапазона для хранения всех значений unsigned short. Это означает, что преобразование short или char в unsigned short или unsigned char для арифметики все еще может привести к переполнению целого числа со знаком и UB. Чтобы избежать этого, вам нужно выполнить расчеты в unsigned int или большем размере.
  2. преобразование unsigned->signed технически определяется реализацией, когда исходное значение выходит за пределы диапазона типа результата. Это не должно быть проблемой для большинства компиляторов и архитектур.

В качестве альтернативы, если вы хотите пойти по маршруту флага компилятора, -fwrapv делает перенос переполнения со знаком для сложения, вычитания и умножения в GCC и Clang. Однако это ничего не делает с INT_MIN / -1.

person user2357112 supports Monica    schedule 21.11.2016