I tried to cast an
int to a
uint16_t with the following code:
std::cout << static_cast<std::uint16_t>(65537) << std::endl;
The output was
1. As far as I’ve got it, only the high-order bits got cast to the destination type. I’m not sure if this is implementation-defined (I used clang).
I wonder, is there an option to specify which bytes I want to get to the destination type when performing a narrowing conversion? Are there some casts to consider low-order bytes first?
Conversion to an unsigned type is done by reduction modulo 2N-1, where N is the number of bits in the destination type. This equates to keeping the N least significant bits of a 2’s complement representation of the number in question.
If you want to keep some more significant bits instead, you’ll want to do a right shift on the value before converting to the destination type.
uint32_t input = 0x12345678; uint16_t lower = static_cast<uint16_t>(input); // lower = 0x5678; uint16_t upper = static_cast<uint16_t>(input >> 16); // upper = 0x1234
Be aware, however, that if you might have a negative value, you probably want to convert to an unsigned type of the same size first, then do the right shift on that result. Results of right shifting a negative number can vary.