我错过了什么吗?我运行了以下内容:
$ 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: %d\n", sizeof l);
输出:
sizeof long: 8
这不意味着每个long包含64位吗? 但是当我执行以下代码行时:
printf("2^64: %ld\n", 1UL<<64);
我从gcc收到以下警告:
sizeof.c:14:29:警告:左移计数&gt; =类型宽度[-Wshift-count-overflow]
如果我将左移位减少到63,则警告消失,但输出:
2 ^ 64:-9223372036854775808
这让我相信我的无符号长度为64个可用位的假设是不正确的,但为什么呢?
答案 0 :(得分:9)
数字2 ^ 64要求65位正确表示二进制 - 位#65设置,其余为零。
这与无符号8位数字最多只能达到255(2 ^ 8 - 1)的原因相同,无符号16位数字最多只能达到65535(2 ^ 16 - 1),依此类推
答案 1 :(得分:2)
sizeof
确实会返回字节数,所以是的,它确实有64位。
使用N
二进制数字,您可以表示总共2^N
个数字。如果您的变量是无符号的,则表示[0, (2^N)-1]
范围。如果它是签名号码,则范围应为[-2^(N-1), +2^(N-1)-1]
。如果您想了解有关已签名整数的更多信息,可以阅读&#34; Two&#39;补码&#34;。
继续显示整数:告诉printf
如何解释变量。如果你告诉它有符号整数,那么它将使用最高有效位作为符号而不是值2^63
(再次检查两个补码)。
另一方面,这将打印整数unsigned:
printf("%lu", x);