Added vector retionnal with max ULPs arguments

This commit is contained in:
Christophe Riccio 2018-09-17 18:46:02 +02:00
parent e5d6b1c64b
commit 311f59ed7e
4 changed files with 92 additions and 16 deletions

View File

@ -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

View File

@ -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 glm
namespace detail
{ {
// 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)
{ {

View File

@ -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

View File

@ -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