Visual Studio C++中UINT16与UINT32无符号数比较结果差异问询
问题原因解答
该现象的核心原因是C/C++标准规定的**整型提升(Integral Promotion)**规则,和处理器原生字长没有直接关系。
核心规则说明
C/C++中对秩低于int的整型类型做算术运算时,会先将操作数提升为int类型再计算,规则如下:
- 如果
int的取值范围可以完全覆盖原类型的所有值,原无符号类型的操作数会被提升为有符号int - 如果
int的取值范围无法覆盖原类型的所有值,操作数会被提升为unsigned int - 秩大于等于
int的类型做运算时,不会发生跨符号类型的提升
不同类型的行为解释
1. UINT8/UINT16场景
常规32位/64位环境下int是32位,可以完全覆盖UINT8(0255)、UINT16(065535)的所有取值,所以运算时会发生如下转换:
- 运算
a - b前,UINT8/UINT16类型的a、b先被转换为有符号int - 有符号
int运算5 - 10得到-5,比较-5 > 0结果为false,和你观察到的现象一致 - 赋值给UINT8/UINT16类型的
c时,会做无符号截断,-5转换为对应无符号类型的最大值减4,是大于0的正数,所以第二个比较结果仍为true
2. UINT32/UINT64场景
UINT32的秩和int相等,UINT64的秩高于int,不会发生向有符号int的提升:
- 运算
a - b直接按无符号规则计算,5-10得到对应无符号类型的极大值,显然大于0,所以两次比较结果都是true
避坑建议
验证无符号数a是否大于等于b时,不要用a - b >= 0的写法,直接写a >= b即可完全规避整型提升带来的异常行为。
内容的提问来源于stack exchange,提问作者MaryK
相关产品推荐
相关产品推荐

