为什么未签名的字符<<未签名的字符不是未签名的字符 [英] Why result of unsigned char << unsigned char is not unsigned char

查看:104
本文介绍了为什么未签名的字符<<未签名的字符不是未签名的字符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从左移获得结果,但找不到解释.

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 1110int(?).

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";

这篇关于为什么未签名的字符&lt;&lt;未签名的字符不是未签名的字符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆