为什么未签名的字符<<未签名的字符不是未签名的字符 [英] Why result of unsigned char << unsigned char is not unsigned char
问题描述
我从左移获得结果,但找不到解释.
I'm getting results from left shift to which I could not find an explanation.
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
,但是我却得到值为1 1111 1110
的int
(?).
I was expecting result to be 1111 1110
but instead I get int
(?) with value of 1 1111 1110
.
如何将无符号字符的位向左移动,以使位被截断,结果为1111 1110?
How can the bits of an unsigned char be shifted to the left so that bits are truncated and the result is 1111 1110?
我想做的是读取一系列字节并将它们解释为长度可变(1-32位)的整数.
What I'm trying to do is to read series of bytes and interpret them as integers of varying lengths (1-32 bits).
F0 F5
1111 0000 1111 0101
可能是
0F (first 4 bits)
0F (next 8 bits)
05 (last 4 bits)
这与小于int的类型不执行算术有关吗?
Has this something to do with the fact that arithmetic is not done with types smaller than int?
推荐答案
引用了一些2011年标准草案:
Quoting some draft of the 2011 standard:
5.8移位运算符[expr.shift]
5.8 Shift operators [expr.shift]
...
操作数应为整数或无范围枚举类型,并执行整数提升. 结果的类型是提升后的左操作数的类型.
The operands shall be of integral or unscoped enumeration type and integral promotions are performed. The type of the result is that of the promoted left operand.
和
4.5整体促销[conv.prom]
4.5 Integral Promotions [conv.prom]
除bool,char16_t,char32_t或wchar_t以外的整数类型的prvalue,其整数转换 如果int可以表示全部,则rank(4.13)小于int的rank可以将其转换为int类型的prvalue 源类型的值;否则,可以将源prvalue转换为unsigned类型的prvalue 诠释
A prvalue of an integer type other than bool, char16_t, char32_t, or wchar_t whose integer conversion rank (4.13) is less than the rank of int can be converted to a prvalue of type int if int can represent all the values of the source type; otherwise, the source prvalue can be converted to a prvalue of type unsigned int
...
因此,value
被提升为int
,而value << shift
的类型是提升后的左操作数的类型,即int
.
So, value
is promoted to int
, and the type of value << shift
is the type of the promoted left operand, i.e. int
.
您可以通过以下其中一种方法来获得所需的结果:
You can achieve your desired result one of these ways:
std::cout << "result " << ((unsigned char)(value << shift)) << "\n";
std::cout << "result " << ((value << shift)&0xff) << "\n";
这篇关于为什么未签名的字符<<未签名的字符不是未签名的字符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!