简体   繁体   English

右移 unsigned char 填充了一个?

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

On my system, (unsigned char) -1 is (expectedly for chars of 8 bits) 1111 1111 in binary (255 decimal).在我的系统上, (unsigned char) -1是(预计为 8 位的字符)二进制 1111 1111(十进制 255)。

Similarly, (unsigned char) -1 >> 1 is as expected 0111 1111. The left was filled with a zero.类似地, (unsigned char) -1 >> 1是预期的 0111 1111。左边用零填充。

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

Now I want to generate the unsigned char 0010 0000 for example.现在我想生成 unsigned char 0010 0000 例如。

I tried ~((unsigned char) -1 >> 1) >> 2 , but this outputs 1110 0000.... what the?我试过~((unsigned char) -1 >> 1) >> 2 ,但这输出 1110 0000.... 什么? Why is the left being filled with ones all of a sudden?为什么左边突然被填满了?


How can I generate an unsigned char with the nth bit (from the left) enabled?如何生成启用第 n 位(从左侧)的unsigned char

I would like我想

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

At the moment, ~((unsigned char) -1 >> 1) >> n is giving me目前, ~((unsigned char) -1 >> 1) >> n给了我

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

This problem exists for uint8_t , uint16_t , but no longer happens at uint32_t and greater. uint8_tuint16_t存在此问题,但在uint32_t及更高版本不再发生。

Due to integer promotions, unsigned char is promoted to int when pretty much any operation is performed on the value.由于 integer 促销,当对值执行几乎任何操作时, unsigned char都会提升为int

When you shift right the left operand undergoes integer promotions, and unsigned char would become int .当您向右移动时,左操作数会经历 integer 提升,并且unsigned char将变为int The value of the expression will be that of the left operand after promotions - therefore the result of ((unsigned char) -1 >> 1) has value 127, of type int .表达式的值将是提升后左操作数的值 - 因此((unsigned char) -1 >> 1)的结果值为 127,类型为int If you ~ (int)127 you'll get an int with sign-bit set;如果你~ (int)127你会得到一个带符号位的int shifting that right will have implementation-defined behaviour.转移该权利将具有实现定义的行为。

The solution is to add a cast around the outer ~ :解决方案是在外部~周围添加一个演员表:

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

Or alternatively, & the value with 0xFF :或者, &带有0xFF的值:

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

As for setting the n th bit from left of unsigned char , the best solution is to *left-shift 1U to the position, as shown by Allan Wind .至于设置unsigned char左侧的第n位,最好的解决方案是 *left-shift 1U到 position,如Allan Wind所示。

Another way to set the nth bit (from the left):另一种设置第 n 位的方法(从左至右):

1 << (CHAR_BIT - n - 1)

You might take advantage of std::numeric_limits<T>::digits to create a less obfuscated and flexible code:您可以利用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';
    }

Prints:印刷:

10000000
01000000
00100000
00010000
00001000
00000100
00000010
00000001

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

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