lmi-commits
[Top][All Lists]
Advanced

[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__);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]