Come usare std :: signaling_nan?
-
04-07-2019 - |
Domanda
Dopo aver esaminato un'altra domanda su SO ( Uso di NaN in C ++ ) sono diventato curioso di sapere std::numeric_limits<double>::signaling_NaN()
.
Impossibile ottenere signaling_NaN per generare un'eccezione. Forse pensavo che segnalarlo significasse davvero un segnale, quindi ho provato a catturare SIGFPE ma no ...
Ecco il mio codice:
double my_nan = numeric_limits<double>::signaling_NaN();
my_nan++;
my_nan += 5;
my_nan = my_nan / 10;
my_nan = 15 / my_nan;
cout << my_nan << endl;
numeric_limits<double>::has_signaling_NaN
restituisce true, quindi è implementato sul mio sistema.
Qualche idea?
Sto usando il compilatore C ++ di ms visual studio .net 2003. Voglio provarlo su un altro quando torno a casa.
Grazie!
Soluzione
Puoi utilizzare la funzione _control87()
per abilitare il floating- eccezioni puntuali. Dalla documentazione MSDN su signal()
:
Nota:
Le librerie di runtime mascherano tutte le eccezioni in virgola mobile per impostazione predefinita.
Quando sono abilitate le eccezioni in virgola mobile, è possibile utilizzare <=> o SEH (Structured Exception Handling) da catturare loro.
Altri suggerimenti
Un avvertimento: L'uso di DLL di terze parti può abilitare silenziosamente queste eccezioni. Ciò è particolarmente vero per il caricamento di DLL scritte in una lingua che le abilita per impostazione predefinita.
Mi è capitato in due casi: stampare da un controllo browser incorporato su una stampante HP e registrare la mia DLL (che imposta alcuni valori iniziali su NaN) da InnoSetup che è scritto in Delphi.
La chiave sta in numeric_limits<T>::has_signaling_NaN
. Quale valore ha questo per te? (Il MSDN sembra suggerire che è sempre false
per MSVC?)
Da TFM :
cout << "The signaling NaN for type float is: "
<< numeric_limits<float>::signaling_NaN( )
<< endl;
- GT &;
La segnalazione NaN per il tipo float è: 1. # QNAN
dove 'Q' sta per 'Quiet'. Non so perché lo restituirebbe, ma è per questo che non fa eccezione per te.
Per curiosità, funziona meglio?
const double &real_snan( void )
{
static const long long snan = 0x7ff0000080000001LL;
return *(double*)&snan;
}