2011-07-07 16 views
51

Jestem początkujący w Obj-C i jestem nieco mylić w tym scenariuszu Mam następujący kod:Porównywanie NSNumbers w Objective C

if (number1 < number2) { 

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

} 

Kiedy uruchomić ten kod widzę bardzo dziwne wyniki, jak to :

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 

Obie liczby są obiektami NSNumber, jak może się stać coś takiego? Otrzymuję te dwie liczby, znajdując odległości między duszkami na ekranie.

Wszelkie wskazówki lub porady byłoby naprawdę ceniona

+1

Podobnie jak notatki, można połączyć je za pomocą '' NSLog's NSLog (@ "liczba% @ jest mniejsza niż% @", number1, number2); ' –

Odpowiedz

94

Zakładam liczba1 i liczba2 są wskaźnikami do obiektów. Znak < porównuje wskaźniki.

Trzeba porównać rzeczywistą floatValue lub doubleValue

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

....

+0

Bardzo dziękuję dzięki Kal –

+34

Alternatywnie, możesz zrobić' if ([number1 compare: number2] == NSOrderedAscending) '. –

+3

Mówiąc prawdę, przegłosowałem, ponieważ: a) Porównanie 'float's jest z natury niespójne i nieważne z prawdą (jeśli cokolwiek, porównaj' liczba1' 'wartość' float' minus 'liczba2' wartość' float' do jakiś mały epsilon), b) 'float's są złe i niegodne zaufania; 'double's są do zrobienia, jeśli cokolwiek, i c) nie przejmuj się porównywanie liczb w ten sposób, jeśli są one liczbami całkowitymi. Komentarz @Adama Rosenfielda jest najlepszym sposobem na zrobienie tego; zaufaj 'metodą porównawczą NSNumber, aby zająć się nią dla ciebie. –

15

NSNumber ma metodę Dla porównania: - (NSComparisonResult) Porównaj: (NSNumber *) anumber

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

To jest najbardziej dokładny i niezawodny sposób, aby to zrobić, ponieważ nie ryzykujesz utraty precyzji. –

33

W przypadkach, w których po prostu chcesz przetestować, czy dwie właściwości NSNumber przechowują tę samą wartość, co lue, następnie z dokumentacji firmy Apple wydaje się, że używając

- (BOOL)isEqualToNumber:(NSNumber *)aNumber 

jest najbardziej prosty i skuteczny sposób, aby porównać dwie wartości NSNumber.

Na przykład:

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

Dokumentacja mówi także „Ta metoda jest bardziej wydajny niż por. Jeśli znasz dwa obiekty są liczbami”

Gdy trzeba wiedzieć, czy wartość jest mniejsza lub większa, oferują metodę

- (NSComparisonResult)compare:(NSNumber *)aNumber 

, ale osobiście wolałbym w tym momencie po prostu wyciągnąć wartości INTEGER (lub wartości podwójnych) oraz regularne < oraz> operatorów zrobić porównanie, bo sprawia, że ​​kod znacznie łatwiejsze do odczytania, tak:

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 
} 

Coś w tym jest o wiele łatwiejsze do odczytania niż zaproszeń do -Porównanie :, moim zdaniem.

Erik

+1

Mówisz, że chcesz "wyciągnąć wartości całkowite lub podwójne wartości". Które? Metoda compare: poprawnie porówna zarówno 64-bitowe liczby całkowite, jak i duże podwójne wartości, które nie mieszczą się w liczbie całkowitej. W pierwszym przypadku wyodrębnianie podwójnych wartości zakończy się niepowodzeniem. W drugim przypadku wyodrębnianie liczb całkowitych zakończy się niepowodzeniem. Używanie porównania: działa. – 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 

}