我有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;
}
此实现是特定的和/或未定义的行为吗?
答案 0 :(得分:5)
此实现是特定的和/或未定义的行为吗?
是的,签名整数溢出是未定义的行为。根据C ++ 11标准的第5/4段:
如果在评估表达式期间,结果未在数学上定义或不在范围内 其类型的可表示值,行为未定义。 [...]
请注意,这同样适用于 unsigned 算术。如第3.9.1 / 4段和脚注46所述:
无符号整数,声明为无符号整数,应遵守算术模
2^n
的算法,其中n
是数字 特定整数大小的值表示中的位数。 [...]这意味着无符号算术不会溢出,因为结果无法表示 无符号整数类型以模数减少,该数字大于可由其表示的最大值 得到无符号整数类型。
答案 1 :(得分:3)
这是带符号的整数溢出,因而是未定义的行为,这个关于如何 Ensure that operations on signed integers do not result in overflow的Cert
文档很棒,据我所知,涵盖了所有实例。这是if
部分中涵盖您问题的Division
声明:
if ( (sl2 == 0) || ( (sl1 == LONG_MIN) && (sl2 == -1) ) ) {
/* Handle error condition */
}
else {
result = sl1 / sl2;
}