Fixed MinGW roundEven bug

This commit is contained in:
Christophe Riccio 2011-12-05 18:08:43 +00:00
parent dad27d9b37
commit dd244d8d25
4 changed files with 86 additions and 9 deletions

View File

@ -146,6 +146,7 @@ namespace detail
return genType(int(x + genType(int(x) % 2))); return genType(int(x + genType(int(x) % 2)));
} }
*/ */
// roundEven // roundEven
template <typename genType> template <typename genType>
GLM_FUNC_QUALIFIER genType roundEven(genType const & x) GLM_FUNC_QUALIFIER genType roundEven(genType const & x)
@ -157,11 +158,25 @@ namespace detail
genType FractionalPart = fract(x); genType FractionalPart = fract(x);
if(FractionalPart > genType(0.5) || FractionalPart < genType(0.5)) if(FractionalPart > genType(0.5) || FractionalPart < genType(0.5))
{
return round(x); return round(x);
else if(!(Integer % 2)) }
else if((Integer % 2) == 0)
{
return IntegerPart; return IntegerPart;
}
else if(x <= genType(0)) // Work around...
{
return IntegerPart - 1;
}
else 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) VECTORIZE_VEC(roundEven)
@ -521,7 +536,7 @@ namespace detail
( (
genType const & x, genType const & x,
genType const & y, genType const & y,
bool a bool const & a
) )
{ {
GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'mix' only accept floating-point inputs"); GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'mix' only accept floating-point inputs");

View File

@ -84,6 +84,7 @@
#include <climits> #include <climits>
#include <cfloat> #include <cfloat>
#include <limits> #include <limits>
#include <cstdio>
//#include <type_traits> //#include <type_traits>
#include "core/setup.hpp" #include "core/setup.hpp"

View File

@ -9,6 +9,7 @@
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <glm/gtx/epsilon.hpp> #include <glm/gtx/epsilon.hpp>
#include <cstdio>
int test_modf() int test_modf()
{ {
@ -212,7 +213,67 @@ int test_roundEven()
{ {
float A = glm::roundEven(-1.5f); 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; Error += 0;
} }

View File

@ -19,7 +19,7 @@ int test_floor_log2()
for(std::size_t i = 1; i < 1000000; ++i) for(std::size_t i = 1; i < 1000000; ++i)
{ {
glm::uint A = glm::floor_log2(glm::uint(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; Error += A == B ? 0 : 1;
assert(!Error); assert(!Error);