c语言 - 为什么我不能在 64 位机器上将 2^64 存储在无符号长整型中?



我错过了什么吗?我已经运行了以下内容:

$ uname -a
Linux archlinux 4.16.6-1-ARCH #1 SMP PREEMPT Mon Apr 30 12:30:03 UTC 2018 x86_64 GNU/Linux

然后在 C 程序中:

long l;
printf("sizeof long: %dn", sizeof l);

其中输出:

sizeof long: 8

这不意味着每个长包含 64 位吗? 但是当我执行以下代码行时:

printf("2^64: %ldn",  1UL<<64);

我从 gcc 收到以下警告:

sizeof.c:14:29: 警告:左移计数>= 类型 [-Wshift-count-overflow] 的宽度

如果我将左位移减少到 63,则警告会消失,但它会输出:

2^64: -9223372036854775808

这让我相信我假设无符号长有 64 个可用位是不正确的,但为什么呢?

数字 2^64 需要 65 位才能在二进制中正确表示 - 位 #65 被设置,其余为零。

这与无符号 8 位数字最多只能达到 255 (2^8 - 1),无符号 16 位数字最多只能达到 65535 (2^16 - 1) 的原因相同,依此类推。

sizeof确实会返回字节数,所以是的,它确实有64位。 使用N个二进制数字,您可以表示总共2^N个数字。如果您的变量是无符号的,这意味着[0, (2^N)-1]范围。如果它是一个有符号的数字,那么范围将是[-2^(N-1), +2^(N-1)-1].如果你想了解更多关于有符号整数的信息,你可以阅读"二的补码"。

继续显示整数:你告诉printf如何解释变量。如果你告诉它是一个有符号整数,那么它将使用最高有效位作为符号而不是值2^63(再次,查看 Two 的补码)。

另一方面,这将打印无符号整数:

printf("%lu", x);

最新更新