Domanda

Ho variabili doppie (o float) che potrebbero essere " vuote " ;, come se non avessi alcun valore valido. Come posso rappresentare questa condizione con i tipi integrati float e double?

Un'opzione sarebbe un wrapper che ha un float e un valore booleano, ma che non può & # 180; t funzionare, poiché le mie librerie hanno contenitori che contengono doppi e non oggetti che si comportano come doppi. Un altro sarebbe usare NaN (std :: numeric_limits). Ma non vedo alcun modo per verificare se una variabile è NaN.

Come posso risolvere il problema di aver bisogno di un " speciale " valore float per indicare qualcosa di diverso dal numero?

È stato utile?

Soluzione

In Visual C ++ esiste un _isnan(double) funzione che puoi importare attraverso float.h.

In C, esiste una isnan(double) che puoi importare tramite math.h.

In C ++, esiste una funzione isnan (doppia) che puoi importare tramite cmath.

Come altri hanno sottolineato, l'uso di NaN può essere molto problematico. Sono un caso speciale che deve essere trattato come puntatori NULL. La differenza è che un NaN di solito non causa dump core e guasti delle applicazioni, ma sono estremamente difficili da rintracciare. Se decidi di usare NaN, usali il meno possibile. L'uso eccessivo di NaN è una pratica di codifica offensiva.

Altri suggerimenti

Lo abbiamo fatto usando NaN:

double d = std::numeric_limits<double>::signaling_NaN();
bool isNaN = (d != d);

I valori di NaN confrontati per l'uguaglianza contro se stesso daranno falso. Questo è il modo in cui esegui il test per NaN, ma che sembra essere valido solo se std::numeric_limits<double>::is_iec559 è vero (in tal caso, è conforme anche a ieee754).

In C99 c'è una macro chiamata isnan per questo in math.h, che controlla anche un numero in virgola mobile per un valore NaN.

Non è un tipo incorporato, ma generalmente utilizzo boost::optional per questo tipo di cose. Se non puoi assolutamente usarlo, forse un puntatore farebbe il trucco - se il puntatore è NULL, allora sai che il risultato non contiene un valore valido.

Un'opzione sarebbe un wrapper che ha un float e un valore booleano, ma che può & # 180; t funzionare, poiché le mie librerie hanno contenitori che immagazzinano doppi e non oggetti che si comportano come doppi .

È un peccato. In C ++ è banale creare una classe basata su modelli che si converte automaticamente nell'attributo double (riferimento) effettivo. (O un riferimento a qualsiasi altro tipo per quella materia.) Basta usare l'operatore di cast in una classe basata su modelli. Esempio: operatore TIPO & Amp; () { valore di ritorno; } È quindi possibile utilizzare un HasValue & Lt; double & Gt; ovunque si userebbe normalmente un doppio.

Un altro sarebbe usare NaN (std :: numeric_limits). Ma non vedo alcun modo per verificare se una variabile è NaN.

Come hanno osservato anche litb e James Schek , C99 ci fornisce isnan ().

Ma stai attento! I valori di Nan rendono la matematica & Amp; logica davvero interessante! Penseresti che un numero non possa essere sia NOT & Gt; = foo che NOT & Lt; = foo. Ma con NaN, può.

C'è un motivo per cui tengo una macro WARN-IF-NAN (X) nella mia cassetta degli attrezzi. Ho avuto alcuni problemi interessanti in passato.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top