好的,这是一个奇怪的问题:
unsigned long long
个变量(我使用了long
个变量,效果相同)sizeof
返回8,这很好)但是,当我尝试使用像1<<63
这样的值,并执行一些简单的按位操作时,奇怪的是,我似乎得到了负值。为什么?
我的测试代码:
unsigned long long c = 0;
c |= 1l << 56; printf("c = %lld\n",c);
c |= 1l << 63; printf("c = %lld\n",c);
输出
c = 72057594037927936
c = -9151314442816847872
旁注:
c = 1l<<63
,也会发生同样的事情。有什么建议吗?
答案 0 :(得分:22)
d
说明符的%lld
部分告诉printf
该参数应该被视为有符号整数。请改用u
:%llu
。
从手册页:
d,我
int参数转换为 signed 十进制表示法。
o,u,x,X
unsigned int参数转换为 unsigned 八进制(o),无符号十进制(u)或无符号十六进制(x和X) )符号。
答案 1 :(得分:4)
我认为你实际上在这里做了一些未定义的事情。我认为表达式1l << 63
在C中是未定义的,因为编译器将在有符号类型中表示1l
,并且移位63位会导致有符号溢出(在C中未定义)。我不是专家,但似乎你想要1ull << 63
。
如果您在clang中传递-Weverything
,您的原始代码实际上会抱怨这一点:
foo.c:7:23: warning: signed shift result (0x8000000000000000) sets the sign bit of the
shift expression's type ('long') and becomes negative [-Wshift-sign-overflow]
c |= 1l << 63; printf("c = %lld\n",c);
~~ ^ ~~
编辑:是的,那么你需要从另一个答案中获得正确的printf格式。