算术运算期间的数据类型促销:-1< (unsigned int)1 == false

时间:2010-10-10 12:58:54

标签: c unsigned integer-promotion

main()  {   
  if ( -1 < (unsigned char) 1 )
    printf("less than");
  else        
    printf("NOT less than");
} 

打印less than。因为,(unsigned char) 1 转换为 (signed char) 1,然后转换为:(signed) -1 < (signed) 1,因此输出为less than

但如果我将上述代码更改为if ( (-1 < (unsigned int) 1 )

然后输出为NOT less than

所以很明显,当我将unsigned char更改为unsigned int:

  • (signed)-1转换为unsigned int [恰好正好相反]
  • 因为-1被存储为2的恭维1;位模式被评估为255(可能)
  • 因此255&lt; 1将评估为false,否则将执行。
  • 即使您用int a = -1;代替'-1'相同的结果

问题:

    在签名和无符号算术期间
  1. 如何确定签名是否会转换为无符号,反之亦然。

  2. 为什么unsigned char和char之间的算术转换不同:显然unsigned转换为signed和unsigned int和int:显然签名转换为unsigned

  3. PS:我知道这不依赖编译器。所以不要说它是。

2 个答案:

答案 0 :(得分:10)

规则如下:

  

6.3.1.8通常的算术转换

     

...

     

否则,将对两个操作数执行整数提升。那么   以下规则适用于提升的操作数:

     
      
  1. 如果两个操作数具有相同的类型,则不需要进一步转换。
  2.   
  3. 否则,如果两个操作数都有有符号整数类型或两者都有无符号整数类型,则具有较小整数转换等级类型的操作数将转换为具有更高等级的操作数类型。
  4.   
  5. 否则,如果具有无符号整数类型的操作数的秩大于或等于另一个操作数的类型的秩,则带有符号整数类型的操作数将转换为具有无符号整数类型的操作数的类型。 / LI>   
  6. 否则,如果带有符号整数类型的操作数的类型可以表示具有无符号整数类型的操作数类型的所有值,则具有无符号整数类型的操作数将转换为带有符号整数的操作数的类型类型。
  7.   
  8. 否则,两个操作数都将转换为无符号整数类型,对应于带有符号整数类型的操作数类型。
  9.   

然后规则如下:

  • -1 < (unsigned char) 1

首先将两个操作数转换为整数(因为int可以表示unsigned char的所有值)。然后对这些签名类型进行比较。然后使用规则1。比较成功。

  • -1 < (unsigned int) 1

int不能表示unsigned int的所有值,因此使用规则3并且有符号整数将转换为无符号整数(UINT_MAX - 1)。比较现在失败了。

答案 1 :(得分:1)

这是由于整数促销。两个参数都可以表示为int,因此它们将转换为int。

ISO C 6.3.1.1,第2段:

  

如果int可以表示原始类型的所有值,则该值将转换为int;   否则,它将转换为unsigned int。这些被称为整数   促销.48)整数促销活动保持所有其他类型不变。