繁体   English   中英

右移 unsigned char 填充了一个?

[英]right-shifting unsigned char is filling with ones?

在我的系统上, (unsigned char) -1是(预计为 8 位的字符)二进制 1111 1111(十进制 255)。

类似地, (unsigned char) -1 >> 1是预期的 0111 1111。左边用零填充。

~((unsigned char) -1 >> 1)是 1000 0000 正如预期的那样。

现在我想生成 unsigned char 0010 0000 例如。

我试过~((unsigned char) -1 >> 1) >> 2 ,但这输出 1110 0000.... 什么? 为什么左边突然被填满了?


如何生成启用第 n 位(从左侧)的unsigned char

我想

n   unsigned char
0   1000 0000
1   0100 0000
2   0010 0000
3   0001 0000
... 
7   0000 0001

目前, ~((unsigned char) -1 >> 1) >> n给了我

n   unsigned char
0   1000 0000
1   1100 0000
2   1110 0000
3   1111 0000
... 
7   1111 1111

uint8_tuint16_t存在此问题,但在uint32_t及更高版本不再发生。

由于 integer 促销,当对值执行几乎任何操作时, unsigned char都会提升为int

当您向右移动时,左操作数会经历 integer 提升,并且unsigned char将变为int 表达式的值将是提升后左操作数的值 - 因此((unsigned char) -1 >> 1)的结果值为 127,类型为int 如果你~ (int)127你会得到一个带符号位的int 转移该权利将具有实现定义的行为。

解决方案是在外部~周围添加一个演员表:

(unsigned char)~((unsigned char) -1 >> 1) >> 2

或者, &带有0xFF的值:

(~((unsigned char) -1 >> 1) >> 2) & 0xFF

至于设置unsigned char左侧的第n位,最好的解决方案是 *left-shift 1U到 position,如Allan Wind所示。

另一种设置第 n 位的方法(从左至右):

1 << (CHAR_BIT - n - 1)

您可以利用std::numeric_limits<T>::digits来创建更少混淆和灵活的代码:

    unsigned char data=0;
    
    const uint8_t sizeBit=std::numeric_limits<decltype(data)>::digits;
    for(uint8_t n=0;n<sizeBit;n++) {
        data = 1 << (sizeBit - (n+1));
        std::bitset<sizeBit> x(data);
        std::cout << x << '\n';
    }

印刷:

10000000
01000000
00100000
00010000
00001000
00000100
00000010
00000001

暂无
暂无

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

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