由于此页面的建议,INT_MAX = 32767并INT_MIN = -32767因此INT_MAX - INT_MIN应等于65534,但它给了我-1;
我很困惑,因为65534不会超出C++中int的限制,即使我在long long int中赋值,它仍然给了我-1.我想可能是我误解了一些关于C++减少的机制.任何人在INT_MAX减去时没有什么正在发生的事情INT_MIN?提前致谢!
INT_MAX如果你的int类型实际上是16位宽的编译器,则只等于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
Run Code Online (Sandbox Code Playgroud)
现在没有溢出,因为计算是在更宽的类型中进行的.我们获得算术上正确的值.当然,这个值不适合类型int.
现在有一个关于-1的假设,记住它可能只是一个侥幸而根本没有你的编译器定义.
假设您有一个二进制补码机器的编译器,它将带符号溢出的行为定义为具有简单的"包装"语义.然后可以如下解释-1值.假设INT_MIN是最负的二进制补码值,用1000..0000二进制表示.INT_MAX是0111..1111.然后计算INT_MAX - INT_MIN减去这两个.在较低位中没有太多有趣的事情发生,因为0从1s 的序列中减去了s 的序列.然后,减法到达高位:0 - 1.这导致值1,借用("借"是减法与加法"进位"的对应).借用被丢弃,我们只剩下截断的结果1111...1111.那当然是-1的二进制补码表示.
注意,INT_MIN也可以简单地定义为-INT_MAX二进制值1000...0001.在这种情况下,相同的包装算法将产生结果-2,可能比-1更令人惊讶.
那么为什么你看到-1可能是你得到了两个补码包装行为,加上实际上INT_MIN并不是算术逆的事实INT_MAX(这将要求-2结果),但是一个比一个小于1的值.那.