C++:Union vs Bitwise运算符

Mar*_*aux 4 c++ performance bitwise-operators unions

我有两个char,我想把它们"按"在一起.
例如:

char c1 = 11; // 0000 1011
char c2 = 5;  // 0000 0101
short int si = stitch(c1, c2); // 0000 1011 0000 0101
Run Code Online (Sandbox Code Playgroud)

所以,我首先尝试的是按位运算符:

short int stitch(char c1, char c2)
{
    return (c1 << 8) | c2;
}
Run Code Online (Sandbox Code Playgroud)

但这不起作用:我得到了short等于c2...... (1)为什么?
(但:c1c2是我真正的应用程序负数...也许这是问题的一部分?)

所以,我的第二个解决方案是使用union:

union stUnion
{
    struct
    {
         char c1;
         char c2;
    }
    short int si;
}

short int stitch(char c1, char c2)
{
    stUnion u;
    u.c1 = c1;
    u.c2 = c2;
    return u.si;
}
Run Code Online (Sandbox Code Playgroud)

这就像我想要的...... 我想

(2)什么是最好/最快的方式?

谢谢!

Pot*_*ter 7

union方法最好是实现定义的(在实践中,它将非常可靠地工作,但格式si取决于平台的字节顺序).

正如您所怀疑的那样,按位方式的问题是负数.负数由前导1的链表示.所以-5例如是

1111 1011
Run Code Online (Sandbox Code Playgroud)

如果你把它投射到int甚至unsigned int,它就变成了

1111 1111 1111 … 1111 1011
Run Code Online (Sandbox Code Playgroud)

当应用OR时,所有那些1将淹没左移数据.

要解决这个问题,在转换之前将chars转换unsigned charint(以防止溢出,甚至出现溢出的可能性):

short int stitch(char c1, char c2)
{
    return ( (int) (unsigned char) c1 << 8) | (unsigned char) c2;
}
Run Code Online (Sandbox Code Playgroud)

或者,如果您可以自由更改参数的类型,并且可以包含<cstdint>,

uint16_t stitch( uint8_t c1, uint8_t c2)
{
    return ( (int) c1 << 8 ) | c2;
}
Run Code Online (Sandbox Code Playgroud)