lmi-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lmi-commits] [lmi] master 32a2f4b6 3/5: Add tests inspired by C99 Annex


From: Greg Chicares
Subject: [lmi-commits] [lmi] master 32a2f4b6 3/5: Add tests inspired by C99 Annex F
Date: Thu, 2 Jun 2022 20:13:04 -0400 (EDT)

branch: master
commit 32a2f4b679a287619c284730e7bd36cef02acc37
Author: Gregory W. Chicares <gchicares@sbcglobal.net>
Commit: Gregory W. Chicares <gchicares@sbcglobal.net>

    Add tests inspired by C99 Annex F
    
    The test with an exponent equal to INT_MIN has undefined behavior;
    that must be corrected illico presto.
---
 bin_exp_test.cpp | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 81 insertions(+), 5 deletions(-)

diff --git a/bin_exp_test.cpp b/bin_exp_test.cpp
index b3c37792..dd0416e4 100644
--- a/bin_exp_test.cpp
+++ b/bin_exp_test.cpp
@@ -34,7 +34,12 @@
 
 namespace
 {
-    constexpr auto inf {std::numeric_limits<double>::infinity()};
+    constexpr auto inf  {std::numeric_limits<double>::infinity ()};
+    constexpr auto qnan {std::numeric_limits<double>::quiet_NaN()};
+
+    constexpr double e     {2.71828'18284'59045'23536};
+    constexpr double e_sq  {7.38905'60989'30650'22723};
+    constexpr double e_101 {7.30705'99793'68067'27265e43};
 } // Unnamed namespace.
 
 void test_systematically()
@@ -70,10 +75,6 @@ void test_systematically()
 
     // powers of e
 
-    constexpr double e     = 2.71828'18284'59045'23536;
-    constexpr double e_sq  = 7.38905'60989'30650'22723;
-    constexpr double e_101 = 7.30705'99793'68067'27265e43;
-
     LMI_TEST_EQUAL(     1.0, bin_exp( e,  0));
     LMI_TEST_EQUAL(     1.0, bin_exp(-e,  0));
     LMI_TEST_EQUAL(     1.0, bin_exp( e, -0));
@@ -106,6 +107,80 @@ void test_systematically()
     LMI_TEST_EQUAL(    neg0, bin_exp(-e, -999));
 }
 
+/// C99 F.9.4.4 rules for pow(), omitting cases incompatible
+/// with a finite non-NaN integer exponent.
+
+void test_C99_F_9_4_4_rules()
+{
+    // (±0)^y = ±∞, y odd and negative
+
+    LMI_TEST_EQUAL(     inf, bin_exp( 0.0, -3));
+    LMI_TEST_EQUAL(    -inf, bin_exp(-0.0, -3));
+
+    // (±0)^y = +∞, y even and negative
+
+    LMI_TEST_EQUAL(     inf, bin_exp( 0.0, -4));
+    LMI_TEST_EQUAL(     inf, bin_exp(-0.0, -4));
+
+    // (±0)^y = ±0, y odd and positive
+
+    LMI_TEST_EQUAL(    pos0, bin_exp( 0.0,  3));
+    LMI_TEST_EQUAL(    neg0, bin_exp(-0.0,  3));
+
+    // (±0)^y = +0, y even and positive
+
+    LMI_TEST_EQUAL(    pos0, bin_exp( 0.0,  4));
+    LMI_TEST_EQUAL(    pos0, bin_exp(-0.0,  4));
+
+    // 1^y = 1, for all y
+
+    LMI_TEST_EQUAL(     1.0, bin_exp( 1.0, INT_MIN));
+    LMI_TEST_EQUAL(     1.0, bin_exp( 1.0, -2));
+    LMI_TEST_EQUAL(     1.0, bin_exp( 1.0, -1));
+    LMI_TEST_EQUAL(     1.0, bin_exp( 1.0,  0));
+    LMI_TEST_EQUAL(     1.0, bin_exp( 1.0,  1));
+    LMI_TEST_EQUAL(     1.0, bin_exp( 1.0,  2));
+    LMI_TEST_EQUAL(     1.0, bin_exp( 1.0, INT_MAX));
+
+    // x^0 = 1, for all x, even a NaN
+
+    LMI_TEST_EQUAL(     1.0, bin_exp(-inf,  0));
+    LMI_TEST_EQUAL(     1.0, bin_exp(  -e,  0));
+    LMI_TEST_EQUAL(     1.0, bin_exp(-1.0,  0));
+    LMI_TEST_EQUAL(     1.0, bin_exp(-0.0,  0));
+    LMI_TEST_EQUAL(     1.0, bin_exp( 0.0,  0));
+    LMI_TEST_EQUAL(     1.0, bin_exp( 1.0,  0));
+    LMI_TEST_EQUAL(     1.0, bin_exp(   e,  0));
+    LMI_TEST_EQUAL(     1.0, bin_exp( inf,  0));
+    LMI_TEST_EQUAL(     1.0, bin_exp(qnan,  0));
+
+    // pow(-∞, y) = -0, y odd and negative
+
+    LMI_TEST_EQUAL(    neg0, bin_exp(-inf, -3));
+
+    // pow(-∞, y) = +0, y even and negative
+
+    LMI_TEST_EQUAL(    pos0, bin_exp(-inf, -4));
+
+    // pow(-∞, y) = -∞, y odd and positive
+
+    LMI_TEST_EQUAL(    -inf, bin_exp(-inf,  3));
+
+    // pow(-∞, y) = +∞, y even and positive
+
+    LMI_TEST_EQUAL(     inf, bin_exp(-inf,  4));
+
+    // pow(+∞ , y) = +0, y negative
+
+    LMI_TEST_EQUAL(    pos0, bin_exp( inf, -3));
+    LMI_TEST_EQUAL(    pos0, bin_exp( inf, -4));
+
+    // pow(+∞ , y) = +∞, y positive
+
+    LMI_TEST_EQUAL(     inf, bin_exp( inf,  3));
+    LMI_TEST_EQUAL(     inf, bin_exp( inf,  4));
+}
+
 void test_integral_powers_of_two()
 {
     //                        00000000011111111
@@ -321,6 +396,7 @@ int test_main(int, char*[])
     std::cout.precision(DECIMAL_DIG);
 
     test_systematically();
+    test_C99_F_9_4_4_rules();
     test_integral_powers_of_two();
     test_integral_powers_of_ten();
     test_quodlibet();



reply via email to

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