为什么在同一语句中左移和右移会产生不同的结果?
Why does left shift and right shift in the same statement yields a different result?
考虑以下示例:
第一个例子:
short x=255;
x = (x<<8)>>8;
cout<<x<<endl;
第二个案例:
short x=255;
x = x<<8;
x = x>>8;
cout<<x<<endl;
第一种情况的输出是255,而第二种情况的输出是-1。-1作为输出是有意义的,因为CPP进行了算术右移。下面是x的中间值,以获得-1作为输出。
x: 0000 0000 1111 1111
x<<8:1111 1111 0000 0000
x>>8:1111 1111 1111 1111
为什么在第一种情况下不发生相同的机制?
这种差异是两个因素造成的。
-
c++标准没有规定整型的最大值。该标准只指定了每个整数类型的最小大小。在您的平台上,
short
是16位值,int
s至少是32位值。
在您的第一个示例中,short
值自然地被提升为int
,这至少是32位,因此左移和右移在转换回short
之前对int
进行操作。
在第二个示例中,在第一次左移操作之后,结果值再次转换回short
,并且由于2的补码算法,它最终是一个负值。右移结束了负号扩展,导致最终结果为-1。
你刚才看到的是符号扩展:
符号扩展是计算机算术中的一种操作,在增加二进制数的位数的同时保持该数的符号(正/负)和值。这是通过将数字附加到数字的最高有效侧来完成的,其过程取决于所使用的特定有符号数字表示。
例如,如果用6位来表示数字"00 1010"(十进制正10)和符号扩展操作将字长增加到16位,那么新的表示就是简单的"0000 0000 0000 1010"。因此,该值和该值为正的事实都被保留。
如果用10位来表示值"11 11110001 "(十进制负15)使用二进制补码,并将这一符号扩展为16位,新的表示形式为"1111 1111 1111 0001"。因此,通过在左侧填充1,保留了负号和原始数字的值。
你一直右移到你的short变成负的点,然后当你移回来时,你得到符号扩展。
在第一种情况下不会发生这种情况,因为移位没有应用于short。它应用于255
,它不是一个短类型,而是默认的整型(可能是int
)。只有当它已经被移回后才会被强制转换:
on the stack: 0000 0000 0000 0000 0000 0000 1111 1111
<<8
on the stack: 0000 0000 0000 0000 1111 1111 0000 0000
>>8
on the stack: 0000 0000 0000 0000 0000 0000 1111 1111
convert to short: 0000 0000 1111 1111
- 三元运算符在返回语句中给出意外的结果
- 为什么语句中的链接方法无法给出预期的结果?
- 使用嵌套 if 语句的意外结果
- 单个cout中的多个语句产生不同的结果
- 如果语句计算结果为 false,即使条件为真
- python 和 c++ 的结果对于嵌套的 for 语句是不同的
- EXPECT_NO_THROW语句的 gtest 捕获结果
- C++ to_string函数根据额外打印语句的先见之明,为浮点数和整数转换提供不同的结果
- 当我使用if语句时,为什么该程序会给我不同的结果
- 如何在QtCreator中基于SqlQuery结果执行条件语句
- 嵌套循环语句结果不正确
- 实现多个返回语句 c++ 时出现奇怪的结果
- 如何在更新语句中获取输出子句的结果
- 为什么我的 if/else 语句没有产生预期的结果?
- 奇怪的条件语句(结果相同)
- 如果.还.语句不输出预期结果.而.循环问题
- 调用函数只有在函数开头有cout语句时才会给出结果
- 在语句中调用 std::set 函数时出现意外"if"评估结果
- 我们是否可以假设下列任意一对浮点算术语句总是产生相同的结果?
- 在c++中,一些宏语句可能会产生意想不到的结果