C++窄化转换时,能否指定获取目标类型的指定字节?
关于无符号整数窄化转换的问题解答
首先,你看到的static_cast<std::uint16_t>(65537)输出1的结果,不是实现定义行为,而是C++标准明确规定的行为:当把一个整数类型转换为无符号整数类型时,如果源值超出目标类型的取值范围,结果等于源值对2^N取模(其中N是目标类型的位数)。
uint16_t是16位无符号类型,取值范围是0~65535,65537对2^16(即65536)取模的结果就是1,所以输出1是符合标准的——本质上是保留了源值的低16位二进制位,而不是你理解的“高阶位被转换”。
如何指定获取目标类型的特定字节?
static_cast本身无法指定取哪部分字节,如果你需要手动控制保留高阶或低阶字节,得通过位运算实现:
- 保留低阶字节(和static_cast效果一致):可以用位与操作明确截取低16位,结果和static_cast相同:
std::cout << static_cast<std::uint16_t>(65537 & 0xFFFF) << std::endl; // 输出1 - 保留高阶字节:如果源整数是32位(比如int通常是32位),可以先右移16位再转换,得到原数的高16位:
假设你有一个更大的数,比如std::cout << static_cast<std::uint16_t>(65537 >> 16) << std::endl; // 输出1,因为65537的高16位是10x12345678,要取高16位的话:std::cout << static_cast<std::uint16_t>(0x12345678 >> 16) << std::endl; // 输出0x1234对应的十进制4660
补充说明
如果是有符号整数转有符号整数的窄化转换(比如int转int8_t),当源值超出目标范围时,结果才是实现定义的;但无符号类型的窄化转换规则是标准统一的,所有编译器都会遵循。
内容的提问来源于stack exchange,提问作者Kaiyakha
相关产品推荐
相关产品推荐

