简体   繁体   English

表达式中多个位移位运算符的意外行为

[英]Unexpected behaviour from multiple bitwise shift operators in an expression

I noticed that a program that I was writing was not working correctly so I wrote a simple test to check if the problem was the binary shifting.我注意到我正在编写的程序运行不正常,所以我编写了一个简单的测试来检查问题是否是二进制移位。 The code is the following:代码如下:

#include <iostream>
#include <Windows.h>
#include <bitset>

using namespace std;
int main(){
    BYTE byte = 0b10010000; //This is 2^7 + 2^4 = 144
    cout << "This is the binary number 10010000: " << endl << "Numerical value: " << (unsigned short int) byte << endl << "Binary string: " << bitset<8>(byte) << endl;

    byte = byte << 1;
    cout << "Shifted left by 1 with << 1:" << endl << "Numerical value: " << (unsigned short int) byte << endl << "Binary string: " << bitset<8>(byte) << endl;

    byte = byte >> 5;
    cout << "Shifted right by 5 with >> 5: " << endl << "Numerical value: " << (unsigned short int) byte << endl << "Binary string: " << bitset<8>(byte) << endl;

    byte = 0b10010000;
    byte = (byte << 1) >> 5; //Expect to store 00000001 inside byte
    cout << "But what happens if I do it all in one line? " << endl << "Numerical value: " << (unsigned short int) byte << endl << "Binary string: " << bitset<8>(byte) << endl;
    return 0;
}

Output produced Output出品

By running it, the following output is produced:通过运行它,会产生以下 output:

This is the binary number 10010000:这是二进制数 10010000:
Numerical value: 144数值:144
Binary string: 10010000二进制字符串:10010000
Shifted left by 1 with << 1: << 1 左移 1:
Numerical value: 32数值:32
Binary string: 00100000二进制字符串:00100000
Shifted right by 5 with >> 5:用 >> 5 右移 5:
Numerical value: 1数值:1
Binary string: 00000001二进制字符串:00000001
But what happens if I do it all in one line?但是,如果我在一行中完成所有操作会发生什么?
Numerical value: 9数值:9
Binary string: 00001001二进制字符串:00001001

What I was expecting我所期待的

I expected the last messages printed by cout would be:我预计cout打印的最后一条消息是:

But what happens if I do it all in one line?但是,如果我在一行中完成所有操作会发生什么?
Numerical value: 1数值:1
Binary string: 00000001二进制字符串:00000001

But surprisingly enough, this wasn't the case.但令人惊讶的是,事实并非如此。
Can someone explain to me why does this happen?有人可以向我解释为什么会这样吗? I tried checking microsoft documentation but found nothing.我尝试检查 microsoft 文档,但一无所获。

Additional info : The type BYTE is defined here: https://docs.microsoft.com/en-us/windows/win32/winprog/windows-data-types附加信息:BYTE 类型在这里定义: https://docs.microsoft.com/en-us/windows/win32/winprog/windows-data-types

You are experiencing the effects of integer promotion.您正在体验 integer 促销的效果。

The operation byte << 1 does not produce an unsigned char , despite byte being of that type.操作byte << 1不会产生unsigned char ,尽管byte属于该类型。 The rationale is that hardware usually cannot perform a number of operations on small types (below a machine word) so C++ inherited from C the concept of promoting data types in operations to larger types.基本原理是硬件通常无法对小型类型(机器字以下)执行许多操作,因此 C++ 继承自 C 将操作中的数据类型提升为较大类型的概念。

So since the result is not 8 bits but, probably, 32 bits, the most significant bit is not shifted out but preserved.因此,由于结果不是 8 位,而是可能是 32 位,因此最高有效位不会移出而是保留。 After you shift the 32 bit value back and implicitly convert it back to an unsigned char the bit is back in your output.在将 32 位值移回并隐式将其转换回unsigned char后,该位又回到了 output 中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM