У меня есть следующий код для INT_MIN/-1
, Я ожидаю, что это будет INT_MAX + 1 (или 0 с опрокидыванием). Однако фактический результат, который я получаю, — INT_MIN. Это мой тестовый код:
#define __STDC_LIMIT_MACROS
#include <stdint.h>
#include <stdio.h>
#include <limits.h>
using namespace std;
int main()
{
int min=INT_MIN;
int res=min/-1;
printf("result: %i\n", res);
printf("max: %i min: %i\n", INT_MAX, INT_MIN);
return 0;
}
Является ли эта реализация специфической и / или неопределенным поведением?
Является ли эта реализация специфической и / или неопределенным поведением?
Да, подписанный Целочисленное переполнение — неопределенное поведение. В соответствии с пунктом 5/4 стандарта C ++ 11:
Если во время оценки выражения результат не определен математически или не находится в диапазоне
представимые значения для его типа, поведение не определено. […]
Обратите внимание, что то же самое не относится к неподписанный арифметика. Как указано в пункте 3.9.1 / 4 и сноске 46:
Целые числа без знака, объявленные как без знака, должны подчиняться законам арифметики по модулю
2^n
гдеn
это число
битов в представлении значения этого конкретного размера целого числа. […]Это подразумевает, что арифметика без знака не переполняется, потому что результат, который не может быть представлен в результате
целочисленный тип без знака уменьшается по модулю на число, которое на единицу больше наибольшего значения, которое может быть представлено
результирующий целочисленный тип без знака.
Это целочисленное переполнение со знаком и, следовательно, неопределенное поведение, это Cert
документ о том, как Убедитесь, что операции со знаковыми целыми числами не приводят к переполнению это здорово, и, насколько я могу судить, охватывает все случаи. Это if
заявление от Division
раздел, который охватывает ваш вопрос:
if ( (sl2 == 0) || ( (sl1 == LONG_MIN) && (sl2 == -1) ) ) {
/* Handle error condition */
}
else {
result = sl1 / sl2;
}