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!

È stato utile?

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;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top