Browse Source

Added vector retionnal with max ULPs arguments

Christophe Riccio 7 years ago
parent
commit
311f59ed7e

+ 13 - 0
glm/detail/qualifier.hpp

@@ -206,5 +206,18 @@ namespace detail
 			return genType(1);
 			return genType(1);
 		}
 		}
 	};
 	};
+
+	// https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
+	union float_t
+	{
+		GLM_CONSTEXPR float_t(float Num = 0.0f) : f(Num) {}
+		// Portable extraction of components.
+		GLM_CONSTEXPR bool negative() const { return i < 0; }
+		GLM_CONSTEXPR int mantissa() const { return i & ((1 << 23) - 1); }
+		GLM_CONSTEXPR int exponent() const { return (i >> 23) & 0xFF; }
+
+		int const i;
+		float const f;
+	};
 }//namespace detail
 }//namespace detail
 }//namespace glm
 }//namespace glm

+ 1 - 16
glm/ext/scalar_relational.inl

@@ -2,23 +2,8 @@
 #include "../ext/scalar_int_sized.hpp"
 #include "../ext/scalar_int_sized.hpp"
 #include "../ext/scalar_uint_sized.hpp"
 #include "../ext/scalar_uint_sized.hpp"
 
 
-namespace glm{
-namespace detail
+namespace glm
 {
 {
-	// https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
-	union float_t
-	{
-		GLM_CONSTEXPR float_t(float Num = 0.0f) : f(Num) {}
-		// Portable extraction of components.
-		GLM_CONSTEXPR bool negative() const { return i < 0; }
-		GLM_CONSTEXPR int32 mantissa() const { return i & ((1 << 23) - 1); }
-		GLM_CONSTEXPR int32 exponent() const { return (i >> 23) & 0xFF; }
-
-		int32 const i;
-		float const f;
-	};
-}//namespace detail
-
 	template<typename genType>
 	template<typename genType>
 	GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool equal(genType const& x, genType const& y, genType const& epsilon)
 	GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool equal(genType const& x, genType const& y, genType const& epsilon)
 	{
 	{

+ 36 - 0
glm/ext/vector_relational.hpp

@@ -62,6 +62,42 @@ namespace glm
 	template<length_t L, typename T, qualifier Q>
 	template<length_t L, typename T, qualifier Q>
 	GLM_FUNC_DECL GLM_CONSTEXPR vec<L, bool, Q> notEqual(vec<L, T, Q> const& x, vec<L, T, Q> const& y, vec<L, T, Q> const& epsilon);
 	GLM_FUNC_DECL GLM_CONSTEXPR vec<L, bool, Q> notEqual(vec<L, T, Q> const& x, vec<L, T, Q> const& y, vec<L, T, Q> const& epsilon);
 
 
+	/// Returns the component-wise comparison between two vectors in term of ULPs.
+	/// True if this expression is satisfied.
+	///
+	/// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
+	/// @tparam T Floating-point
+	/// @tparam Q Value from qualifier enum
+	template<length_t L, typename T, qualifier Q>
+	GLM_FUNC_DECL GLM_CONSTEXPR vec<L, bool, Q> equal(vec<L, T, Q> const& x, vec<L, T, Q> const& y, int ULPs);
+
+	/// Returns the component-wise comparison between two vectors in term of ULPs.
+	/// True if this expression is satisfied.
+	///
+	/// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
+	/// @tparam T Floating-point
+	/// @tparam Q Value from qualifier enum
+	template<length_t L, typename T, qualifier Q>
+	GLM_FUNC_DECL GLM_CONSTEXPR vec<L, bool, Q> equal(vec<L, T, Q> const& x, vec<L, T, Q> const& y, vec<L, int, Q> const& ULPs);
+
+	/// Returns the component-wise comparison between two vectors in term of ULPs.
+	/// True if this expression is not satisfied.
+	///
+	/// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
+	/// @tparam T Floating-point
+	/// @tparam Q Value from qualifier enum
+	template<length_t L, typename T, qualifier Q>
+	GLM_FUNC_DECL GLM_CONSTEXPR vec<L, bool, Q> notEqual(vec<L, T, Q> const& x, vec<L, T, Q> const& y, int ULPs);
+
+	/// Returns the component-wise comparison between two vectors in term of ULPs.
+	/// True if this expression is not satisfied.
+	///
+	/// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
+	/// @tparam T Floating-point
+	/// @tparam Q Value from qualifier enum
+	template<length_t L, typename T, qualifier Q>
+	GLM_FUNC_DECL GLM_CONSTEXPR vec<L, bool, Q> notEqual(vec<L, T, Q> const& x, vec<L, T, Q> const& y, vec<L, int, Q> const& ULPs);
+
 	/// @}
 	/// @}
 }//namespace glm
 }//namespace glm
 
 

+ 42 - 0
glm/ext/vector_relational.inl

@@ -27,4 +27,46 @@ namespace glm
 	{
 	{
 		return greaterThan(abs(x - y), Epsilon);
 		return greaterThan(abs(x - y), Epsilon);
 	}
 	}
+
+
+	template<length_t L, typename T, qualifier Q>
+	GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<L, bool, Q> equal(vec<L, T, Q> const& x, vec<L, T, Q> const& y, int MaxULPs)
+	{
+		return equal(x, y, vec<L, int, Q>(MaxULPs));
+	}
+
+	template<length_t L, typename T, qualifier Q>
+	GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<L, bool, Q> equal(vec<L, T, Q> const& x, vec<L, T, Q> const& y, vec<L, int, Q> const& MaxULPs)
+	{
+		vec<L, bool, Q> Result;
+		for(length_t i = 0; i < L; ++i)
+		{
+			detail::float_t const a(x[i]);
+			detail::float_t const b(y[i]);
+
+			// Different signs means they do not match.
+			if(a.negative() != b.negative())
+			{
+				// Check for equality to make sure +0==-0
+				return a.mantissa() == b.mantissa() && a.exponent() == b.exponent();
+			}
+
+			// Find the difference in ULPs.
+			int const DiffULPs = abs(a.i - b.i);
+			Result[i] = DiffULPs <= MaxULPs;
+		}
+		return Result;
+	}
+
+	template<length_t L, typename T, qualifier Q>
+	GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<L, bool, Q> notEqual(vec<L, T, Q> const& x, vec<L, T, Q> const& y, int MaxULPs)
+	{
+		return !equal(x, y, MaxULPs);
+	}
+
+	template<length_t L, typename T, qualifier Q>
+	GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<L, bool, Q> notEqual(vec<L, T, Q> const& x, vec<L, T, Q> const& y, vec<L, int, Q> const& MaxULPs)
+	{
+		return !equal(x, y, MaxULPs);
+	}
 }//namespace glm
 }//namespace glm