2012-01-03 67 views
7

我得到的结果是左移,我找不到解释。为什么无符号字符的结果<< unsigned char不是无符号字符

unsigned char value = 0xff; // 1111 1111 
unsigned char = 0x01; // 0000 0001 

std::cout << "SIZEOF value " << sizeof(value) << "\n"; // prints 1 as expected 
std::cout << "SIZEOF shift " << sizeof(shift) << "\n"; // prints 1 as expected 

std::cout << "result " << (value << shift) << "\n"; // prints 510 ??? 

std::cout << "SIZEOF result " << sizeof(value << shift) << "\n"; // prints 4 ??? 

我期待的结果是1111 1110而是我得到int(?)与1 1111 1110价值。

无符号字符的位如何向左移动以使位被截断并且结果为1111 1110?

我想要做的是读取一系列的字节,并将它们解释为不同长度的整数(1-32位)。

F0  F5 
1111 0000 1111 0101 

可能是

0F (first 4 bits) 
0F (next 8 bits) 
05 (last 4 bits) 

有这事做的事实,算术不与类型比INT小呢?

+0

11111111 << 1实际上是111111110,你打印表达式的结果,试着做:'value = value << shift;'然后'cout << value;' – Yaniro 2012-01-03 14:18:28

回答

9

引用了2011年标准的一些草案:

5.8移运营商[expr.shift]

...

操作数应该是完整的或无范围的枚举类型,并且执行积分促销。 结果的类型是升级的左操作数的类型。

4.5积分促销[conv.prom]

比BOOL,char16_t,char32_t,或wchar_t的其整转换 秩(4.13)以外的整数类型的prvalue是如果int可以表示源类型的所有值,则小于int的等级可以被转换为int类型的prvalue;否则,源prvalue可以被转换成类型的无符号 INT

一个prvalue ...

所以,value被提升为int,和value << shift类型是促进左操作数的类型,即int

你可以达到你想要的结果通过以下方式之一:

std::cout << "result " << ((unsigned char)(value << shift)) << "\n"; 
std::cout << "result " << ((value << shift)&0xff) << "\n"; 
2

只需将它转换回unsigned char类型:

std::cout << "result " << static_cast<unsigned char>(value << shift) << "\n"; 

或者,使用按位与:

std::cout << "result " << ((value << shift) & 0xFF) << "\n"; 
2

你可以掩盖位你感兴趣的:

(value << shift) & 0xff 

你们看到的是整型提升的结果,并且是该语言的一部分。想象一下,你正在从2个8位数组成一个16位整数 - 你不想手动提升到一个更高宽度的整数来获得高位和低位到正确的位置,对吗?

相关问题