Как использовать std::signaling_nan?
-
04-07-2019 - |
Вопрос
Посмотрев на другой вопрос о 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, поэтому оно реализовано в моей системе.
Есть идеи?
Я использую компилятор C++ MS Visual Studio .net 2003.Я хочу проверить это на другом, когда приду домой.
Спасибо!
Решение
Вы можете использовать _control87()
функция для включения исключений с плавающей запятой.Из документации MSDN на _control87()
:
Примечание:
Библиотеки времени выполнения по умолчанию маскируют все исключения с плавающей запятой.
Если включены исключения с плавающей запятой, вы можете использовать signal()
или SEH (структурированная обработка исключений) чтобы поймать их.
Другие советы
Слово предупреждения:Использование сторонних DLL может автоматически активировать эти исключения.Это особенно актуально для загрузки DLL, написанных на языке, который разрешает их по умолчанию.
У меня такое было в двух случаях:Печать из встроенного элемента управления браузером на принтер HP и регистрация моей DLL (которая устанавливает некоторые начальные значения в NaN) из InnoSetup, написанной на Delphi.
Ключ заключается в numeric_limits<T>::has_signaling_NaN
.Какую ценность это имеет для вас?(Похоже, MSDN предполагает, что это всегда false
для MSVC?)
От ТФМ:
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;
}