[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi-commits] [lmi] master 7f767c85 1/5: Make signed zeros easy to disti
From: |
Greg Chicares |
Subject: |
[lmi-commits] [lmi] master 7f767c85 1/5: Make signed zeros easy to distinguish in tests |
Date: |
Thu, 2 Jun 2022 20:13:04 -0400 (EDT) |
branch: master
commit 7f767c854200710c5f8be427a30a575a88e35a45
Author: Gregory W. Chicares <gchicares@sbcglobal.net>
Commit: Gregory W. Chicares <gchicares@sbcglobal.net>
Make signed zeros easy to distinguish in tests
---
math_functions.hpp | 20 ++++++++++++++++++++
math_functions_test.cpp | 46 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 66 insertions(+)
diff --git a/math_functions.hpp b/math_functions.hpp
index 30f43f99..dcf6cc96 100644
--- a/math_functions.hpp
+++ b/math_functions.hpp
@@ -96,6 +96,26 @@ inline T outward_quotient(T numerator, T denominator)
return (0 < numerator == 0 < denominator) ? x + y : x - y;
}
+/// Signed zeros, for comparison tests.
+
+enum signed_zero
+ {pos0 // positive zero
+ ,neg0 // negative zero
+ };
+
+template<typename T>
+bool operator==(T t, signed_zero z)
+{
+ static_assert(std::is_floating_point_v<T>);
+ bool const st = std::signbit(t);
+ bool const sz =
+ (pos0 == z) ? false
+ : (neg0 == z) ? true
+ : throw std::domain_error("outside signed_zero domain")
+ ;
+ return T(0) == t && sz == st;
+}
+
/// Algebraic sign of argument.
///
/// Return value is of same type as argument, as for many members
diff --git a/math_functions_test.cpp b/math_functions_test.cpp
index acddfa28..f291fd8b 100644
--- a/math_functions_test.cpp
+++ b/math_functions_test.cpp
@@ -476,6 +476,50 @@ void test_compound_interest()
);
}
+void test_signed_zero()
+{
+ constexpr double inf {std::numeric_limits<double>::infinity ()};
+ constexpr double qnan {std::numeric_limits<double>::quiet_NaN()};
+
+ LMI_TEST(pos0 == pos0);
+ LMI_TEST(pos0 != neg0);
+ LMI_TEST(neg0 != pos0);
+ LMI_TEST(neg0 == neg0);
+
+ LMI_TEST(pos0 == 0.0);
+ LMI_TEST( 0.0 == pos0);
+ LMI_TEST(pos0 != -0.0);
+ LMI_TEST(-0.0 != pos0);
+
+ LMI_TEST(neg0 != 0.0);
+ LMI_TEST( 0.0 != neg0);
+ LMI_TEST(neg0 == -0.0);
+ LMI_TEST(-0.0 == neg0);
+
+ LMI_TEST(pos0 != qnan);
+ LMI_TEST(qnan != pos0);
+ LMI_TEST(neg0 != qnan);
+ LMI_TEST(qnan != neg0);
+
+ LMI_TEST(pos0 != inf);
+ LMI_TEST( inf != pos0);
+ LMI_TEST(pos0 != -inf);
+ LMI_TEST(-inf != pos0);
+
+ LMI_TEST(neg0 != inf);
+ LMI_TEST( inf != neg0);
+ LMI_TEST(neg0 != -inf);
+ LMI_TEST(-inf != neg0);
+
+ LMI_TEST(pos0 != 1.0);
+ LMI_TEST(neg0 != 1.0);
+
+ // These intentionally do not compile:
+// LMI_TEST(pos0 == 0);
+// LMI_TEST(pos0 == '0');
+// LMI_TEST(pos0 == nullptr);
+}
+
template<typename T>
void test_signum(char const* file, int line)
{
@@ -727,6 +771,8 @@ int test_main(int, char*[])
test_compound_interest();
+ test_signed_zero();
+
test_signum<bool >(__FILE__, __LINE__);
test_signum<signed char >(__FILE__, __LINE__);
test_signum<unsigned char>(__FILE__, __LINE__);