fix approx<float> with epsilon

This commit is contained in:
BlackMATov
2021-02-28 12:50:05 +07:00
parent 093416ceee
commit c1cb6cba78
2 changed files with 16 additions and 13 deletions

View File

@@ -393,6 +393,12 @@ namespace vmath_hpp
return !!x;
}
template < typename T >
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, bool>
constexpr approx(T x, T y, T epsilon) noexcept {
return abs(x - y) <= epsilon;
}
template < typename T >
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, bool>
constexpr approx(T x, T y) noexcept {
@@ -400,24 +406,12 @@ namespace vmath_hpp
/// REFERENCE:
/// http://www.realtimecollisiondetection.net/pubs/Tolerances
const T epsilon = std::numeric_limits<T>::epsilon();
return abs(x - y) <= epsilon * max(max(T{1}, abs(x)), abs(y));
return approx(x, y, epsilon * max(T{1}, max(abs(x), abs(y))));
} else {
return x == y;
}
}
template < typename T >
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, bool>
constexpr approx(T x, T y, T epsilon) noexcept {
if constexpr ( std::is_floating_point_v<T> ) {
/// REFERENCE:
/// http://www.realtimecollisiondetection.net/pubs/Tolerances
return abs(x - y) <= epsilon * max(max(T{1}, abs(x)), abs(y));
} else {
return abs(x - y) <= epsilon;
}
}
template < typename T >
[[nodiscard]] std::enable_if_t<std::is_arithmetic_v<T>, bool>
constexpr less(T x, T y) noexcept {

View File

@@ -151,6 +151,15 @@ TEST_CASE("vmath/fun") {
STATIC_CHECK_FALSE(approx(0, 1));
STATIC_CHECK_FALSE(approx(0, 1, 0));
STATIC_CHECK(approx(0, 1, 1));
STATIC_CHECK_FALSE(approx(1, 3, 1));
STATIC_CHECK(approx(1, 3, 2));
STATIC_CHECK(approx(1.f, 1.f));
STATIC_CHECK_FALSE(approx(0.f, 1.f));
STATIC_CHECK_FALSE(approx(0.f, 1.f, 0.f));
STATIC_CHECK(approx(0.f, 1.f, 1.f));
STATIC_CHECK_FALSE(approx(1.f, 3.f, 1.f));
STATIC_CHECK(approx(1.f, 3.f, 2.f));
STATIC_CHECK(approx(1.f, 1.f + std::numeric_limits<float>::epsilon() * 0.5f));
STATIC_CHECK_FALSE(approx(1.f, 1.f + std::numeric_limits<float>::epsilon() * 1.5f));