std::isfinite в MSVC

Стандарт C++11 и C11 определяет функцию std::isfinite. . Visual Studio 2012, похоже, не предоставляет его как часть cmath или math.h, но имеет amp_math.h, который кажется, предоставляет эту функцию.

Можно ли заменить isfinite на std::isfinite? В документации не говорится о поведении при вызове с помощью NAN, и у меня нет компилятора VS для проверки этого.


person pmr    schedule 29.01.2013    source источник


Ответы (2)


Как уже указал Мариус, isfinite из amp_math.h должен использоваться в C++ AMP, который является расширением MS для параллельных вычислений на многоядерных архитектурах, подобных CUDA или OpenCL. И поскольку эта функция может использоваться только в реальных функциях с ограниченным доступом AMP (обычно в ядрах графического процессора), она не будет вам особенно полезна.

К сожалению, VS 2012 не поддерживает математические функции C++11 и функции управления с плавающей запятой. Но как только вы узнаете, что находитесь в VC, и реализуете для него специальный код, вы можете просто использовать _finite (или, скорее, !_finite) из <float.h>, которая является MS-специфичной функцией, поддерживаемой по крайней мере, начиная с VS 2003. Но имейте в виду, что _finite принимает только double и, таким образом, преобразует любые аргументы, отличные от double (хотя VC все равно не имеет правильного long double), со всеми вытекающими последствиями (в то время как INF и тихие NaN должны быть преобразованы без проблем, я не уверен, что ловушка на сигнальном NaN в преобразовании также произошла бы в результате прямого вызова std::finite).

В стандартной библиотеке VC есть другие подобные функции, которые можно использовать для своих целей. отсутствие поддержки C++11/C99 ​​(например, _isnan и т.п.). (Почему они отказываются просто удалить это подчеркивание перед этими функциями и поместить простую оболочку <cfenv> вокруг _controlfp и, таким образом, немного приблизиться к полной поддержке C++11, это совершенно другой вопрос.)

РЕДАКТИРОВАТЬ: Помимо этого, прямой подход к проверке INFs и NaNs также может работать:

template<typename T> bool isfinite(T arg)
{
    return arg == arg && 
           arg != std::numeric_limits<T>::infinity() &&
           arg != -std::numeric_limits<T>::infinity();
}

Но, конечно, с теми же последствиями, что и, возможно, перехват для сигнализации NaNs (хотя я должен признать, что я не очень хорошо разбираюсь в тонкостях сигнализации NaNs и исключений с плавающей запятой в целом).

person Christian Rau    schedule 29.01.2013
comment
Хорошо, это достаточная головная боль, чтобы заставить меня просто использовать boost.org/doc/libs/1_52_0/libs/math/doc/sf_and_dist/html/ - person pmr; 29.01.2013
comment
Возможно, это само собой разумеется, но ваша функция isfinite в вашем редактировании очень специфична для C++. - person pattivacek; 08.03.2014
comment
@patrickvacek Правда, но Visual Studio все равно не имеет разумной поддержки C. Я вижу, что ответ касается только части вопроса на C ++, но ОП, похоже, знает оба языка и, таким образом, должен быть в состоянии вывести C-версию ответа, если это необходимо. - person Christian Rau; 08.03.2014

isfinite из amp_math.h можно вызывать только из функций, отмеченных restrict(amp), что не делает их взаимозаменяемыми, даже если поведение было таким же.

person Marius Bancila    schedule 29.01.2013
comment
Ваш ответ точен, но разработка Кристианом Рау альтернативных возможностей делает его лучшим ответом. Виноват мой недоопределенный вопрос, а не ваш ответ. - person pmr; 29.01.2013