C++ 为什么INT_MAX减去INT_MIN等于-1?

C++ 为什么INT_MAX减去INT_MIN等于-1?,c++,C++,正如建议的那样,INT_MAX=32767和INT_MIN=-32767因此INT_MAX-INT_MIN应该等于65534,但它给了我-1 我很困惑,因为65534没有超出C++中的int限制,即使我在长的int中赋值,它仍然给了我1。我想可能是我误解了C++还原的一些机制。任何人都不知道当INT\u MAX减去INT\u MIN时到底发生了什么?提前谢谢 INT\u MAX仅当编译器的INT类型实际上是16位宽时才等于32767。INT_MAX的这样一个值现在仍然可以在嵌入式处理器的编译器中

正如建议的那样,
INT_MAX=32767
INT_MIN=-32767
因此
INT_MAX-INT_MIN
应该等于65534,但它给了我-1


<>我很困惑,因为65534没有超出C++中的int限制,即使我在长的int中赋值,它仍然给了我1。我想可能是我误解了C++还原的一些机制。任何人都不知道当
INT\u MAX
减去
INT\u MIN
时到底发生了什么?提前谢谢

INT\u MAX
仅当编译器的
INT
类型实际上是16位宽时才等于32767。
INT_MAX
的这样一个值现在仍然可以在嵌入式处理器的编译器中看到

无论
INT\u MAX
是什么,它既是
INT
类型的值,也是该类型的最大值。如果在
int
类型中,将最负的
int
值从最正的值中减去,则触发溢出,这是未定义的行为

不管你的
int
是16位宽还是64位宽;根据ISO C,
INT_MAX-INT_MIN
表示的计算没有明确定义的含义

可能-1结果是由您的实现定义的。也就是说,编译器遵循有关整数溢出的特定规则。检查编译器手册

如果可用的类型大于
int
,则可以执行减法。例如,假设某个给定编译器上的
long-long
int
宽。(这不是必需的,但假设我们有一个实现,它是真的,这是常见的)。然后我们可以做:

(long long) INT_MAX - (long long) INT_MIN
现在没有溢出,因为计算是在较宽的类型中执行的。我们得到了算术上正确的值。当然,该值不能重新放入类型
int


现在有一个关于-1的假设,请记住它可能只是一个侥幸,根本不是由编译器定义的

假设您有一个用于二的补码机的编译器,它将有符号溢出的行为定义为具有简单的“包装”语义。-1值可以解释如下。假设
INT_MIN
是最负的两个补码值,用二进制表示为
1000..0000
INT_MAX
0111..1111
。计算
INT_MAX-INT_MIN
然后减去这两个。在低位没有什么有趣的事情发生,因为从
1
序列中减去了
0
。然后,减法到达高位:
0-1
。这导致值
1
,带有借出(“借出”是减法与加法的“进位”的对应项)。借用被丢弃,只剩下被截断的结果
1111…1111
。这当然是二者对-1的补码表示

请注意,
INT\u MIN
也可以简单地定义为
-INT\u MAX
,它是二进制值
1000…0001
。在这种情况下,相同的包装算法将产生结果-2,可能比-1更令人惊讶


所以你看到-1的原因可能是你得到了2的补码包装行为,加上
INT\u MIN
实际上不是
INT\u MAX
的算术逆(这需要-2的结果),但是一个比这个小一的值。

INT\u MAX
只有在
INT
类型实际上是16位宽的编译器上才等于32767。
INT_MAX
的这样一个值现在仍然可以在嵌入式处理器的编译器中看到

无论
INT\u MAX
是什么,它既是
INT
类型的值,也是该类型的最大值。如果在
int
类型中,将最负的
int
值从最正的值中减去,则触发溢出,这是未定义的行为

不管你的
int
是16位宽还是64位宽;根据ISO C,
INT_MAX-INT_MIN
表示的计算没有明确定义的含义

可能-1结果是由您的实现定义的。也就是说,编译器遵循有关整数溢出的特定规则。检查编译器手册

如果可用的类型大于
int
,则可以执行减法。例如,假设某个给定编译器上的
long-long
int
宽。(这不是必需的,但假设我们有一个实现,它是真的,这是常见的)。然后我们可以做:

(long long) INT_MAX - (long long) INT_MIN
现在没有溢出,因为计算是在较宽的类型中执行的。我们得到了算术上正确的值。当然,该值不能重新放入类型
int


现在有一个关于-1的假设,请记住它可能只是一个侥幸,根本不是由编译器定义的

假设您有一个用于二的补码机的编译器,它将有符号溢出的行为定义为具有简单的“包装”语义。-1值可以解释如下。假设
INT_MIN
是最负的两个补码值,用二进制表示为
1000..0000
INT_MAX
0111..1111
。计算
INT_MAX-INT_MIN
然后减去这两个。在低位没有什么有趣的事情发生,因为从
1
序列中减去了
0
。然后,减法到达高位:
0-1
。这导致值
1
,带有借出(“借出”是减法与加法的“进位”的对应项)。借用被丢弃,只剩下被截断的结果