请参阅下面的简单代码:
#include <iostream>
#include <stdlib.h>
using namespace std;
int main(void)
{
unsigned long currentTrafficTypeValueDec;
long input;
input=63;
currentTrafficTypeValueDec = (unsigned long) 1LL << input;
cout << currentTrafficTypeValueDec << endl;
printf("%u \n", currentTrafficTypeValueDec);
printf("%ld \n", currentTrafficTypeValueDec);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
为什么printf()显示带负值的currentTrafficTypeValueDec(unsigned long)?
输出是:
9223372036854775808
0
-9223372036854775808
Run Code Online (Sandbox Code Playgroud)
Mik*_*one 17
%d
是一个签名格式化程序.将currentTrafficTypeValueDec
(2到63次幂)的位重新解释为a signed long
给出负值.所以printf()
打印一个负数.
也许你想用%lu
?
有趣的点...
cout
将数字打印为无符号长整型,所有 64 位都是有效的,并打印为无符号二进制整数(我认为这里的格式是%lu
)。
printf(%u ...
将输入视为正常的无符号整数(32 位?)。这会导致第 33 位到第 64 位下降 - 留下零。
printf(%ld ...
将输入视为 64 位有符号数,然后将其打印出来。
您可能会对最后一个感到困惑的printf
是,它给出的绝对值与 相同cout
,但带有一个减号。当查看为无符号整数时,所有 64 位在生成整数值时都很重要。但是对于有符号数,第 64 位是符号位。当设置符号位时(如您的示例中所示),它表示剩余的 63 位将被视为以2 的补码表示的负数. 正数只需将其二进制值转换为十进制即可打印出来。但是,对于负数,会发生以下情况:打印负号,将 1 到 63 位与二进制“1”位进行异或,将结果加 1 并打印无符号值。通过删除符号位(第 64 位),您最终得到 63 个“0”位,与“1”位进行异或得到 63 个“1”位,加上 +1,整个过程翻转为您提供一个具有位的无符号整数64 设置为“1”,其余设置为“0” - 这与您使用cout
BUT得到的相同,作为负数。
一旦你弄清楚为什么上述解释是正确的,你也应该能够理解这一点