[nncc.foundation] Add 'relative_epsilon_equal' (#227)
author박종현/동작제어Lab(SR)/Senior Engineer/삼성전자 <jh1302.park@samsung.com>
Fri, 18 May 2018 00:08:54 +0000 (09:08 +0900)
committerGitHub Enterprise <noreply-CODE@samsung.com>
Fri, 18 May 2018 00:08:54 +0000 (09:08 +0900)
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 <jh1302.park@samsung.com>
libs/foundation/include/nncc/foundation/math/Float.h [new file with mode: 0644]
libs/foundation/src/math/Float.cpp [new file with mode: 0644]
libs/foundation/src/math/Float.test.cpp [new file with mode: 0644]

diff --git a/libs/foundation/include/nncc/foundation/math/Float.h b/libs/foundation/include/nncc/foundation/math/Float.h
new file mode 100644 (file)
index 0000000..41626c2
--- /dev/null
@@ -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 (file)
index 0000000..d51b197
--- /dev/null
@@ -0,0 +1,29 @@
+#include "nncc/foundation/math/Float.h"
+
+#include <cmath>
+#include <cfloat>
+#include <algorithm>
+
+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 (file)
index 0000000..19117af
--- /dev/null
@@ -0,0 +1,30 @@
+#include <nncc/foundation/math/Float.h>
+
+#include <cmath>
+
+#include <gtest/gtest.h>
+
+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));
+}