右移 unsigned char 是用 ones 填充的吗?
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 ....什么?怎么左边突然全是1了?
如何生成启用第 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
及更高版本。
由于整数提升,当几乎对值执行任何操作时,unsigned char
被提升为 int
。
当您右移时,左操作数会进行整数提升,unsigned char
将变为 int
。表达式的值将是提升后左操作数的值 - 因此 ((unsigned char) -1 >> 1)
的结果值为 127,类型为 int
。如果你 ~
(int)127
你会得到一个设置了符号位的 int
;向右移动将具有实现定义的行为。
解决方法是在around外加一个cast ~
:
(unsigned char)~((unsigned char) -1 >> 1) >> 2
或者,&
0xFF
的值:
(~((unsigned char) -1 >> 1) >> 2) & 0xFF
关于设置[=12=左起第n
位,最好的解决办法是*左移1U
到位置,如.
设置第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
在我的系统上,(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 ....什么?怎么左边突然全是1了?
如何生成启用第 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
及更高版本。
由于整数提升,当几乎对值执行任何操作时,unsigned char
被提升为 int
。
当您右移时,左操作数会进行整数提升,unsigned char
将变为 int
。表达式的值将是提升后左操作数的值 - 因此 ((unsigned char) -1 >> 1)
的结果值为 127,类型为 int
。如果你 ~
(int)127
你会得到一个设置了符号位的 int
;向右移动将具有实现定义的行为。
解决方法是在around外加一个cast ~
:
(unsigned char)~((unsigned char) -1 >> 1) >> 2
或者,&
0xFF
的值:
(~((unsigned char) -1 >> 1) >> 2) & 0xFF
关于设置[=12=左起第n
位,最好的解决办法是*左移1U
到位置,如
设置第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