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”,…)
将打印一个无符号十六进制整数(即
无符号int
),在大多数现代系统中为32位。
long a=2为了可读性,让我们使用有符号8位整数:

cout << hex<<(-1<<1)<<endl;
printf("%x",-1<<1);
现在按1左移:

-1 bitwise is 11111111

但是,使用转换说明符
%x
告诉
printf()
11111111
作为未签名,因此它打印出
fe
第一种情况有效:
pow(2,32)
双精度
的形式返回精确值232,将其转换为
long long
(我假设这就是神秘的
ll
类型)。使用
cout
打印此值完全有效

(-1的情况下,由于您试图将负数左移,因此此代码将调用,
5.8节的移位运算符表示(强调我的):


E1 Try
printf的值(“%d”,…)
相反。4294967296肯定不等于FFFFFFF E。前者是
2^32
,后者是
2^32-2
。对于左移负数是否未定义,有不同的解释。John创建了一个a以查看我们是否可以解决它。但为什么它要打印“-2”如果是cout?它不应该打印“4294967296”吗?我在问这两个值为什么不同。我理解十六进制和十进制表示法之间的区别。@JohnDibling你只需要32位就可以显示
-1@ZacHowland:我知道,但是OP的代码使用
ll
作为
a
的类型声明,我猜这意味着
uint64\u t
@JohnDibling表示
>a
,是的。他在那之后所做的一切都是处理32位的
int
s(这是他整个问题的一大部分)。@ZacHowland:我想你是对的。我当时做了32位的值。
E1
这里没有非负值。而且,这与我使用的标准(C++03)不匹配@JohnDibling这是
n3485
,据我所知,语言已从
03
更改。对,引用说
E1
是非负的,然后它被定义为,否则它是未定义的,适合这种情况。编辑您的帖子,以包含已发布标准的文本,而不是草稿。有一些不同ces.那么,你是否将此解释为负数左移会导致未定义的行为?你是否有意(有效)回滚我的编辑并返回到标准草案?
11111111 11111111 11111111 11111110 
cout << hex<<(-1<<1)<<endl;
printf("%x",-1<<1);
-1 bitwise is 11111111
-1 << 1
11111110 which is -2