【问题标题】:Comparison between unsigned int and int without using cast operator不使用强制转换运算符的 unsigned int 和 int 之间的比较
【发布时间】:2015-08-19 03:06:57
【问题描述】:

我环顾四周的每个人都存在一个关于我的问题的话题,但我找不到。

unsigned int x = 5; 
int y = -3;
if(y<x)
   func1();
else
   func2();

func2 被调用。但我想打电话给func1

我知道在比较这些值时必须使用强制转换运算符。
但不允许使用强制转换运算符或更改变量的类型。

我该如何解决这个问题?

【问题讨论】:

  • 如果启用了转换警告,编译器应始终在此类比较中生成一个,而无需显式强制转换。即使您在比较之前检查 (y 完全 禁止类型转换但不强制执行签名警告(和大多数/所有其他警告)太过分了。

标签: c int compare type-conversion unsigned-integer


【解决方案1】:

首先检查y 是否为负值,然后知道,你知道x 总是更大,因为它是无符号的。

如果y 不是负数,则直接将其值与x 进行比较。我认为这不会引起问题,因为没有负号。

请看下面的例子:

if(y<0)
{
    //x>y
    func1();
}
else if (y<x)
{
    //lets say y=3, and x=5
    func1();
}
else
{
    func2();
}

【讨论】:

    【解决方案2】:

    if 语句中的条件可以这样写

    if( y < 0 || y<x)
       func1();
    else
       func2();
    

    【讨论】:

    • 这仍然会为比较生成警告。可悲的是,编码风格完全不允许强制转换,但不强制执行警告。演员有时 do 有时是有意义的。这个例子其实就是一个完美的证明。
    【解决方案3】:

    使用更广​​泛的整数数学进行比较。未使用强制转换,变量类型未更改。
    优化的编译器不会进行乘法运算,只会进行整数扩展。
    可以改用* 1LL+ 0LL

    int main(void) {
      long long ll = 1;
      unsigned int x = 5;
      int y = -3;
      // if (y < x)
      if (ll * y < ll * x)
        puts("func1();");
      else
        puts("func2();");
      return 0;
    }
    
    Output: func1();
    

    long long 通常比int 宽:见How to determine integer types that are twice the width as `int` and `unsigned`?

    【讨论】:

      【解决方案4】:

      尝试补充y (~y),它变成2

      unsigned int x = 5; 
      int y = -3;
      if(~y<x)
         func1();
      else
         func2();
      

      【讨论】:

      • 谢谢,通过使用这个符号 ~y ,我们是否会取变量 y 的第一个补码?
      • @user3151801 这是一个错误的条件。考虑 y 等于 -3 且 x 等于 2 的情况。
      • 那么您可以将 INT_MAX 添加到它们并进行比较。 #include
      • 这是实现定义的行为,因为它依赖于 2 的补码表示。它甚至不适用于y == INT_MIN 另外,如果x &gt;= -(llong long)(INT_MIN)(假定long long 的位数比int 多)怎么办?
      猜你喜欢
      • 2013-06-15
      • 2011-05-19
      • 1970-01-01
      • 2020-11-10
      • 2011-07-02
      • 1970-01-01
      • 2012-06-06
      • 2014-08-03
      • 2018-05-06
      相关资源
      最近更新 更多