2012-04-17 23 views
6

Mam metodę, która musi zrobić coś innego, gdy otrzyma unset float niż float z wartością 0. Zasadniczo, muszę sprawdzić, czy zmienna była, czy nie, licząc ją jako zestaw, jeśli ma wartość od 0.Jak odróżnić unset float od tego o wartości 0?

Więc co zastępczy należy użyć jako wartość wyłączonym (nil, NULL, NO, etc) i jak można sprawdzać, czy zmienna jest ustawiona bez powrotu prawdziwe dla wartości 0 ?

+0

Dlaczego nie NaN (np. 1,0/0,0)? Aby sprawdzić, czy zmienna jest NaN, to po prostu 'num! = Num' (NaN nie jest równe cokolwiek, nawet samemu). – cHao

+0

Pozyskiwanie NaN przez dzielenie przez zero jest niebezpieczne, ponieważ może pułapkować/generować sygnalizację NaN –

+0

Czy istnieje lepszy sposób? Nie zmyliłem się z NaN na tyle, aby martwić się, jak * celowo * je wygenerować. :) Całkiem pewne, że 'NaN' nie będzie działało jako literał float ... – cHao

Odpowiedz

16

Możesz zainicjować swoje pływaki na NaN (np. Dzwoniąc pod numer nan() lub nanf()), a następnie przetestować je pod isnan(), jeśli zostały zmienione w celu zachowania numeru. (Zauważ, że testowanie myvalue == nan() będzie nie pracy.)

Jest to zarówno dość proste (prawdopodobnie będzie to math.h w każdym przypadku) i koncepcyjnie sensowne: Każda wartość, która nie jest ustawiona na liczbę „nie jest liczbą” ...

+5

Niesamowite, dziękuję! Współpracowałem z 'CGFloat myFloat = NAN;' oraz 'if (isnan (myFloat)) {...}'. – Nathan

+0

Miło to słyszeć! –

+2

Inną opcją dla konkretnego przypadku byłoby użycie MAXFLOAT. – Till

3

Użycie stałej wartości do wskazania stanu nieustalonego często prowadzi do błędów, gdy zmienna prawomocnie uzyskuje wartość tej stałej.

Należy rozważyć użycie NSNumber do przechowywania pływaka. W ten sposób może nie tylko być nil, będzie domyślnie do tego stanu.

Zakłada się, że potrzebna jest tylko niewielka liczba elementów pływających. Jeśli potrzebujesz ich milionów, NSNumber może być zbyt wolny i wymagać dużej ilości pamięci.

+0

Muszę matematyki z tych pływaków, więc NSNumber nie jest idealny. Przypuszczam, że mógłbym przejściowo się nawrócić, ale wydaje mi się to kosztowne i niepotrzebne. Czy możesz rozwinąć niebezpieczeństwa związane z używaniem czegoś takiego jak NaN? – Nathan

+0

Niebezpieczeństwo polega na tym, że twój pływak może zostać przypisany, ale posiada wartość NaN, więc twój kod traktuje to jako nieprzypisane. Oczywiście, nie powinieneś ślepo przekazywać NaN większości procedur matematycznych. Jeśli te wartości pochodzą od użytkownika, polecenie ponownego wpisania, gdy ich wynik spowodował NaN, jest również logiczne. – Dondragmer

2

Zamiast przeciążać te właściwości float (nazwijmy je X i Y), utwórz osobną flagę isValid dla każdej właściwości. Inicjalizuj flagi, aby wskazać, że zmienne nie zostały ustawione i podaj własne setery, aby odpowiednio zarządzały flagami. Więc twój kod może wyglądać następująco:

if (self.isXValid == YES) { 
    self.Y = ... // assigning to Y sets isYValid to YES 
} 
else if (self.isYValid == YES) { 
    self.X = ... // assigning to Y sets isXValid to YES 
} 

Można rzeczywiście pójść o krok dalej i mieć setter dla X również przypisać Y i odwrotnie. Lub, jeśli X i Y są tak blisko ze sobą powiązane, że można je obliczyć na podstawie wartości drugiej, tak naprawdę potrzebujesz tylko jednej zmiennej dla obu właściwości.

Powiązane problemy