正如this page建议的那样,INT_MAX = 32767
和INT_MIN = -32767
所以INT_MAX - INT_MIN
应该等于65534,但它会给我-1;
我很困惑因为65534没有超出C ++中int的限制,即使我在long long int中赋值,它仍然给了我-1。我想可能是我误解了一些关于C ++减少的机制。任何人都没有INT_MAX
减去INT_MIN
时的确切情况?提前谢谢!
答案 0 :(得分:7)
INT_MAX
类型实际为16位宽的编译器,则 int
仅等于32767。现在,嵌入式处理器的编译器仍然可以看到INT_MAX
的这样的值。
无论INT_MAX
是什么,它都是int
类型的值,它是该类型的最大值。如果在int
类型中,您从最积极的值中减去最负的int
值,则会触发溢出,即未定义的行为。
int
是16位宽还是64位并不重要; INT_MAX - INT_MIN
表示的计算根据ISO C没有明确定义的含义。
-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
然后减去这两个。低位中没有太多有趣的事情,因为0
的序列正从1
的序列中减去。然后,减法到达高位:0 - 1
。这导致值1
,借用(“借用”是减法与加法“进位”的对应)。借用被丢弃,我们只剩下截断的结果1111...1111
。那当然是-1的二进制补码表示。
请注意,INT_MIN
也可以简单地定义为-INT_MAX
,即二进制值1000...0001
。在这种情况下,相同的包装算法将产生结果-2,可能比-1更令人惊讶。
那么为什么你看到-1可能就是你得到了两个补码包装行为,加上INT_MIN
实际上并不是INT_MAX
的算术逆的事实(这会要求一个-2结果),但是比这个值小1的值。
答案 1 :(得分:2)
如果你对某些实现说INT_MAX = 32767
,当然甚至会有32768溢出。
除了注意,如果你要添加两个整数文字说int + int
,即使你将结果分配给long
(假设long可以保存该添加的结果),那也没有用,因为溢出使用int
添加int
时可能会发生 - 因为添加的结果不适合int
;在这种情况下,编译器不会将int
提升为long
,因为添加结果不适合int
内部。
答案 2 :(得分:1)
INT_MAX = 32767和INT_MIN = -32767
实际上他们是:
-32767(-2 ^ 15 + 1)或更少*
32767(2 ^ 15-1)或更高*
我在你的系统上差不多了,sizeof(int)== 4 - > 4个字节 - > 32 位。
INT_MAX定义为2 ^ 32 -1 == 4294967295。
对INT_MIN应用相同的内容。
键入smth,如:
std::cout << INT_MAX << " " << INT_MIN << std::endl;
你会看到。 int(INT_MAX-INT_MIN)中实际存在溢出,因此为-1 。
答案 3 :(得分:1)
该页面没有说明这种情况。它说INT_MAX
至少是32767.它并不是说它是平等的。如果您想知道特定实现的实际价值,请将其打印出来(或者查看该实现的文档,记住它可能取决于目标架构)。
无论如何,INT_MAX
的定义是int
的最大值,因此INT_MAX+1
足以超出int
的限制,更不用说INT_MAX - INT_MIN
。您获得的-1
的值是特定于实现的行为,但它不是来自典型的2补码实现的意外结果,其中{{1}等于2 N-1 -1且INT_MAX
等于-2 N-1 ,对于某些值N,称为&#34;宽度&#34;以INT_MIN
为单位。这通常是[*] 32,但标准允许低至16.因此对于具有32位2的实现,实际值为int
和2147483647
对于具有16位2的补码-2147483648
的实现,补int
,32767
和-32768
。
在这样的实现上,假设整数溢出包围,那么int
的结果将是INT_MAX - INT_MIN
,因为数学值为2 < sup> N -1,其为-1模2 N 。例如,如果您想确保整数溢出包装,GCC有一个选项-1
,如果您没有指定该选项,那么它可能会换行,或者它可能会做一些不同的事情。
[*]通过一些非常不科学的概念&#34;最常见的&#34;。