From 5df433b4ea5e657079e5d5e7305dc06b0331beeb Mon Sep 17 00:00:00 2001 From: Zbigniew Sarbinowski Date: Mon, 29 Jul 2024 14:01:36 +0000 Subject: [PATCH 1/5] Fix hermite.pass.cpp for HEX float on z/OS --- libcxx/test/std/numerics/c.math/hermite.pass.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/libcxx/test/std/numerics/c.math/hermite.pass.cpp b/libcxx/test/std/numerics/c.math/hermite.pass.cpp index 08fbd5c3283c1..fb702369ad036 100644 --- a/libcxx/test/std/numerics/c.math/hermite.pass.cpp +++ b/libcxx/test/std/numerics/c.math/hermite.pass.cpp @@ -26,7 +26,12 @@ #include "type_algorithms.h" -inline constexpr unsigned g_max_n = 128; +inline constexpr unsigned g_max_n = +#if !(defined(__MVS__) && !defined(__BFP__)) + 128; +#else + 39; +#endif template std::array sample_points() { @@ -203,6 +208,7 @@ std::vector get_roots(unsigned n) { template void test() { +#if !(defined(__MVS__) && !defined(__BFP__)) { // checks if NaNs are reported correctly (i.e. output == input for input == NaN) using nl = std::numeric_limits; for (Real NaN : {nl::quiet_NaN(), nl::signaling_NaN()}) @@ -215,6 +221,7 @@ void test() { for (unsigned n = 0; n < g_max_n; ++n) assert(!std::isnan(std::hermite(n, x))); } +#endif { // checks std::hermite(n, x) for n=0..5 against analytic polynoms const auto h0 = [](Real) -> Real { return 1; }; @@ -289,6 +296,7 @@ void test() { } } +#if !(defined(__MVS__) && !defined(__BFP__)) { // check input infinity is handled correctly Real inf = std::numeric_limits::infinity(); for (unsigned n = 1; n < g_max_n; ++n) { @@ -316,6 +324,7 @@ void test() { } } } +#endif } struct TestFloat { From 75025ad1b8fd35537bd3fa5e862fefe76b2fd446 Mon Sep 17 00:00:00 2001 From: Zbigniew Sarbinowski Date: Mon, 29 Jul 2024 14:51:25 +0000 Subject: [PATCH 2/5] clang-format change --- libcxx/test/std/numerics/c.math/hermite.pass.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libcxx/test/std/numerics/c.math/hermite.pass.cpp b/libcxx/test/std/numerics/c.math/hermite.pass.cpp index fb702369ad036..2da2b0b5224af 100644 --- a/libcxx/test/std/numerics/c.math/hermite.pass.cpp +++ b/libcxx/test/std/numerics/c.math/hermite.pass.cpp @@ -28,9 +28,9 @@ inline constexpr unsigned g_max_n = #if !(defined(__MVS__) && !defined(__BFP__)) - 128; + 128; #else - 39; + 39; #endif template From b4ece9122d33080c511dd44aca053d41d2c3ad9c Mon Sep 17 00:00:00 2001 From: Zbigniew Sarbinowski Date: Wed, 31 Jul 2024 21:35:10 +0000 Subject: [PATCH 3/5] eliminating #if directives and code formatting --- .../test/std/numerics/c.math/hermite.pass.cpp | 49 ++++++++++--------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/libcxx/test/std/numerics/c.math/hermite.pass.cpp b/libcxx/test/std/numerics/c.math/hermite.pass.cpp index 2da2b0b5224af..28bf27cafc3dd 100644 --- a/libcxx/test/std/numerics/c.math/hermite.pass.cpp +++ b/libcxx/test/std/numerics/c.math/hermite.pass.cpp @@ -26,12 +26,13 @@ #include "type_algorithms.h" -inline constexpr unsigned g_max_n = -#if !(defined(__MVS__) && !defined(__BFP__)) - 128; -#else - 39; -#endif +template +constexpr unsigned get_maximal_order() { + if constexpr (std::numeric_limits::max_exponent10 < std::numeric_limits::max_exponent) + return 128; + else + return 39; +} template std::array sample_points() { @@ -208,20 +209,23 @@ std::vector get_roots(unsigned n) { template void test() { -#if !(defined(__MVS__) && !defined(__BFP__)) - { // checks if NaNs are reported correctly (i.e. output == input for input == NaN) + if constexpr ( + std::numeric_limits::has_quiet_NaN && + std::numeric_limits< + Real>::has_signaling_NaN) { // checks if NaNs are reported correctly (i.e. output == input for input == NaN) using nl = std::numeric_limits; for (Real NaN : {nl::quiet_NaN(), nl::signaling_NaN()}) - for (unsigned n = 0; n < g_max_n; ++n) + for (unsigned n = 0; n < get_maximal_order(); ++n) assert(std::isnan(std::hermite(n, NaN))); } - { // simple sample points for n=0..127 should not produce NaNs. + if constexpr (std::numeric_limits::has_quiet_NaN && + std::numeric_limits< + Real>::has_signaling_NaN) { // simple sample points for n=0..127 should not produce NaNs. for (Real x : sample_points()) - for (unsigned n = 0; n < g_max_n; ++n) + for (unsigned n = 0; n < get_maximal_order(); ++n) assert(!std::isnan(std::hermite(n, x))); } -#endif { // checks std::hermite(n, x) for n=0..5 against analytic polynoms const auto h0 = [](Real) -> Real { return 1; }; @@ -244,21 +248,21 @@ void test() { { // checks std::hermitef for bitwise equality with std::hermite(unsigned, float) if constexpr (std::is_same_v) - for (unsigned n = 0; n < g_max_n; ++n) + for (unsigned n = 0; n < get_maximal_order(); ++n) for (float x : sample_points()) assert(std::hermite(n, x) == std::hermitef(n, x)); } { // checks std::hermitel for bitwise equality with std::hermite(unsigned, long double) if constexpr (std::is_same_v) - for (unsigned n = 0; n < g_max_n; ++n) + for (unsigned n = 0; n < get_maximal_order(); ++n) for (long double x : sample_points()) assert(std::hermite(n, x) == std::hermitel(n, x)); } { // Checks if the characteristic recurrence relation holds: H_{n+1}(x) = 2x H_n(x) - 2n H_{n-1}(x) for (Real x : sample_points()) { - for (unsigned n = 1; n < g_max_n - 1; ++n) { + for (unsigned n = 1; n < get_maximal_order() - 1; ++n) { Real H_next = std::hermite(n + 1, x); Real H_next_recurrence = 2 * (x * std::hermite(n, x) - n * std::hermite(n - 1, x)); @@ -296,23 +300,23 @@ void test() { } } -#if !(defined(__MVS__) && !defined(__BFP__)) - { // check input infinity is handled correctly + if constexpr (std::numeric_limits::has_infinity) { // check input infinity is handled correctly Real inf = std::numeric_limits::infinity(); - for (unsigned n = 1; n < g_max_n; ++n) { + for (unsigned n = 1; n < get_maximal_order(); ++n) { assert(std::hermite(n, +inf) == inf); assert(std::hermite(n, -inf) == ((n & 1) ? -inf : inf)); } } - { // check: if overflow occurs that it is mapped to the correct infinity + if constexpr (std::numeric_limits< + Real>::has_infinity) { // check: if overflow occurs that it is mapped to the correct infinity if constexpr (std::is_same_v) { // Q: Why only double? // A: The numeric values (e.g. overflow threshold `n`) below are different for other types. static_assert(sizeof(double) == 8); - for (unsigned n = 0; n < g_max_n; ++n) { + for (unsigned n = 0; n < get_maximal_order(); ++n) { // Q: Why n=111 and x=300? - // A: Both are chosen s.t. the first overlow occurs for some `n()`. if (n < 111) { assert(std::isfinite(std::hermite(n, +300.0))); assert(std::isfinite(std::hermite(n, -300.0))); @@ -324,7 +328,6 @@ void test() { } } } -#endif } struct TestFloat { @@ -338,7 +341,7 @@ struct TestInt { template void operator()() { // checks that std::hermite(unsigned, Integer) actually wraps std::hermite(unsigned, double) - for (unsigned n = 0; n < g_max_n; ++n) + for (unsigned n = 0; n < get_maximal_order(); ++n) for (Integer x : {-42, -7, -5, -1, 0, 1, 5, 7, 42}) assert(std::hermite(n, x) == std::hermite(n, static_cast(x))); } From 112f3d98a0caa308cc5ad5551a33fae74cbca368 Mon Sep 17 00:00:00 2001 From: Zbigniew Sarbinowski Date: Thu, 1 Aug 2024 18:36:45 +0000 Subject: [PATCH 4/5] Addressing comments ... --- libcxx/test/std/numerics/c.math/hermite.pass.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libcxx/test/std/numerics/c.math/hermite.pass.cpp b/libcxx/test/std/numerics/c.math/hermite.pass.cpp index 28bf27cafc3dd..4b58d9170bdd8 100644 --- a/libcxx/test/std/numerics/c.math/hermite.pass.cpp +++ b/libcxx/test/std/numerics/c.math/hermite.pass.cpp @@ -28,10 +28,12 @@ template constexpr unsigned get_maximal_order() { - if constexpr (std::numeric_limits::max_exponent10 < std::numeric_limits::max_exponent) + if constexpr (std::numeric_limits::max_exponent < 64) + return 39; + else if constexpr (std::numeric_limits::max_exponent < 129) return 128; else - return 39; + return 1024; } template From 8dfb341ca0cbc684a54e6f34b29f9ac4de772b50 Mon Sep 17 00:00:00 2001 From: Zbigniew Sarbinowski Date: Fri, 2 Aug 2024 20:42:23 +0000 Subject: [PATCH 5/5] more comments... --- libcxx/test/std/numerics/c.math/hermite.pass.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/libcxx/test/std/numerics/c.math/hermite.pass.cpp b/libcxx/test/std/numerics/c.math/hermite.pass.cpp index 4b58d9170bdd8..4283cbfd7bc18 100644 --- a/libcxx/test/std/numerics/c.math/hermite.pass.cpp +++ b/libcxx/test/std/numerics/c.math/hermite.pass.cpp @@ -28,12 +28,13 @@ template constexpr unsigned get_maximal_order() { - if constexpr (std::numeric_limits::max_exponent < 64) - return 39; - else if constexpr (std::numeric_limits::max_exponent < 129) + if constexpr (std::numeric_limits::is_iec559) return 128; - else - return 1024; + else { // Workaround for z/OS HexFloat. + // Note |H_n(x)| < 10^75 for n < 39 and x in sample_points(). + static_assert(std::numeric_limits::max_exponent10 == 75); + return 39; + } } template