【问题标题】:Is INT_MIN/-1 defined behavior in C++?INT_MIN/-1 是在 C++ 中定义的行为吗?
【发布时间】:2013-06-18 18:28:19
【问题描述】:

我有以下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;
}

此实现是特定的和/或未定义的行为吗?

【问题讨论】:

  • 有符号溢出未定义,只有无符号溢出定义为“模1 &lt;&lt; width”。
  • INT_MAX + 1 在翻转时不是 0,而是 INT_MIN
  • 如果有符号整数的表示是一个的补码或有符号的大小,这是定义的行为,因为这样就不会发生溢出。
  • @DanielFischer 这不可能。如果是真的,那么可以使用反码将整个文档存储在单个 int 中。
  • @wizzwizz4 对不起,我不明白你的意思。以防万一:在我的评论中,我的意思是 INT_MIN/-1 是在一个补码或有符号幅度表示中定义的行为(因为这样数学结果也可以表示为 int)。

标签: c++ math integer-overflow integer-division


【解决方案1】:

此实现是特定的和/或未定义的行为吗?

是的,有符号整数溢出是未定义的行为。根据 C++11 标准的第 5/4 段:

如果在计算表达式期间,结果未在数学上定义或不在 其类型的可表示值,行为是未定义的。 [...]

注意,这同样不适用于 unsigned 算术。如第 3.9.1/4 段和脚注 46 所述:

声明为无符号的无符号整数应遵守算术模2^n 的定律,其中n 是数字 该特定整数大小的值表示中的位数。 [...]

这意味着无符号算术不会溢出,因为结果不能由结果表示 无符号整数类型以比可以表示的最大值大一的数字为模减少 生成的无符号整数类型。

【讨论】:

    【解决方案2】:

    这是有符号整数溢出,因此是未定义的行为,这个关于如何使用 Ensure that operations on signed integers do not result in overflowCert 文档很棒,据我所知涵盖了所有实例。这是 Division 部分的 if 声明,涵盖了您的问题:

    if ( (sl2 == 0) || ( (sl1 == LONG_MIN) && (sl2 == -1) ) ) {
      /* Handle error condition */
    }
    else {
      result = sl1 / sl2;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-28
      • 2016-09-15
      • 1970-01-01
      • 2014-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-21
      相关资源
      最近更新 更多