无符号值赋值给int与long long类型输出结果差异问题
以下结论基于绝大多数桌面/服务器的默认编译环境:int为32位有符号整数,long long为64位有符号整数。
首先先明确-1U的取值:1U是unsigned int类型,对无符号数执行负运算时,按照C++无符号整数的运算规则,结果等于UINT_MAX(即2^32 - 1 = 4294967295),-1U本身的类型是unsigned int。
第一段代码int a = -1U; cout << a;输出-1的原因
- 32位有符号
int的可表示范围是-2^31 ~ 2^31 -1,无法覆盖unsigned int的最大值4294967295 - 将超出目标类型取值范围的无符号数赋值给有符号类型时,行为是实现定义的,几乎所有现代编译器都会直接拷贝二进制位,不做数值转换
- 4294967295的32位二进制是全1,对应32位有符号
int的补码表示就是-1,所以输出结果为-1
第二段代码long long a = -1U; cout << a;输出4294967295的原因
- 64位有符号
long long的可表示范围是-2^63 ~ 2^63 -1,完全可以覆盖unsigned int的所有取值 - 此时
unsigned int类型的4294967295可以无损转换为long long类型的正整数4294967295,不存在位截断的情况,所以输出就是对应的正数值
两类转换的核心差异:当有符号目标类型可以完整表示原无符号类型的所有取值时,执行数值等价的安全转换;如果无法覆盖原无符号类型的最大值,则执行实现定义的二进制位直接拷贝,最终结果由目标类型的编码规则决定。
内容的提问来源于stack exchange,提问作者Bitthal Maheshwari
相关产品推荐
相关产品推荐

