فهرست منبع

Fixed MinGW roundEven bug

Christophe Riccio 14 سال پیش
والد
کامیت
dd244d8d25
4فایلهای تغییر یافته به همراه86 افزوده شده و 9 حذف شده
  1. 18 3
      glm/core/func_common.inl
  2. 1 0
      glm/glm.hpp
  3. 66 5
      test/core/core_func_common.cpp
  4. 1 1
      test/gtx/gtx_integer.cpp

+ 18 - 3
glm/core/func_common.inl

@@ -146,6 +146,7 @@ namespace detail
 		return genType(int(x + genType(int(x) % 2)));
     }
 */
+	
     // roundEven
     template <typename genType>
     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<genType>::is_float, "'mix' only accept floating-point inputs");

+ 1 - 0
glm/glm.hpp

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

+ 66 - 5
test/core/core_func_common.cpp

@@ -9,6 +9,7 @@
 
 #include <glm/glm.hpp>
 #include <glm/gtx/epsilon.hpp>
+#include <cstdio>
 
 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;
 }
 

+ 1 - 1
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);