Browse Source

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).
pull/87/head
Vladimír Vondruš 12 years ago
parent
commit
75c3e00844
  1. 17
      src/Magnum/Math/Constants.h
  2. 74
      src/Magnum/Math/Test/ConstantsTest.cpp

17
src/Magnum/Math/Constants.h

@ -29,6 +29,13 @@
* @brief Class @ref Magnum::Math::Constants
*/
#include <cmath>
#include "Magnum/configure.h"
#ifndef MAGNUM_TARGET_GLES
#include <limits>
#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<class T> struct Constants {
Constants() = delete;
@ -68,6 +76,9 @@ template<class T> 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<Double> {
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<Double>::quiet_NaN(); }
static constexpr Double inf() { return std::numeric_limits<Double>::infinity(); }
};
#endif
template<> struct Constants<Float> {
@ -93,6 +107,9 @@ template<> struct Constants<Float> {
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

74
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<class> void _constants();
template<class> void _specials();
};
ConstantsTest::ConstantsTest() {
addTests({&ConstantsTest::constantsFloat,
&ConstantsTest::constantsDouble});
addTests({&ConstantsTest::constants,
&ConstantsTest::specials});
}
void ConstantsTest::constantsFloat() {
constexpr Float a = Constants<Float>::sqrt2();
constexpr Float b = Constants<Float>::sqrt3();
CORRADE_COMPARE(Math::pow<2>(a), 2.0f);
CORRADE_COMPARE(Math::pow<2>(b), 3.0f);
constexpr Float c = Constants<Float>::pi();
constexpr Float d = Constants<Float>::piHalf();
constexpr Float e = Constants<Float>::tau();
CORRADE_COMPARE(0.5f*c, d);
CORRADE_COMPARE(2.0f*c, e);
constexpr Float f = Constants<Float>::e();
CORRADE_COMPARE(std::log(f), 1.0f);
void ConstantsTest::constants() {
_constants<Float>();
#ifndef MAGNUM_TARGET_GLES
_constants<Double>();
#endif
}
void ConstantsTest::constantsDouble() {
void ConstantsTest::specials() {
_specials<Float>();
#ifndef MAGNUM_TARGET_GLES
constexpr Double a = Constants<Double>::sqrt2();
constexpr Double b = Constants<Double>::sqrt3();
CORRADE_COMPARE(Math::pow<2>(a), 2.0);
CORRADE_COMPARE(Math::pow<2>(b), 3.0);
constexpr Double c = Constants<Double>::pi();
constexpr Double d = Constants<Double>::piHalf();
constexpr Double e = Constants<Double>::tau();
CORRADE_COMPARE(0.5*c, d);
CORRADE_COMPARE(2.0*c, e);
constexpr Double f = Constants<Double>::e();
CORRADE_COMPARE(std::log(f), 1.0);
#else
CORRADE_SKIP("Double precision is not supported when targeting OpenGL ES.");
_specials<Double>();
#endif
}
template<class T> void ConstantsTest::_constants() {
constexpr T a = Constants<T>::sqrt2();
constexpr T b = Constants<T>::sqrt3();
CORRADE_COMPARE(Math::pow<2>(a), T(2));
CORRADE_COMPARE(Math::pow<2>(b), T(3));
constexpr T c = Constants<T>::pi();
constexpr T d = Constants<T>::piHalf();
constexpr T e = Constants<T>::tau();
CORRADE_COMPARE(T(0.5)*c, d);
CORRADE_COMPARE(T(2.0)*c, e);
constexpr T f = Constants<T>::e();
CORRADE_COMPARE(std::log(f), T(1));
}
template<class T> void ConstantsTest::_specials() {
constexpr T g = Constants<T>::nan();
CORRADE_VERIFY(g != g);
constexpr T h = Constants<T>::inf() - Constants<T>::inf();
CORRADE_VERIFY(h != h);
}
}}}
CORRADE_TEST_MAIN(Magnum::Math::Test::ConstantsTest)

Loading…
Cancel
Save