Cleanest way to combine two shorts to an int

后端 未结 7 1266
野的像风
野的像风 2020-12-17 23:31

I have two 16-bit shorts (s1 and s2), and I\'m trying to combine them into a single 32-bit integer (i1). According to the spec I\'m dealing with, s1 is the most significant

相关标签:
7条回答
  • 2020-12-18 00:09

    I know this is an old post but the quality of the present posted answers is depressing...

    These are the issues to consider:

    • Implicit integer promotion of shorts (or other small integer types) will result in an operand of type int which is signed. This will happen regardless of the signedness of the small integer type. Integer promotion happens in the shift operations and in the bitwise OR.
    • In case of the shift operators, the resulting type is that of the promoted left operand. In case of bitwise OR, the resulting type is obtained from "the usual arithmetic conversions".
    • Left-shifting a negative number results in undefined behavior. Right-shifting a negative number results in implementation-defined behavior (logical vs arithmetic shift). Therefore signed numbers should not be used together with bit shifts in 99% of all use-cases.
    • Unions, arrays and similar are poor solutions since they make the code endianess-dependent. In addition, type punning through unions is also not well-defined behavior in C++ (unlike C). Pointer-based solutions are bad since they will end up violating "the strict aliasing rule".

    A proper solution will therefore:

    • Use operands with types that are guaranteed to be unsigned and will not be implicitly promoted.
    • Use bit-shifts, since these are endianess-independent.
    • Not use some non-portable hogwash solution with unions or pointers. There is absolutely nothing gained from such solutions except non-portability. Such solutions are however likely to invoke one or several cases of undefined behavior.

    It will look like this:

    int32_t  i32 = (int32_t)( (uint32_t)s1<<16 | (uint32_t)s2 );
    

    Any other solution is highly questionable and at best non-portable.

    0 讨论(0)
提交回复
热议问题