[英]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_t
和uint16_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.