【问题标题】:Why do we define INT_MIN as -INT_MAX - 1? [duplicate]为什么我们将 INT_MIN 定义为 -INT_MAX - 1? [复制]
【发布时间】:2014-11-18 04:17:42
【问题描述】:

AFAIK 这是一个标准的“成语”

#  define INT_MIN   (-INT_MAX - 1)  
#  define INT_MAX   2147483647    

问题:为什么INT_MIN的定义不是-2147483648?

【问题讨论】:

  • 如果两个都单独定义,当你要修改的时候,要提醒自己两个都改。如果其中一个依赖于另一个,那么您只需更改一个,更改将适用于两者。
  • @HuStmpHrrr:我读到有一个原因,但没有解释这个原因(与编译器有关,与代码设计无关)
  • 不幸的是,我目前没有 gcc。但我认为您可以直接尝试int foo = -2147483648; 看看编译器是否会抱怨。我对结果很好奇。
  • 我不喜欢这样一个事实,即当我将其标记为“可能重复”时,它会立即被标记为“重复”。但无论如何,这个问题之前已经被问过很多次了。
  • @AndreyT 我同意。太好了,所有所说的 insta-dupe 的权力都被授予了我们这些有足够疯狂来建立高声望的人,但如果他们能给老 -如果我们认为它是一个样式,则将其命名为副本作为替代方案,但希望我们的其他成员在它背后有额外的重量。我不认为这是一个很难添加的功能。也许可以在 meta 上抛出一些东西。

标签: c types integer signed


【解决方案1】:

因为2147483648long 值,因为它不适合int(在具有32 位int 和64 位long 的通用系统中,在具有32 位@987654327 的系统上@它的类型为long long)。所以-2147483648 的类型是long,而不是int

请记住,在 C 中,无后缀的十进制整数常量是可以表示的第一种类型 intlonglong long

同样在 C 中-2147483648 不是整数常量; 2147483648 是一个整数常量。 -2147483648 是由一元运算符- 和整数常量2147483648 组成的表达式。

编辑:如果您不相信 -2147483648 不是 int 类型(cmets 中的一些人似乎仍然怀疑),您可以尝试打印:

printf("%zu %zu\n", sizeof INT_MIN, sizeof -2147483648);

你很可能会得到:

4 8

在常见的 32 位和 64 位系统上。

另外跟随评论,我说的是最近的 C 标准:使用 c99 或 c11 方言来测试这个。十进制整数常量的 c89 规则不同:-2147483648 在 c89 中属于 unsigned long 类型。实际上在 c89 中(在 c99 中有所不同,见上文),无后缀十进制整数常量的类型为 intlongunsigned long

EDIT2@WhozCraig 添加了另一个示例(但用于 C++)以显示 -2147483648 不是 int 类型。

下面的例子虽然是在 C++ 中,但也说明了这一点。它是用 32 位架构 g++ 编译的。注意从传递的参数推导中收集的类型信息:

#include <iostream>
#include <climits>

template<typename T>
void foo(T value)
{
    std::cout << __PRETTY_FUNCTION__ << '\n';
    std::cout << value << '\n';
}

int main()
{
    foo(-2147483648);
    foo(INT_MIN);
    return 0;
}

输出

void foo(T) [T = long long]
-2147483648
void foo(T) [T = int]
-2147483648

【讨论】:

  • 对不起,我不明白。这个-2147483648 被认为是long
  • 言归正传。一元减号应用于表达式,其类型已由确定。 2147483648 作为值(在应用一元减号之前)在 32 位系统上不能表示为 int
  • 我不认为这是 OP 所要求的,因为 INT_MIN 是使用 INT_MAX 定义的,OP 想知道为什么 INT_MIN 不是使用常量(如 INT_MAX)定义的。
  • @WhozCraig:你说的有道理
  • @ouah:Because 2147483648 is a long value as it does not fit an int 但数字是-2147483648,它是 int 范围的一部分。
猜你喜欢
  • 2013-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多