From 75c3e00844b81b67dac35420af30102d489f520d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 1 Jan 2015 14:36:56 +0100 Subject: [PATCH] Math: added NaN and infinity to constants. Using std::numeric_limits for the Double variants looks like an overkill to me, but there apparently isn't any other way, except for crafting the value manually using the exact binary representation (and hoping it will be portable) or producing the value as result of division by zero or something like that (and then working around the warnings and also hoping it will be portable). --- src/Magnum/Math/Constants.h | 17 ++++++ src/Magnum/Math/Test/ConstantsTest.cpp | 74 ++++++++++++++------------ 2 files changed, 57 insertions(+), 34 deletions(-) diff --git a/src/Magnum/Math/Constants.h b/src/Magnum/Math/Constants.h index 212da2cd4..b94cfdeef 100644 --- a/src/Magnum/Math/Constants.h +++ b/src/Magnum/Math/Constants.h @@ -29,6 +29,13 @@ * @brief Class @ref Magnum::Math::Constants */ +#include + +#include "Magnum/configure.h" +#ifndef MAGNUM_TARGET_GLES +#include +#endif + #include "Magnum/Types.h" namespace Magnum { namespace Math { @@ -37,6 +44,7 @@ namespace Magnum { namespace Math { @brief Numeric constants @see @ref Magnum::Constants, @ref Magnum::Constantsd +@todo Invent a way to generate double NaN/infinity without including whole limits header */ template struct Constants { Constants() = delete; @@ -68,6 +76,9 @@ template struct Constants { static constexpr T e(); /**< @brief Euler's number */ static constexpr T sqrt2(); /**< @brief Square root of 2 */ static constexpr T sqrt3(); /**< @brief Square root of 3 */ + + static constexpr T nan(); /**< @brief Quiet NaN */ + static constexpr T inf(); /**< @brief Positive infinity */ #endif }; @@ -82,6 +93,9 @@ template<> struct Constants { static constexpr Double e() { return 2.718281828459045; } static constexpr Double sqrt2() { return 1.414213562373095; } static constexpr Double sqrt3() { return 1.732050807568877; } + + static constexpr Double nan() { return std::numeric_limits::quiet_NaN(); } + static constexpr Double inf() { return std::numeric_limits::infinity(); } }; #endif template<> struct Constants { @@ -93,6 +107,9 @@ template<> struct Constants { static constexpr Float e() { return 2.718281828f; } static constexpr Float sqrt2() { return 1.414213562f; } static constexpr Float sqrt3() { return 1.732050808f; } + + static constexpr Float nan() { return NAN; } + static constexpr Float inf() { return INFINITY; } }; #endif diff --git a/src/Magnum/Math/Test/ConstantsTest.cpp b/src/Magnum/Math/Test/ConstantsTest.cpp index 2331e477e..80b0a1026 100644 --- a/src/Magnum/Math/Test/ConstantsTest.cpp +++ b/src/Magnum/Math/Test/ConstantsTest.cpp @@ -34,51 +34,57 @@ class ConstantsTest: public Corrade::TestSuite::Tester { public: ConstantsTest(); - void constantsFloat(); - void constantsDouble(); + void constants(); + void specials(); + + private: + template void _constants(); + template void _specials(); }; ConstantsTest::ConstantsTest() { - addTests({&ConstantsTest::constantsFloat, - &ConstantsTest::constantsDouble}); + addTests({&ConstantsTest::constants, + &ConstantsTest::specials}); } -void ConstantsTest::constantsFloat() { - constexpr Float a = Constants::sqrt2(); - constexpr Float b = Constants::sqrt3(); - CORRADE_COMPARE(Math::pow<2>(a), 2.0f); - CORRADE_COMPARE(Math::pow<2>(b), 3.0f); - - constexpr Float c = Constants::pi(); - constexpr Float d = Constants::piHalf(); - constexpr Float e = Constants::tau(); - CORRADE_COMPARE(0.5f*c, d); - CORRADE_COMPARE(2.0f*c, e); - - constexpr Float f = Constants::e(); - CORRADE_COMPARE(std::log(f), 1.0f); +void ConstantsTest::constants() { + _constants(); + #ifndef MAGNUM_TARGET_GLES + _constants(); + #endif } -void ConstantsTest::constantsDouble() { +void ConstantsTest::specials() { + _specials(); #ifndef MAGNUM_TARGET_GLES - constexpr Double a = Constants::sqrt2(); - constexpr Double b = Constants::sqrt3(); - CORRADE_COMPARE(Math::pow<2>(a), 2.0); - CORRADE_COMPARE(Math::pow<2>(b), 3.0); - - constexpr Double c = Constants::pi(); - constexpr Double d = Constants::piHalf(); - constexpr Double e = Constants::tau(); - CORRADE_COMPARE(0.5*c, d); - CORRADE_COMPARE(2.0*c, e); - - constexpr Double f = Constants::e(); - CORRADE_COMPARE(std::log(f), 1.0); - #else - CORRADE_SKIP("Double precision is not supported when targeting OpenGL ES."); + _specials(); #endif } +template void ConstantsTest::_constants() { + constexpr T a = Constants::sqrt2(); + constexpr T b = Constants::sqrt3(); + CORRADE_COMPARE(Math::pow<2>(a), T(2)); + CORRADE_COMPARE(Math::pow<2>(b), T(3)); + + constexpr T c = Constants::pi(); + constexpr T d = Constants::piHalf(); + constexpr T e = Constants::tau(); + CORRADE_COMPARE(T(0.5)*c, d); + CORRADE_COMPARE(T(2.0)*c, e); + + constexpr T f = Constants::e(); + CORRADE_COMPARE(std::log(f), T(1)); +} + +template void ConstantsTest::_specials() { + constexpr T g = Constants::nan(); + CORRADE_VERIFY(g != g); + + constexpr T h = Constants::inf() - Constants::inf(); + CORRADE_VERIFY(h != h); +} + }}} CORRADE_TEST_MAIN(Magnum::Math::Test::ConstantsTest)