From 95c9f0a1c43612a79f7ec2912bede7fe27d1270f Mon Sep 17 00:00:00 2001 From: =?utf8?q?=EB=B0=95=EC=A2=85=ED=98=84/=EB=8F=99=EC=9E=91=EC=A0=9C?= =?utf8?q?=EC=96=B4Lab=28SR=29/Senior=20Engineer/=EC=82=BC=EC=84=B1?= =?utf8?q?=EC=A0=84=EC=9E=90?= Date: Fri, 18 May 2018 09:08:54 +0900 Subject: [PATCH] [nncc.foundation] Add 'relative_epsilon_equal' (#227) This commit introduces nncc::foundation::math::relative_epsilon_equal, which compares two float values and returns true if their relative diff is less than a specified threshold expressed as a multiple of machine epsilon. Signed-off-by: Jonghyun Park --- .../include/nncc/foundation/math/Float.h | 17 ++++++++++++ libs/foundation/src/math/Float.cpp | 29 +++++++++++++++++++++ libs/foundation/src/math/Float.test.cpp | 30 ++++++++++++++++++++++ 3 files changed, 76 insertions(+) create mode 100644 libs/foundation/include/nncc/foundation/math/Float.h create mode 100644 libs/foundation/src/math/Float.cpp create mode 100644 libs/foundation/src/math/Float.test.cpp diff --git a/libs/foundation/include/nncc/foundation/math/Float.h b/libs/foundation/include/nncc/foundation/math/Float.h new file mode 100644 index 0000000..41626c2 --- /dev/null +++ b/libs/foundation/include/nncc/foundation/math/Float.h @@ -0,0 +1,17 @@ +#ifndef __NNCC_FOUNDATION_MATH_FLOAT_H__ +#define __NNCC_FOUNDATION_MATH_FLOAT_H__ + +namespace nncc +{ +namespace foundation +{ +namespace math +{ + +bool relative_epsilon_equal(float lhs, float rhs, unsigned tolerance = 1); + +} // namespace math +} // namespace foundation +} // namespace nncc + +#endif // __NNCC_FOUNDATION_MATH_FLOAT_H__ diff --git a/libs/foundation/src/math/Float.cpp b/libs/foundation/src/math/Float.cpp new file mode 100644 index 0000000..d51b197 --- /dev/null +++ b/libs/foundation/src/math/Float.cpp @@ -0,0 +1,29 @@ +#include "nncc/foundation/math/Float.h" + +#include +#include +#include + +namespace nncc +{ +namespace foundation +{ +namespace math +{ + +bool relative_epsilon_equal(float lhs, float rhs, unsigned tolerance) +{ + if (std::isnan(lhs) && std::isnan(rhs)) + { + return true; + } + + const auto delta = std::fabs(lhs - rhs); + const auto max = std::max(std::fabs(lhs), std::fabs(rhs)); + + return delta <= (max * FLT_EPSILON * tolerance); +} + +} // namespace math +} // namespace foundation +} // namespace nncc diff --git a/libs/foundation/src/math/Float.test.cpp b/libs/foundation/src/math/Float.test.cpp new file mode 100644 index 0000000..19117af --- /dev/null +++ b/libs/foundation/src/math/Float.test.cpp @@ -0,0 +1,30 @@ +#include + +#include + +#include + +TEST(FOUNDATION_MATH_FLOAT, relative_epsilon_equal_nan_nan) +{ + ASSERT_TRUE(nncc::foundation::math::relative_epsilon_equal(NAN, NAN)); +} + +TEST(FOUNDATION_MATH_FLOAT, relative_epsilon_equal_num_pos) +{ + ASSERT_TRUE(nncc::foundation::math::relative_epsilon_equal(1.0f, 1.0f)); +} + +TEST(FOUNDATION_MATH_FLOAT, relative_epsilon_equal_num_neg) +{ + ASSERT_FALSE(nncc::foundation::math::relative_epsilon_equal(1.0f, 2.0f)); +} + +TEST(FOUNDATION_MATH_FLOAT, relative_epsilon_equal_tolerance_pos) +{ + ASSERT_TRUE(nncc::foundation::math::relative_epsilon_equal(1.0f, 1.0f + FLT_EPSILON, 2)); +} + +TEST(FOUNDATION_MATH_FLOAT, relative_epsilon_equal_tolerance_neg) +{ + ASSERT_FALSE(nncc::foundation::math::relative_epsilon_equal(1.0f, 1.0f + 3 * FLT_EPSILON, 2)); +} -- 2.7.4