比较 int 与 long 和其他

Comparing int with long and others

我想知道是否有这样的事情:

int a = ...;
long b = ...;

if (a < b)
     doSomethings();

始终有效(未签名除外)

我刚刚测试了一些值,但我想确定一下。我假设 a 在比较中被转换为 long ,其他类型呢?

在这种情况下

if (a < b)

如果其中一个操作数的类型为 long,则类型 int 的对象始终转换为类型 long,因为类型 long 的等级高于类型int.

其他类型则按照C标准(6.5.8关系运算符)

3 If both of the operands have arithmetic type, the usual arithmetic conversions are performed.

这意味着在整数提升之后,一个较低等级的操作数被转换为另一个操作数的类型。

int/long 比较总是有效的。 2 个操作数被转换为通用类型,在本例中 long 并且所有 int 都可以毫无问题地转换为 long

int ii = ...;
long ll = ...;
if (ii < ll)
   doSomethings();

unsigned/long 如果 long 范围超过 unsigned,比较总是有效。如果 unsigned 范围是 [0...65535]long[-2G...2G-1],那么操作数被转换为 long 并且所有 unsigned 都可以转换为 long 没问题。

unsigned uu16 = ...;
long ll32 = ...;
if (uu16 < ll32)
   doSomethings();
long 范围不超过 unsigned 时,

unsigned/long 比较有问题。如果 unsigned 范围是 [0...4G-1]long[-2G...2G-1],那么操作数将转换为 long,这是一种不包含这两个范围的常见类型,问题随之而来.

unsigned uu32 = ...;
long ll32 = ...;

// problems
if (uu32 < ll32)  
   doSomethings();

// corrected solution
if (uu32 <= LONG_MAX && uu32 < ll32)  
   doSomethings();

// wrong solution
if (ll32 < 0 || uu32 < ll32)  
   doSomethings();

如果类型 long long 包含 unsigned 的所有范围,代码可以使用至少 long long 宽度进行比较。

unsigned uu;
long ll;
#if LONG_MAX >= UINT_MAX
  if (uu < ll)  
#if LLONG_MAX >= UINT_MAX
  if (uu < ll*1LL)  
#else 
  if (uu32 <= LONG_MAX && uu32 < ll32)  
  // if (ll < 0 || uu < ll)  
#endif