std::isfinite в MSVC
Стандарты C++11 и C11 определяют функцию std::isfinite. Visual Studio 2012, кажется, не предоставляет его как частьcmath
или же math.h
, но имеет amp_math.h
который, кажется, обеспечивает эту функцию.
Это isfinite
взаимозаменяемы с std::isfinite
? Документация не говорит о поведении при вызове с NAN
и у меня нет компилятора VS, чтобы проверить это.
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 - это совершенно другой вопрос.)
РЕДАКТИРОВАТЬ: Кроме этого, прямой подход для проверки INF
с и NaN
Может также работать:
template<typename T> bool isfinite(T arg)
{
return arg == arg &&
arg != std::numeric_limits<T>::infinity() &&
arg != -std::numeric_limits<T>::infinity();
}
Но, конечно, с теми же последствиями, вероятно, ловушкой для сигнализации NaN
s (хотя я должен признать, что я не очень хорошо разбираюсь в тонкостях передачи сигналов NaN
s и исключения с плавающей точкой в общем).
isfinite
от amp_math.h
можно вызывать только из функций, отмеченных restrict(amp)
, что не делает его взаимозаменяемым, даже если поведение было таким же.