(-2147483648> 0) 在 C 中返回 true ?

新手上路,请多包涵

-2147483648 是 32 位整数类型的最小整数,但在 if(...) 语句中似乎会溢出:

 if (-2147483648 > 0)
    std::cout << "true";
else
    std::cout << "false";

这将在我的测试中打印 true 。但是,如果我们将 -2147483648 转换为整数,结果会有所不同:

 if (int(-2147483648) > 0)
    std::cout << "true";
else
    std::cout << "false";

这将打印 false

我很困惑。任何人都可以对此作出解释吗?


2012 年 2 月 5 日更新:

感谢您的评论,在我的编译器中, int 的大小为 4 个字节。我正在使用 VC 进行一些简单的测试。我已经更改了问题中的描述。

在这篇文章中有很多非常好的回复, AndreyT 非常详细地解释了编译器将如何处理此类输入,以及如何实现这个最小整数。另一方面, qPCR4vir 给出了一些相关的“好奇心”以及整数的表示方式。如此令人印象深刻!

原文由 benyl 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 524
1 个回答

-2147483648 不是“数字”。 C++ 语言不支持负文字值。

-2147483648 实际上是一个表达式:正文字值 2147483648 一元 - 运算符在它前面。值 2147483648 对于您平台上的 int 范围的正面而言显然太大了。如果类型 long int 在您的平台上具有更大的范围,编译器将不得不自动假设 2147483648 具有 long int 类型。 (在 C++11 中,编译器还必须考虑 long long int 类型。)这将使编译器在较大类型的域中评估 -2147483648 并且结果为负,正如人们所期望的那样。

但是,显然在您的情况下 --- 的范围与 int long int 的范围相同,并且通常没有整数类型的范围大于 int 平台。这正式意味着正常 2147483648 溢出所有可用的有符号整数类型,这反过来意味着您的程序的行为是未定义的。 (在这种情况下,语言规范选择了未定义的行为,而不是要求诊断消息,这有点奇怪,但事实就是这样。)

在实践中,考虑到行为未定义, 2147483648 可能会被解释为一些依赖于实现的负值,在应用一元 - 后恰好变为正值。或者,某些实现可能决定尝试使用无符号类型来表示值(例如,在 C89/90 中,编译器需要使用 unsigned long int ,但在 C99 或 C++ 中则不需要)。允许实现做任何事情,因为无论如何行为是未定义的。

作为旁注,这就是为什么像 INT_MIN 这样的常量通常被定义为

#define INT_MIN (-2147483647 - 1)

而不是看似更直接的

#define INT_MIN -2147483648

后者不会按预期工作。

原文由 AnT stands with Russia 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题