C++ 为什么printf和cout对此代码给出不同的输出?
十进制的C++ 为什么printf和cout对此代码给出不同的输出?,c++,bit-shift,C++,Bit Shift,十进制的4294967296等于十六进制的ffffffe,基本上是2^32。为什么printf和cout的行为不同?这种转换是如何工作的?%x格式化输出以十六进制显示值,因此您应该将std::hex传递到cout以执行相同的操作: 4294967296 -2 fffffffe std::coutprintf格式标志%x表示以十六进制打印整数值 也有一个流操纵器来实现这一点(std::hex),但您没有使用它。当您向没有操纵器的流输出整数值时,它以10为基数输出 有关printf格式标志的更多信
4294967296
等于十六进制的ffffffe
,基本上是2^32
。为什么printf和cout的行为不同?这种转换是如何工作的?%x
格式化输出以十六进制显示值,因此您应该将std::hex
传递到cout
以执行相同的操作:
4294967296
-2
fffffffe
std::coutprintf
格式标志%x
表示以十六进制打印整数值
也有一个流操纵器来实现这一点(std::hex
),但您没有使用它。当您向没有操纵器的流输出整数值时,它以10为基数输出
有关printf
格式标志的更多信息,请参阅有关流操纵器的信息
换档操作员加法表达式 操作数应为整数或枚举类型,且为整数 进行促销活动。结果的类型是 提升的左操作数。如果正确的操作数 为负数,或大于或等于 提升的左操作数
2/E1的值这将产生与您需要告诉它以十六进制打印相同的正确答案11111111 11111111 11111111 11111110
cout%x是十六进制,其中cout只是直接输出数字(int) -1是0xFFFFFFFF移位,您必须将其添加到左侧的0中 所以最后一个F(二进制中是1111)变成了1110 其他人会更清楚地回答你的问题,我想…首先 十六进制的FFFFFFE,基本上是2^32 是错误的。FFFFFFF E=4294967294,它是2^32-2(对于无符号整数)或-2(对于2的补码中的32位有符号整数)
其次,将打印一个无符号十六进制整数(即printf(“%x”,…)
),在大多数现代系统中为32位。无符号int
long a=2为了可读性,让我们使用有符号8位整数:
现在按1左移:cout << hex<<(-1<<1)<<endl; printf("%x",-1<<1);
-1 bitwise is 11111111
但是,使用转换说明符告诉%x
将printf()
作为未签名,因此它打印出11111111
第一种情况有效:fe
以pow(2,32)
的形式返回精确值232,将其转换为双精度
(我假设这就是神秘的long long
类型)。使用ll
打印此值完全有效 在cout
(-1的情况下,由于您试图将负数左移,因此此代码将调用,
5.8节的移位运算符表示(强调我的):
E1 Try相反。4294967296肯定不等于FFFFFFF E。前者是printf的值(“%d”,…)
,后者是2^32
。对于左移负数是否未定义,有不同的解释。John创建了一个a以查看我们是否可以解决它。但为什么它要打印“-2”如果是cout?它不应该打印“4294967296”吗?我在问这两个值为什么不同。我理解十六进制和十进制表示法之间的区别。@JohnDibling你只需要32位就可以显示2^32-2
-1@ZacHowland:我知道,但是OP的代码使用
作为ll
的类型声明,我猜这意味着a
@JohnDibling表示uint64\u t
,是的。他在那之后所做的一切都是处理32位的>a
s(这是他整个问题的一大部分)。@ZacHowland:我想你是对的。我当时做了32位的值。int
这里没有非负值。而且,这与我使用的标准(C++03)不匹配@JohnDibling这是E1
,据我所知,语言已从n3485
更改。对,引用说03
是非负的,然后它被定义为,否则它是未定义的,适合这种情况。编辑您的帖子,以包含已发布标准的文本,而不是草稿。有一些不同ces.那么,你是否将此解释为负数左移会导致未定义的行为?你是否有意(有效)回滚我的编辑并返回到标准草案?E1
11111111 11111111 11111111 11111110
cout << hex<<(-1<<1)<<endl; printf("%x",-1<<1);
-1 bitwise is 11111111
-1 << 1
11111110 which is -2