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