From dd244d8d2589bbb33895d497ca739160c11b036a Mon Sep 17 00:00:00 2001 From: Christophe Riccio Date: Mon, 5 Dec 2011 18:08:43 +0000 Subject: [PATCH] Fixed MinGW roundEven bug --- glm/core/func_common.inl | 21 ++++++++-- glm/glm.hpp | 1 + test/core/core_func_common.cpp | 71 +++++++++++++++++++++++++++++++--- test/gtx/gtx_integer.cpp | 2 +- 4 files changed, 86 insertions(+), 9 deletions(-) diff --git a/glm/core/func_common.inl b/glm/core/func_common.inl index 35186345..5bdd9b76 100644 --- a/glm/core/func_common.inl +++ b/glm/core/func_common.inl @@ -146,6 +146,7 @@ namespace detail return genType(int(x + genType(int(x) % 2))); } */ + // roundEven template GLM_FUNC_QUALIFIER genType roundEven(genType const & x) @@ -157,11 +158,25 @@ namespace detail genType FractionalPart = fract(x); if(FractionalPart > genType(0.5) || FractionalPart < genType(0.5)) + { return round(x); - else if(!(Integer % 2)) + } + else if((Integer % 2) == 0) + { return IntegerPart; + } + else if(x <= genType(0)) // Work around... + { + return IntegerPart - 1; + } else - return IntegerPart + mix(genType(-1), genType(1), x >= genType(0)); + { + return IntegerPart + 1; + } + //else // Bug on MinGW 4.5.2 + //{ + // return mix(IntegerPart + genType(-1), IntegerPart + genType(1), x <= genType(0)); + //} } VECTORIZE_VEC(roundEven) @@ -521,7 +536,7 @@ namespace detail ( genType const & x, genType const & y, - bool a + bool const & a ) { GLM_STATIC_ASSERT(detail::type::is_float, "'mix' only accept floating-point inputs"); diff --git a/glm/glm.hpp b/glm/glm.hpp index 7d1055df..00c147f0 100644 --- a/glm/glm.hpp +++ b/glm/glm.hpp @@ -84,6 +84,7 @@ #include #include #include +#include //#include #include "core/setup.hpp" diff --git a/test/core/core_func_common.cpp b/test/core/core_func_common.cpp index 32b9189b..13d3face 100644 --- a/test/core/core_func_common.cpp +++ b/test/core/core_func_common.cpp @@ -9,6 +9,7 @@ #include #include +#include int test_modf() { @@ -209,10 +210,70 @@ int test_round() int test_roundEven() { int Error = 0; - + { float A = glm::roundEven(-1.5f); - Error += A == -2.0f ? 0 : 1; + Error += glm::equalEpsilon(A, -2.0f, 0.0001f) ? 0 : 1; + Error += 0; + } + { + float A = glm::roundEven(1.5f); + Error += glm::equalEpsilon(A, 2.0f, 0.0001f) ? 0 : 1; + Error += 0; + } + + { + float A = glm::roundEven(-3.5f); + Error += glm::equalEpsilon(A, -4.0f, 0.0001f) ? 0 : 1; + Error += 0; + } + { + float A = glm::roundEven(3.5f); + Error += glm::equalEpsilon(A, 4.0f, 0.0001f) ? 0 : 1; + Error += 0; + } + + { + float A = glm::roundEven(-2.5f); + Error += glm::equalEpsilon(A, -2.0f, 0.0001f) ? 0 : 1; + Error += 0; + } + { + float A = glm::roundEven(2.5f); + Error += glm::equalEpsilon(A, 2.0f, 0.0001f) ? 0 : 1; + Error += 0; + } + + { + float A = glm::roundEven(-2.4f); + Error += glm::equalEpsilon(A, -2.0f, 0.0001f) ? 0 : 1; + Error += 0; + } + { + float A = glm::roundEven(2.4f); + Error += glm::equalEpsilon(A, 2.0f, 0.0001f) ? 0 : 1; + Error += 0; + } + + { + float A = glm::roundEven(-2.6f); + Error += glm::equalEpsilon(A, -3.0f, 0.0001f) ? 0 : 1; + Error += 0; + } + { + float A = glm::roundEven(2.6f); + Error += glm::equalEpsilon(A, 3.0f, 0.0001f) ? 0 : 1; + Error += 0; + } + + { + float A = glm::roundEven(-2.0f); + Error += glm::equalEpsilon(A, -2.0f, 0.0001f) ? 0 : 1; + Error += 0; + } + { + float A = glm::roundEven(2.0f); + Error += glm::equalEpsilon(A, 2.0f, 0.0001f) ? 0 : 1; Error += 0; } @@ -232,7 +293,7 @@ int test_roundEven() float G = glm::roundEven(1.9f); Error += G == 2.0f ? 0 : 1; } - + { float A = glm::roundEven(-0.0f); Error += A == 0.0f ? 0 : 1; @@ -249,7 +310,7 @@ int test_roundEven() float G = glm::roundEven(-1.9f); Error += G == -2.0f ? 0 : 1; } - + { float A = glm::roundEven(1.5f); Error += A == 2.0f ? 0 : 1; @@ -283,7 +344,7 @@ int test_roundEven() float G = glm::roundEven(-7.5f); Error += G == -8.0f ? 0 : 1; } - + return Error; } diff --git a/test/gtx/gtx_integer.cpp b/test/gtx/gtx_integer.cpp index 1a77db3f..5d115cbb 100644 --- a/test/gtx/gtx_integer.cpp +++ b/test/gtx/gtx_integer.cpp @@ -19,7 +19,7 @@ int test_floor_log2() for(std::size_t i = 1; i < 1000000; ++i) { glm::uint A = glm::floor_log2(glm::uint(i)); - glm::uint B = glm::uint(glm::log2(double(i))); // Will fail with float, lack of accuracy + glm::uint B = glm::uint(glm::floor(glm::log2(double(i)))); // Will fail with float, lack of accuracy Error += A == B ? 0 : 1; assert(!Error);