2013-02-27 14 views
7

Quali sono i vantaggi di NaN, PositiveInfinity o NegativeInfinity per float e double? Quando dovremmo usarli o evitarli?Quando utilizzare NaN o +/- Infinity?

Se esistono costanti come queste, perché float.Parse("a") genera un errore anziché restituire float.NaN?

Come è NaN diverso da null? Perché è possibile anche division by zero per i tipi floating?

+0

si potrebbe usare TryParse piuttosto che analizzare? – Liam

+2

Utilizzato a causa di operazioni matematiche. – Evgeny

+8

@Evgeny: commento più vago di sempre. –

risposta

7

Essi non sono così tanto qualcosa che si utilizzare come sono qualcosa che è necessario essere a conoscenza di:

double hmm = 1.0/0.0; 
double hmm2 = -1.0/0.0; 
double hmm3 = 0.0/0.0; 
Console.WriteLine("1/0 == {0}", hmm); 
Console.WriteLine("-1/0 == {0}", hmm2); 
Console.WriteLine("0/0 == {0}", hmm3); 

uscita:

1/0 == Infinity 
-1/0 == -Infinity 
0/0 == NaN 

EDIT: Per quanto riguarda questa domanda:

Se ci sono delle costanti come questi, perché fa float.Par se ("a") lancia un errore piuttosto che restituire float.NaN?

double.NaN è in realtà una definizione matematica in un modo - è "definito" come 0.0/0.0 - mentre le parole "non un numero" implicano che qualcosa di simile double.Parse("a") deve anche restituire double.NaN, non è così. Perché?

La mia impressione è perché sarebbe impossibile determinare se il double.NaN hai ricevuto è stato il risultato di dati di immondizia (nel caso della stringa) o il effettivo definizione di un numero indeterminato, come lo zero diviso per zero. Quindi, per fare una distinzione tra questi due casi, double.Parse("a") lancia un Exception, che ritengo sia più accurato.

+0

Perché la divisione per zero è possibile per i tipi floating? – LZW

+1

@LZW Risposta semplice: poiché è possibile digitare/compile/eseguire '1.0/0.0' - nei tempi antichi, ciò causerebbe un' DivideByZeroException', ma ci sono applicazioni teoriche per i valori "Definito" 'Infinito' e' NaN' - ad esempio, WPF usa entrambi per indicare dimensioni "unset" o "indefinite", ecc. – JerKimball

+0

@LZW: In molti casi, determinare * se * un'espressione in virgola mobile possa essere valutata senza calcoli intermedi che vanno fuori intervallo richiedono calcoli che sono più costosi di quelli necessari per valutare l'espressione quando tutto è nel raggio d'azione. Consentire al codice di provare a valutare l'espressione e quindi scoprire se ci fosse un problema è quindi più economico di richiedere il codice per rilevare in anticipo le condizioni problematiche. – supercat

6

se ci sono costanti come questi perché float.Parse("a") errore tiro piuttosto che ritornare float.NaN?

Poiché nessuna delle due alternative che hai elencato sono applicabili qui:

PositiveInfinity e NegativeInfinity sono solo che - vale a dire che sono il risultato di espressioni come 1/0 o -1/0.

NaN è il risultato di 0/0, ovvero un'espressione il cui risultato non è (normalmente) ben definito e non genera un numero.

float.Parse("a") è niente del genere. Certo, potrebbe potenzialmente essere rappresentato da NaN ma poi non si potrebbe distinguere tra l'utente inserendo un float valore valido (a) ed un valore valido float (NaN). Questo non è un argomento molto forte, tuttavia: NaN è esplicitamente un segnaposto per un numero non valido quindi concettualmente, potrebbe essere utilizzato per rappresentare input dell'utente valido.

D'altra parte, ci sono altri tipi che hanno un metodo Parse e per i quali esiste alcun valore NaN (come int). Per questi tipi, Parsedeve pertanto segnalare un errore. Sarebbe incoerente (e quindi una cattiva progettazione dell'API) fare in modo che il metodo Parse di tipi diversi si comporti diversamente.

+2

parseFloat di JavaScript ("a") restituisce NaN. – LZW

1

Oltre ai risultati dell'aritmetica, i valori di infinito possono essere utilizzati per definire alcun limite per un contesto.

Ad esempio: un controllo WPF padre che chiede a uno dei suoi figli di misurarsi, nel contesto che non esiste alcuna restrizione di dimensioni; cioè availableSize è PositiveInfinity

Rif: MeasureOverride

+0

Questa è l'unica risposta che fornisce un esempio del mondo reale (non teorico). – LZW

9

Infinities sono usati perché sono parte del sistema aritmetico supportato da virgola mobile. Vi sono varie operazioni, come la divisione per zero, in cui l'infinito è un risultato utile ed è matematicamente sensibile. Ovviamente, nessuna quantità fisica diretta può essere infinita (per esempio, non si possono avere infiniti grammi), ma l'infinito può essere un valore utile per qualche aspetto di un modello matematico di processi fisici o di altre cose che gli esseri umani modellano con i computer.

I NaN vengono utilizzati perché il sistema aritmetico è incompleto. Cioè, ci sono operazioni con valori di input per i quali il risultato matematico corretto non è rappresentabile all'interno di un punto mobile. Ad esempio, sqrt (-1) è un'operazione matematica legittima, ma il risultato, il numero immaginario i, non è rappresentabile in virgola mobile. Quindi NaN viene usato come segnaposto per indicare che i valori sono andati oltre i numeri in virgola mobile. NaN può anche essere utilizzato per altri scopi, ad esempio per contrassegnare i dati non inizializzati in altro modo, per facilitare il debug.

float.Parse("a") genera un errore anziché restituire un NaN perché non è un'operazione legittima. Questa espressione non esegue un'operazione matematica che ha un risultato corretto al di fuori dei numeri rappresentabili. È un errore reale, quindi genera un errore.

+0

Mi piace questa risposta; spiega perché Parse fallisce, poiché fondamentalmente stai cercando di unificare due tipi che non hanno alcuna relazione (float e stringa) – JerKimball

0

Per risolvere NAN e l'infinito, utilizzare questo:

if (Double.IsNaN(YourValue) || Double.IsInfinity(YourValue)) 
{ 
    YourValue = 0; 
}