2016-11-21 15 views
-3

В стандарте C указано, что переполнение в арифметике не определено.Внедрение/принудительная арифметика обхода в C

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

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

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

+3

«Стандарт C говорит, что переполнение в арифметике не определено». -Это очень неправильно! – Olaf

+1

Используйте целые числа unsigned, где переполнение всегда определяется или компилируется с помощью '-fwrapv', чтобы получить надёжное переполнение над целыми целыми числами. – PSkocik

ответ

3

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

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

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

 Смежные вопросы

  • Нет связанных вопросов^_^