9

好的,这是一个奇怪的问题:

  • 我正在使用unsigned long long变量(我甚至使用过变量long,效果相同)
  • 需要能够存储 64 位整数(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

旁注:

  1. 当然,即使我c = 1l<<63直接做也会发生同样的事情。
  2. 所有测试均在 Mac OS X 10.6 上进行,并使用 Apple 的 LLVM Compiler 3.0 编译

有什么建议么?

4

2 回答 2

22

说明符的d一部分%lld是告诉printf参数应该被视为有符号整数。使用 au代替:%llu.

从手册页:

d, 我

int 参数转换为有符号十进制表示法。

o, 你, x, X

unsigned int 参数转换为 无符号 八进制 (o)、无符号 十进制 (u) 或无符号十六进制(x 和 X)表示法。

于 2012-12-10T02:16:30.560 回答
4

我认为你实际上在这里做了一些未定义的事情。我认为该表达式1l << 63 在 C 中是未定义的,因为编译器将以1l有符号类型表示,并且移位 63 位会导致有符号溢出(在 C 中未定义)。我不是专家,但似乎你想要1ull << 63

-Weverything事实上,如果你传入clang ,你的原始代码会抱怨这个:

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 格式。

于 2012-12-10T02:40:28.597 回答