From c1cb6cba782c4e2e8dabf7d22f97f2dadf53add6 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 28 Feb 2021 12:50:05 +0700 Subject: [PATCH] fix approx with epsilon --- headers/vmath.hpp/vmath_fun.hpp | 20 +++++++------------- untests/vmath_fun_tests.cpp | 9 +++++++++ 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/headers/vmath.hpp/vmath_fun.hpp b/headers/vmath.hpp/vmath_fun.hpp index f155291..88b9b61 100644 --- a/headers/vmath.hpp/vmath_fun.hpp +++ b/headers/vmath.hpp/vmath_fun.hpp @@ -393,6 +393,12 @@ namespace vmath_hpp return !!x; } + template < typename T > + [[nodiscard]] std::enable_if_t, bool> + constexpr approx(T x, T y, T epsilon) noexcept { + return abs(x - y) <= epsilon; + } + template < typename T > [[nodiscard]] std::enable_if_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::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, bool> - constexpr approx(T x, T y, T epsilon) noexcept { - if constexpr ( std::is_floating_point_v ) { - /// 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, bool> constexpr less(T x, T y) noexcept { diff --git a/untests/vmath_fun_tests.cpp b/untests/vmath_fun_tests.cpp index 4bb37e9..609e966 100644 --- a/untests/vmath_fun_tests.cpp +++ b/untests/vmath_fun_tests.cpp @@ -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::epsilon() * 0.5f)); STATIC_CHECK_FALSE(approx(1.f, 1.f + std::numeric_limits::epsilon() * 1.5f));