未签名的长长超出范围

Unsigned Long Long out of range?

本文关键字:范围      更新时间:2023-10-16

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

  • 我正在使用unsigned long long变量(我甚至使用了long变量,效果相同)
  • 我需要能够存储 64 位整数(sizeof返回 8,这很好)

但是,当我尝试转到 1<<63 之类的值并执行一些简单的按位运算时,奇怪的是,我似乎得到了负值。这是为什么呢?

我的测试代码:

    unsigned long long c = 0;
    c |= 1l << 56; printf("c = %lldn",c);
    c |= 1l << 63; printf("c = %lldn",c);

输出:

c = 72057594037927936 
c = -9151314442816847872

旁注 :

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

有什么建议吗?

%lld说明符的d部分告诉printf参数应被视为有符号整数。请改用u%llu

从手册页:

d, i

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

o, u, x, X

无符号

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

我认为你实际上在这里做了一些未定义的事情。我认为表达式 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 = %lldn",c);
           ~~ ^  ~~

编辑:而且,是的,那么您需要从另一个答案中获得正确的printf格式。