Bohan Gao
Bohan Gao

Reputation: 382

-1 < 4 return NO? It's so strange

int counter=-1;
NSArray *pointArray=[[NSArray alloc]initWithObjects:@"1",@"2",@"3",@"1",@"2", nil];
NSString *result=[NSString stringWithFormat:@"%d",counter<pointArray.count-1];

Believe it or not the result is 0 !!! Try and who can tell me why???

Upvotes: 2

Views: 77

Answers (2)

Nate Chandler
Nate Chandler

Reputation: 4553

Notice that the following code reproduces this issue:

#include <Foundation/Foundation.h>
int main(int argc, char *argv[]) {
    NSUInteger uns = 4;
    int sig = -1;
    BOOL cmp = (sig < uns);
    NSLog(@"(%d<%zu)=%d", sig, uns, cmp);
}

The output of this is

 (-1<4)=0

As has been pointed out, the trouble is that you are comparing an int to an NSUInteger. But recall that, on 64-bit systems, NSUInteger is a typedef of unsigned long.

The behavior we're seeing is a result of usual arithmetic conversion:

  1. If either operand is of type long double, the other operand is converted to type long double.
  2. If the above condition is not met and either operand is of type double, the other operand is converted to type double.
  3. If the above two conditions are not met and either operand is of type float, the other operand is converted to type float.
  4. If the above three conditions are not met (none of the operands are of floating types), then integral conversions are performed on the operands as follows:
    • If either operand is of type unsigned long, the other operand is converted to type unsigned long.
    • If the above condition is not met and either operand is of type long and the other of type unsigned int, both operands are converted to type unsigned long.
    • If the above two conditions are not met, and either operand is of type long, the other operand is converted to type long.
    • If the above three conditions are not met, and either operand is of type unsigned int, the other operand is converted to type unsigned int.
    • If none of the above conditions are met, both operands are converted to type int.

Since neither of the operands are of floating point type, we arrive at 4.. Since the second operand (pointArray.count-1) is of type NSUInteger, that is of type unsigned long, the other operand (counter) is converted to type unsigned long, taking on the value of 18446744073709551615 which is indeed greater than 4.

Upvotes: 0

Extra Savoir-Faire
Extra Savoir-Faire

Reputation: 6036

You're comparing a signed number (-1) to an unsigned number (pointArray.count - 1).

Upvotes: 3

Related Questions