Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comparing int with long and others

I am wondering if things like this :

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

if (a < b)
     doSomethings();

always works (excepted for unsigned)

I just tested with a few values, but I want to be sure. I assume a is cast to long in the comparison, what about others type ?

like image 558
Spooky Avatar asked Dec 14 '22 09:12

Spooky


2 Answers

int/long compare always works. The 2 operands are converted to a common type, in this case long and all int can be converted to long with no problems.

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

unsigned/long compare always works if long ranges exceeds unsigned. If unsigned range was [0...65535] and long was [-2G...2G-1], then the operands are converted to long and all unsigned can be converted to long with no problems.

unsigned uu16 = ...;
long ll32 = ...;
if (uu16 < ll32)
   doSomethings();

unsigned/long compare has trouble when long ranges does not exceed unsigned. If unsigned range was [0...4G-1] and long was [-2G...2G-1], then the operands are converted to long, a common type that does not encompass both ranges and problems ensue.

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();

If type long long includes all the range of unsigned, code could use do the compare with at least long long width.

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
like image 185
chux - Reinstate Monica Avatar answered Dec 28 '22 22:12

chux - Reinstate Monica


In this condition

if (a < b)

an object of type int is always converted to the type long provided that one of the operands has type long because type long has higher rank than type int.

As for other types then according to the C Standard (6.5.8 Relational operators)

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

It means that after the integer promotion an operand with a lower rank is converted to the type of the other operand.

like image 41
Vlad from Moscow Avatar answered Dec 28 '22 23:12

Vlad from Moscow