代码:
unsigned int i = 1<<31;
printf("%d\n", i);
为什么输出为-2147483648
,为负值?
更新了问题:
#include <stdio.h>
int main(int argc, char * argv[]) {
int i = 1<<31;
unsigned int j = 1<<31;
printf("%u, %u\n", i, j);
printf("%d, %d\n", i, j);
return 0;
}
上面的印刷品:
2147483648, 2147483648
-2147483648, -2147483648
那么,这是否意味着,签署了int&amp; unsigned int具有相同的位值,不同之处在于将第31位转换为数字值时如何处理?
答案 0 :(得分:5)
%d
打印int
的{{1}}版本。对unsigned int i
尝试%u
。
unsigned int
printf("%u\n", i);
int main(){
printf("%d, %u",-1,-1);
return 0;
}
即存储有符号整数的方式以及它如何从无符号转换为有符号整数或反之亦然将对您有所帮助。关注this。
要回答您更新的问题,系统如何代表它们,即在2的补码中(如上述情况所示)
Output: -1, 4294967295
。
答案 1 :(得分:4)
对%u
unsigned int
”
printf("%u\n", i);
............................................... ........
对更新问题的响应:任何位序列都可以解释为有符号或无符号值。
答案 2 :(得分:3)
printf("%d\n", i);
调用UB。 i
为unsigned int
,您尝试将其打印为signed int
。写1 << 31
而不是1U << 31
也是未定义的。
将其打印为:
printf("%u\n", i);
或
printf("%X\n", i);
关于您更新的问题,它也会出于同样的原因调用UB(如果您使用'1U'而不是1
,那么因为int
初始化为1U << 31
超出范围值。如果unsigned
初始化超出范围值,则模块化算法进入图像并且分配余数。对于signed
,行为未定义。)
了解平台上的行为
在您的平台上,int似乎是4个字节。当您编写1 << 31
之类的内容时,它会转换为您计算机上的位图0x80000000
。
现在,当您尝试将此模式打印为已签名时,它会在2s完成系统中打印带符号的解释,即-2 31 (AKA INT_MIN)。当您将其打印为无符号时,您会得到2 31 作为输出。
<强>学习收获强>
1.使用1U << 31
代替1 << 31
2.始终在printf中使用正确的打印说明符
3.将正确的参数类型传递给variadic functions
4.当隐式类型转换(无符号 - >带符号,宽类型 - >窄类型)发生时要小心。如果可能的话,完全避免这种铸件。
答案 3 :(得分:3)
尝试
printf("%u\n", i);
通过使用%d
说明符,printf期望参数为int
,并将其转换为int
。
因此,请%u
使用unsigned int
。
答案 4 :(得分:3)
您没有在unsigned
上进行轮班操作,而是在signed int
上进行轮班操作。
1
是signed
。signed
(假设int
是32位宽),这已经是未定义的行为unsigned
。 unsigned
作为签名,再次没有定义的行为。答案 5 :(得分:2)
%u
用于unsigned int
%d
用于签名int。
:
2147483648, 2147483648 (output for unsigned int)
-2147483648, -2147483648 (output for signed int )