Как использовать std :: signaling_nan? - PullRequest
7 голосов
/ 25 октября 2008

Посмотрев другой вопрос о SO ( Использование NaN в C ++ ), мне стало любопытно узнать std::numeric_limits<double>::signaling_NaN().

Мне не удалось заставить signaling_NaN выдать исключение. Я подумала, что под сигналом это действительно означает сигнал, поэтому я попыталась поймать SIGFPE, но нет ...

Вот мой код:

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 оценивается как true, поэтому он реализован в моей системе.

Есть идеи?

Я использую компилятор MS Visual Studio .net 2003 C ++. Я хочу проверить это на другом, когда вернусь домой.

Спасибо!

Ответы [ 4 ]

5 голосов
/ 26 октября 2008

Слово предупреждения: Использование сторонних библиотек DLL может автоматически включить эти исключения. Это особенно верно для загрузки библиотек DLL, написанных на языке, который включает их по умолчанию.

Это происходило в двух случаях: печать из встроенного элемента управления браузера на принтер HP и регистрация моей DLL (которая устанавливает некоторые начальные значения для NaN) из InnoSetup, написанного на Delphi.

5 голосов
/ 25 октября 2008

Вы можете использовать функцию _control87() для включения исключений с плавающей точкой. Из документации MSDN на _control87():

Примечание:

По умолчанию библиотеки времени выполнения маскируют все исключения с плавающей точкой.

Когда исключения с плавающей запятой включены, вы можете использовать signal() или SEH (Структурная обработка исключений) , чтобы перехватить их.

1 голос
/ 25 октября 2008

Ключ лежит в numeric_limits<T>::has_signaling_NaN. Какое значение это имеет для вас? (MSDN, кажется, предполагает, что это всегда false для MSVC?)

0 голосов
/ 25 октября 2008

С TFM :

cout << "The signaling NaN for type float is:  "
    << numeric_limits<float>::signaling_NaN( )
    << endl;

->

Сигнализация NaN для типа float: 1. # QNAN

, где 'Q' означает 'Тихий'. Не знаю, почему это вернуло бы это, но именно поэтому оно не бросает исключение для вас.

Из любопытства, это работает лучше?

const double &real_snan( void )
{
    static const long long snan = 0x7ff0000080000001LL;
    return *(double*)&snan;
}
...