Float o doppio valore speciale
-
22-07-2019 - |
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?
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.