为什么我能用hex表示大于MAXINT的int,而不是十进制?
据我所知,十进制和hex只是(假设)一个int
的表示。
这意味着如果我定义一个整数, x
我应该能够将x
打印为:
- 小数:
printf("%d", x);
- hex:
printf("%x", x);
我不明白的是当x
超过MAXINT时这是如何表现的。
以下面的代码为例:
#include int main(int argc, char** argv) { // Define two numbers that are both less than MAXINT int a = 808548400; int b = 2016424312; int theSum = a + b; // 2824972712 -> larger than MAXINT printf("%d\n", theSum); // -1469994584 -> Overflowed printf("%x\n", theSum); // A861A9A8 -> Correct representation }
正如我的评论所示,这两个十进制数的总和是一个大于MAXINT的数字。 这个数字在以十进制打印时溢出(如我所料),但是当以hex打印时,它看起来非常好。
有趣的是,如果我继续添加此数字,并使其再次溢出,它将返回正确表示十进制数。 hex数始终是正确的。
任何人都可以解释为什么会这样。
TIA
引用n1570(最新的C11草案), §7.21.6.1p8 :
[…]
o,u,x,Xunsigned int
参数转换为无符号八进制( o ),无符号十进制( u )或无符号hex表示法( x或X )[…]
因此,简而言之,您在此处使用了错误类型的转换说明符。 实际上,您的签名溢出是未定义的行为 ,但您的实现显然使用2的补码表示负数,溢出导致系统的回绕 ,因此结果与正确的无符号数完全相同。
如果您使用%u
而不是%x
,则会看到十进制表示法中的相同数字。 同样,这将是系统上恰好 “正确”的未定义行为的结果。 始终避免签名溢出,结果可以是任何东西 。