Come determinare se un numero NSN di Cocoa rappresenta NaN (non un numero)?Determinare se NSNumber è NaN
Questo emerge, ad esempio, quando analizzo una stringa con contenuti non numerici non validi.
Come determinare se un numero NSN di Cocoa rappresenta NaN (non un numero)?Determinare se NSNumber è NaN
Questo emerge, ad esempio, quando analizzo una stringa con contenuti non numerici non validi.
Quindi, ho scoperto che la proprietà di classe [NSDecimalNumber notANumber]
è solo per questo scopo. In alcune lingue NaN! = NaN, ma questo non è il caso di Cocoa.
Non esiste un oggetto di questo tipo per NSNumber poiché se non è un numero, quindi, beh, non è un NSNumber. È più usuale usare un oggetto nullo per rappresentarlo.
Come dice Mike Abdullah, il modo naturale per rappresentare un NaN in Cocoa è con nil
, ma [NSNumber numberWithDouble:NAN]
restituisce un oggetto valido. Non c'è il NSNumber
, un modo specifico per rilevare questo, ma il modo generale, isnan([foo doubleValue])
, funziona. Se non ti piacciono le funzioni, puoi inserirle in una categoria.
hey guys: Sono abbastanza sicuro che nil non significa la stessa cosa di NaN. Nil significa nessun valore. NaN è usato per rappresentare il risultato di certe operazioni in virgola mobile (dividendo per zero, per esempio) ... quindi in realtà NaN È un numero .. È il numero "Non un numero" ... – nielsbot
Sì, lo sappiamo. Il punto rimane che 'nil' è il modo naturale per rappresentare cose come una stringa con costanti non numeriche, come nell'esempio dell'OP. –
c'è anche la funzione isnan() l'ho trovata oggi.
Qualsiasi espressione booleana con NaN restituirà sempre false. Ma come è utile?
Stavo recuperando Nan dalla posizioneInView: mentre gestivo alcuni gesti in un'app per iPhone. Ed è stato molto contento di scoprire che qualsiasi espressione booleana con NaN restituirà sempre false. Metto questo per usare liek qui sotto:
// Stavo usando il UIPanGestureRecognizer
, e sembra che su TouchUp vorrei ottenere Nan per il/location .x - .y - piuttosto ragionevole dal momento che in questo caso la fine di un tocco non ha una posizione
CGPoint location = [gestureRecognizer locationInView:self];
if (location.x != location.x || location.y != location.y)
{
return;
}
Allora finché .x e .y o valori float legittimi, ovviamente non saranno mai diverso da lì proprio valore. MA nel caso di .x o .y essendo NaN, il confronto sarà falso. E posso tranquillamente evitare i calcoli con Nan.
Per decimali, almeno:
[[NSDecimalNumber notANumber] isEqualToNumber:myNumber]
ho trovato che questo funziona, ma è legale?
NSNumber *NaN = [NSDecimalNumber notANumber];
NSDecimalNumber *x = ... fill it somehow with NaN content ...
if (x == NaN) ... this works
è NaN
garantita per essere un valore costante singleton
? Sarebbe bello, ma suppongo che non lo sia, dal momento che tutti gli esempi che ho trovato usano i metodi isEqual
.
Certo, nessuna parola 'singleton' nella documentazione, sembra necessario isEqual-ish tutti i controlli. (( – dmitrynikolaev
NaN non è un valore univoco - ci sono varianti, tra cui NaN 'quiet' e 'NaN di segnalazione' e la definizione di codifica consente ad alcuni bit irrilevanti (ad esempio il segno) di avere qualsiasi valore. Per questo motivo == NAN non può essere –
Sicuramente è un singleton dietro le quinte, ma è comunque meglio usare sEqual nel caso in cui questo comportamento cambi in futuro. – Andy
Per determinare se NSNumber è un NaN, convertirlo in un doppio e utilizzare la funzione C isnan()
:
NSNumber *validNumber = [NSNumber numberWithDouble: 1.];
NSLog(@"%d", isnan(validNumber.doubleValue)); // prints "0"
NSNumber *nanNumber = [NSNumber numberWithDouble: 0./0.];
NSLog(@"%d", isnan(nanNumber.doubleValue)); // prints "1"
Tuttavia, si deve fare attenzione, perché ci sono altri valori speciali, ad esempio:
NSNumber *posInfinity = [NSNumber numberWithDouble: 1./0.];
NSLog(@"%d", isnan(posInfinity.doubleValue)); // prints "0"
Se si desidera verificare la presenza di questi valori così, è meglio usare isnormal()
invece:
NSLog(@"%d", isnormal(validNumber.doubleValue)); // prints "1"
NSLog(@"%d", isnormal(nanNumber.doubleValue)); // prints "0"
NSLog(@"%d", isnormal(posInfinity.doubleValue)); // prints "0"
Vale la pena notare che 'isnormal (0)' restituisce 0 (come 'isnormal (NAN)') quindi se zero è un valore potenzialmente valido, controlla sia 'inan' che' isinf'. 'isfinite()' è un'opzione migliore. – Demitri
Possiamo anche usare un #define definito in matematica.h, nel modo seguente
if(isnan(myNumber))
{ // myNumber is NaN .
}
Questa soluzione funziona con i tipi di dati primitivi e non con gli oggetti NSNumber direttamente, devi ottenere il valore di NSNumber, esempio: number.intValue – ObjSal
Solo per chiarezza, per verificare se un NSNumber è NaN allora il codice sarebbe: '[NSNumber isEqualToNumber: [NSDecimalNumber NotANumber]]'. Questo restituisce SÌ se NSNumber è NaN. – SimonB