2011-07-07 11 views
51

Soy un principiante en Obj-C y estoy un poco confundido en este escenario Tengo el siguiente código:NSNumbers Comparando en Objective C

if (number1 < number2) { 

      NSLog(@"THE FOLLOWING NUMBER "); 
      NSLog(@"%@", number1); 
      NSLog(@"IS LESS THAN"); 
      NSLog(@"%@", number2); 

} 

Cuando ejecuto el código veo realmente extraños resultados como este :

2011-07-06 20:38:18.044 helloworld[1014:207] THE FOLLOWING NUMBER 
2011-07-06 20:38:18.047 helloworld[1014:207] 190.8776 
2011-07-06 20:38:18.050 helloworld[1014:207] IS LESS THAN 
2011-07-06 20:38:18.053 helloworld[1014:207] 96.75866 

Ambos números son objetos NSNumber, ¿cómo podría ocurrir algo como esto? Obtengo los dos números al encontrar las distancias entre los sprites en la pantalla.

Alguna pista o consejos realmente sería apreciada

+1

Así como una nota, puede combinar esos '' NSLog's utilizando NSLog (@ "EL NÚMERO% @ ES MENOR QUE% @", number1, number2); ' –

Respuesta

94

Asumo nº1 y nº2 son punteros a objetos. El signo < está comparando los punteros.

Es necesario comparar la floatValue real o doubleValue

if ([number1 doubleValue] < [number2 doubleValue]) 

....

+0

Excelente gracias tanto Kal –

+34

Como alternativa, puede hacer' if ([number1 compare: number2] == NSOrderedAscending) '. –

+3

Para decirte la verdad, he votado negativamente porque: a) La comparación de 'float's es intrínsecamente inconsistente y verazmente inválida (en todo caso, compara el valor' float' de 'number1' menos el valor' float' de 'number2' para algunos pequeños épsilon), b) 'flotar' son malvados y poco confiables; 'double's son el camino a seguir, si acaso, yc) no te molestes en comparar números de esta forma si son enteros. El comentario de Adam Rosenfield es la mejor manera de hacerlo; confíe en el método de comparación 'NSNumber' para encargarse de ello. –

15

NSNumber tiene un método para la comparación: - (NSComparisonResult) comparar: (NSNumber *) unNumero

if([numberOne compare:numberTwo] == NSOrderedSame) 
{ 
     // proceed 
} 
+3

Esta es la manera más precisa y confiable de hacerlo, ya que no corre el riesgo de perder precisión. –

33

Para los casos en los que simplemente desea probar si dos propiedades NSNumber contienen el mismo va Lue, a continuación, a partir de la documentación de Apple, parece que el uso de

- (BOOL)isEqualToNumber:(NSNumber *)aNumber 

es la forma más directa y eficaz para comparar dos valores NSNumber.

Por ejemplo:

if ([someNumber isEqualToNumber:someOtherNumber]) 
{ 
    // The numbers hold the same value 
} 
else 
{ 
    // The numbers hold different values 
} 

La documentación también dice "Este método es más eficiente que comparar: si conoce los dos objetos son números".

Siempre que necesite saber si un valor es menor o mayor, que ofrecen el método

- (NSComparisonResult)compare:(NSNumber *)aNumber 

, pero personalmente preferiría en ese momento para simplemente sacar los valores enteros (o valores dobles) y utilizar operadores regulares < y> para hacer la comparación, porque eso hace que el código mucho más fácil de leer, así:

if (firstNumber.intValue > secondNumber.intValue) 
{ 
    // First number is greater than the second number 
} 
else if (firstNumber.intValue == secondNumber.intValue) 
{ 
    // The two numbers have the same value 
} 
else 
{ 
    // The first number is smaller than the second number 
} 

Algo así es mucho más fácil de leer que las llamadas a -compare :, en mi opinión.

Erik

+1

Usted dice que "extraerá los valores enteros o los valores dobles". ¿Cuáles? El método compare: comparará correctamente los enteros de 64 bits y los valores dobles grandes que no encajan en un entero. En el primer caso, la extracción de valores dobles fallaría. En el segundo caso, la extracción de enteros fallaría. Usando comparar: funciona. – gnasher729

0

Swift 3,1

let number1 = NSNumber(value: 10.2) 
let number2 = NSNumber(value: 20.2) 
let result = number1.compare(number2) 
if result == .orderedAscending { 

} else if result == .orderedDescending { 

} else { // .orderedSame 

}