You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

表达式中多位移位运算符出现异常行为的原因咨询

问题

编写程序时发现位移位异常,编写测试用例排查问题,测试代码如下:

#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;
}

运行结果差异:

  • 分步执行左移1位再右移5位,结果为1(二进制00000001),符合预期;
  • 合并为一行表达式byte = (byte << 1) >> 5;执行时,结果为9(二进制00001001),与预期不符。

BYTE是Windows定义的数据类型,请求解释该异常原因。

原因解释

这个差异的核心是C++的整数提升规则在起作用:

  1. BYTE本质是unsigned char(Windows头文件中定义为typedef unsigned char BYTE;),属于窄整数类型。
  2. 分步执行逻辑:
    • 第一步byte = byte << 1;:byte作为unsigned char参与左移,8位的0b10010000左移1位后,最高位的1被丢弃,得到0b00100000(数值32),赋值回byte后仍是8位数据。
    • 第二步byte = byte >> 5;:32(0b00100000)右移5位,得到0b00000001(数值1),符合预期。
  3. 合并表达式执行逻辑:
    • 在表达式(byte << 1) >> 5中,byte会先被整数提升为int类型(因为unsigned char的取值范围完全包含在int内,C++标准会自动做提升)。
    • 左移操作在32位int上进行:0b10010000(144)提升为int后是0x00000090,左移1位得到0x00000120(二进制0000000100100000),此时最高位的1不会被丢弃,因为int有足够的位数容纳。
    • 接着对这个32位值右移5位,得到0x00000009(二进制00001001),最后赋值回byte时截断为8位,结果就是9。

简言之:分步执行时每一步都把结果截断回8位的BYTE,合并表达式时中间结果保留为32位int,导致右移时保留了原本会被截断的高位数据。

内容的提问来源于stack exchange,提问作者Alex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 17:40:40