【问题标题】:Comparing an int64_t value with another uint32_t value将一个 int64_t 值与另一个 uint32_t 值进行比较
【发布时间】:2021-06-01 20:29:34
【问题描述】:
int main(){
 int64_t a = -1;
 uint32_t b = -1;

 bool c = a > b;
 std:: cout << c << std::endl;
 
 return 0;
}

我的理解是b,这是一个较小的类型将转换为较大的类型a(unit32 to int64):

Comparing int with long and others

那么a是一个有符号值将被转换为一个无符号值:

Signed/unsigned comparisons

基本上我们的比较会变成:

18446744073709551615 > 4294967295

但我的c 结果是false。我在这里错过了什么?

【问题讨论】:

  • 基本上比较会变成-1 &gt; 4294967295。
  • 但将a 视为无符号数字并不是-1。它的18446744073709551615,如果另一个值也是无符号的,不是有符号的值应该变成无符号的吗?
  • b 不是 18446744073709551615(太大了,无法放入 32 位无符号整数),而是 4294967295。
  • @Eljay a 是不是b 的值。
  • 您是否在cppinsights 中尝试过此操作,看看会发生什么?

标签: c++


【解决方案1】:

给定int64_t a 和uint32_b,在a &gt; b 中,b 将零-扩展到 64 位(请记住,它是无符号的,所以它实际上是 4294967295 而不是 @ 987654327@),然后进行比较。相关比较是-1 &gt; 4294967295为假。

the C++ standard 的相关位在“6.8.4 整数转换等级[conv.rank]”下,“有符号整数类型的等级应大于任何带符号整数类型的等级 更小的宽度。”和“任何无符号整数类型的等级应等于相应有符号整数类型的等级。”,在“7.4 常用算术转换 [expr.arith.conv]”下,“否则,如果操作数的类型带符号整数类型可以表示所有的值 无符号整数类型的操作数的类型,无符号整数类型的操作数应 被转换为带符号整数类型的操作数的类型。”和“7.6.9 关系运算符 [expr.rel]”下,“通常的算术转换(7.4)是在算术或枚举类型的操作数上执行的。”

【讨论】:

  • 但是上面的第二个链接说When comparing signed with unsigned, the compiler converts the signed value to unsigned,a 不是应该变成未签名的吗?
  • @Dan 那是指int 和unsigned int。你有一个long 和一个unsigned int。这部分答案适用于您:“否则,如果一个操作数是 long int 而另一个是 unsigned int,那么如果 long int 可以表示 unsigned int 的所有值,则 unsigned int 应转换为 long int;否则两个操作数都应转换为 unsigned long int。"
  • @AlexReynolds 表达式-1L &gt; 0U 为假。如果a 变为未签名,那不是真的吗?
  • @JosephSible-ReinstateMonica 如果sizeof(long) &gt; sizeof(unsigned),比较是false。这个区别被问题绕过了,因为它使用固定宽度的整数来代替。
  • @FrançoisAndrieux 好点;我确实在假设 AMD64 SysV ABI。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-04-20
  • 1970-01-01
  • 2013-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多