Там нет простого, вообще, переносимый способ избежать целочисленного переполнения.
Использование более широкого целочисленного типа не является общим решением, поскольку нет гарантии, что существует более широкий целочисленный тип. Для типов int
и long
очень распространены одинаковые размеры на некоторых системах. 32-разрядные системы обычно составляют как int
, так и long
32 бита; даже некоторые 64-битные системы делают то же самое. И некоторые 64-битные системы делают как int
, так и long
64 бит.
Вы писали:
И я была предоставлена информация о том, что переменная res
не может пересечь предел целое.
Лучше быть осторожным с терминологией. Хотя имя типа int
, очевидно, является аббревиатурой слова «целое число», слова не являются синонимами. В C и C++ int
является одним из нескольких целых чисел типов; другие включают unsigned char
и long long
.
Предположительно, что вы имеете в виду, что значение res
не должны находиться за пределами диапазона типа int
, который INT_MIN
к INT_MAX
.
Если вы используете long long
для получения результата, вероятно, вы сможете избежать переполнения; вы можете сравнить результат с значениями INT_MIN
и INT_MAX
и предпринять любые корректирующие действия, если это вне пределов досягаемости. Но все же возможно, что и int
, и long long
будут 64 бит. То, что вы делаете с этим, зависит от того, насколько портативен ваш код.
Вы не можете безопасно проверить, не произошло ли превышение знака целого сложения или вычитания после факта. Переполнение в подписанной арифметике вызывает неопределенное поведение.Как правило, результат обертывается, но в принципе ваша программа может потерпеть крах, прежде чем у вас будет возможность изучить результат.
Некоторые компиляторы могут предоставлять функции, которые выполняют безопасную подписанную арифметику и сообщают вам, произошло ли переполнение. Обратитесь к документации вашего компилятора.
Есть способы проверить операнды перед выполнением операции. Они сложны, и я слишком ленив, чтобы работать над деталями, но вкратце:
- Если операнды
+
имеют противоположные знаки, или если один из операндов имеет 0
, добавление является безопасным.
- Если оба операнда положительны, добавление безопасно, если
x
не превышает INT_MAX - y
.
- Если оба операнда отрицательные, добавление безопасно, если
y
составляет не менее INT_MIN - y
.
Я не гарантирую, что приведенное выше полностью верно * Я просто написал это с головы), но в большинстве случаев это, вероятно, больше усилий, чем того стоит.
Одна переменная не увеличит объем памяти вашей программы каким-либо значимым образом, и поскольку ваш пример неполный, похоже, что это будет переменная в стеке. Вы также делаете предположение, что long больше, чем int, и этого может и не быть. –
Вариант 3 бессмыслен. Я бы выбрал вариант 2, а не потому, что 'long' увеличит использование вашей памяти (это не будет иметь никакого смысла), но поскольку' long' не обязательно делает то, что вы хотите (он может иметь тот же размер, что и ' int'). –
Вариант 2 все еще может быть неудачным. Возьмите 'a = INT_MAX, b = 2, c = 1'. – chris