diff --git a/libcxx/include/complex b/libcxx/include/complex index df18159595b34..5f6f41abc3d16 100644 --- a/libcxx/include/complex +++ b/libcxx/include/complex @@ -1236,6 +1236,32 @@ _LIBCPP_HIDE_FROM_ABI complex<_Tp> cosh(const complex<_Tp>& __x) { // tanh +template +_LIBCPP_HIDE_FROM_ABI _Tp __sin2(const _Tp __x) noexcept { + static_assert(std::is_arithmetic<_Tp>::value, "requires an arithmetic type"); + return 2 * std::sin(__x) * std::cos(__x); +} + +template +_LIBCPP_HIDE_FROM_ABI _Tp __sinh2(const _Tp __x) noexcept { + static_assert(std::is_arithmetic<_Tp>::value, "requires an arithmetic type"); + return 2 * std::sinh(__x) * std::cosh(__x); +} + +template +_LIBCPP_HIDE_FROM_ABI _Tp __cos2(const _Tp __x) noexcept { + static_assert(std::is_arithmetic<_Tp>::value, "requires an arithmetic type"); + const _Tp __cos = std::cos(__x); + return 2 * __cos * __cos - 1; +} + +template +_LIBCPP_HIDE_FROM_ABI _Tp __cosh2(const _Tp __x) noexcept { + static_assert(std::is_arithmetic<_Tp>::value, "requires an arithmetic type"); + const _Tp __cosh = std::cosh(__x); + return 2 * __cosh * __cosh - 1; +} + template _LIBCPP_HIDE_FROM_ABI complex<_Tp> tanh(const complex<_Tp>& __x) { if (std::isinf(__x.real())) { @@ -1245,13 +1271,11 @@ _LIBCPP_HIDE_FROM_ABI complex<_Tp> tanh(const complex<_Tp>& __x) { } if (std::isnan(__x.real()) && __x.imag() == 0) return __x; - _Tp __2r(_Tp(2) * __x.real()); - _Tp __2i(_Tp(2) * __x.imag()); - _Tp __d(std::cosh(__2r) + std::cos(__2i)); - _Tp __2rsh(std::sinh(__2r)); + _Tp __d(std::__cosh2(__x.real()) + std::__cos2(__x.imag())); + _Tp __2rsh(std::__sinh2(__x.real())); if (std::isinf(__2rsh) && std::isinf(__d)) - return complex<_Tp>(__2rsh > _Tp(0) ? _Tp(1) : _Tp(-1), __2i > _Tp(0) ? _Tp(0) : _Tp(-0.)); - return complex<_Tp>(__2rsh / __d, std::sin(__2i) / __d); + return complex<_Tp>(__2rsh > _Tp(0) ? _Tp(1) : _Tp(-1), __x.imag() > _Tp(0) ? _Tp(0) : _Tp(-0.)); + return complex<_Tp>(__2rsh / __d, std::__sin2(__x.imag()) / __d); } // asin diff --git a/libcxx/test/std/numerics/complex.number/cases.h b/libcxx/test/std/numerics/complex.number/cases.h index b360e1423ff57..172b5fc939da2 100644 --- a/libcxx/test/std/numerics/complex.number/cases.h +++ b/libcxx/test/std/numerics/complex.number/cases.h @@ -15,184 +15,200 @@ #include #include +#include #include #include "test_macros.h" -TEST_CONSTEXPR_CXX20 const std::complex testcases[] = -{ - std::complex( 1.e-6, 1.e-6), - std::complex(-1.e-6, 1.e-6), - std::complex(-1.e-6, -1.e-6), - std::complex( 1.e-6, -1.e-6), - - std::complex( 1.e+6, 1.e-6), - std::complex(-1.e+6, 1.e-6), - std::complex(-1.e+6, -1.e-6), - std::complex( 1.e+6, -1.e-6), - - std::complex( 1.e-6, 1.e+6), - std::complex(-1.e-6, 1.e+6), - std::complex(-1.e-6, -1.e+6), - std::complex( 1.e-6, -1.e+6), - - std::complex( 1.e+6, 1.e+6), - std::complex(-1.e+6, 1.e+6), - std::complex(-1.e+6, -1.e+6), - std::complex( 1.e+6, -1.e+6), - - std::complex(-0, -1.e-6), - std::complex(-0, 1.e-6), - std::complex(-0, 1.e+6), - std::complex(-0, -1.e+6), - std::complex( 0, -1.e-6), - std::complex( 0, 1.e-6), - std::complex( 0, 1.e+6), - std::complex( 0, -1.e+6), - - std::complex(-1.e-6, -0), - std::complex( 1.e-6, -0), - std::complex( 1.e+6, -0), - std::complex(-1.e+6, -0), - std::complex(-1.e-6, 0), - std::complex( 1.e-6, 0), - std::complex( 1.e+6, 0), - std::complex(-1.e+6, 0), - - std::complex(std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()), - std::complex(-std::numeric_limits::infinity(), std::numeric_limits::quiet_NaN()), - std::complex(-2, std::numeric_limits::quiet_NaN()), - std::complex(-1, std::numeric_limits::quiet_NaN()), - std::complex(-0.5, std::numeric_limits::quiet_NaN()), - std::complex(-0., std::numeric_limits::quiet_NaN()), - std::complex(+0., std::numeric_limits::quiet_NaN()), - std::complex(0.5, std::numeric_limits::quiet_NaN()), - std::complex(1, std::numeric_limits::quiet_NaN()), - std::complex(2, std::numeric_limits::quiet_NaN()), - std::complex(std::numeric_limits::infinity(), std::numeric_limits::quiet_NaN()), - - std::complex(std::numeric_limits::quiet_NaN(), -std::numeric_limits::infinity()), - std::complex(-std::numeric_limits::infinity(), -std::numeric_limits::infinity()), - std::complex(-2, -std::numeric_limits::infinity()), - std::complex(-1, -std::numeric_limits::infinity()), - std::complex(-0.5, -std::numeric_limits::infinity()), - std::complex(-0., -std::numeric_limits::infinity()), - std::complex(+0., -std::numeric_limits::infinity()), - std::complex(0.5, -std::numeric_limits::infinity()), - std::complex(1, -std::numeric_limits::infinity()), - std::complex(2, -std::numeric_limits::infinity()), - std::complex(std::numeric_limits::infinity(), -std::numeric_limits::infinity()), - - std::complex(std::numeric_limits::quiet_NaN(), -2), - std::complex(-std::numeric_limits::infinity(), -2), - std::complex(-2, -2), - std::complex(-1, -2), - std::complex(-0.5, -2), - std::complex(-0., -2), - std::complex(+0., -2), - std::complex(0.5, -2), - std::complex(1, -2), - std::complex(2, -2), - std::complex(std::numeric_limits::infinity(), -2), - - std::complex(std::numeric_limits::quiet_NaN(), -1), - std::complex(-std::numeric_limits::infinity(), -1), - std::complex(-2, -1), - std::complex(-1, -1), - std::complex(-0.5, -1), - std::complex(-0., -1), - std::complex(+0., -1), - std::complex(0.5, -1), - std::complex(1, -1), - std::complex(2, -1), - std::complex(std::numeric_limits::infinity(), -1), - - std::complex(std::numeric_limits::quiet_NaN(), -0.5), - std::complex(-std::numeric_limits::infinity(), -0.5), - std::complex(-2, -0.5), - std::complex(-1, -0.5), - std::complex(-0.5, -0.5), - std::complex(-0., -0.5), - std::complex(+0., -0.5), - std::complex(0.5, -0.5), - std::complex(1, -0.5), - std::complex(2, -0.5), - std::complex(std::numeric_limits::infinity(), -0.5), - - std::complex(std::numeric_limits::quiet_NaN(), -0.), - std::complex(-std::numeric_limits::infinity(), -0.), - std::complex(-2, -0.), - std::complex(-1, -0.), - std::complex(-0.5, -0.), - std::complex(-0., -0.), - std::complex(+0., -0.), - std::complex(0.5, -0.), - std::complex(1, -0.), - std::complex(2, -0.), - std::complex(std::numeric_limits::infinity(), -0.), - - std::complex(std::numeric_limits::quiet_NaN(), +0.), - std::complex(-std::numeric_limits::infinity(), +0.), - std::complex(-2, +0.), - std::complex(-1, +0.), - std::complex(-0.5, +0.), - std::complex(-0., +0.), - std::complex(+0., +0.), - std::complex(0.5, +0.), - std::complex(1, +0.), - std::complex(2, +0.), - std::complex(std::numeric_limits::infinity(), +0.), - - std::complex(std::numeric_limits::quiet_NaN(), 0.5), - std::complex(-std::numeric_limits::infinity(), 0.5), - std::complex(-2, 0.5), - std::complex(-1, 0.5), - std::complex(-0.5, 0.5), - std::complex(-0., 0.5), - std::complex(+0., 0.5), - std::complex(0.5, 0.5), - std::complex(1, 0.5), - std::complex(2, 0.5), - std::complex(std::numeric_limits::infinity(), 0.5), - - std::complex(std::numeric_limits::quiet_NaN(), 1), - std::complex(-std::numeric_limits::infinity(), 1), - std::complex(-2, 1), - std::complex(-1, 1), - std::complex(-0.5, 1), - std::complex(-0., 1), - std::complex(+0., 1), - std::complex(0.5, 1), - std::complex(1, 1), - std::complex(2, 1), - std::complex(std::numeric_limits::infinity(), 1), - - std::complex(std::numeric_limits::quiet_NaN(), 2), - std::complex(-std::numeric_limits::infinity(), 2), - std::complex(-2, 2), - std::complex(-1, 2), - std::complex(-0.5, 2), - std::complex(-0., 2), - std::complex(+0., 2), - std::complex(0.5, 2), - std::complex(1, 2), - std::complex(2, 2), - std::complex(std::numeric_limits::infinity(), 2), - - std::complex(std::numeric_limits::quiet_NaN(), std::numeric_limits::infinity()), - std::complex(-std::numeric_limits::infinity(), std::numeric_limits::infinity()), - std::complex(-2, std::numeric_limits::infinity()), - std::complex(-1, std::numeric_limits::infinity()), - std::complex(-0.5, std::numeric_limits::infinity()), - std::complex(-0., std::numeric_limits::infinity()), - std::complex(+0., std::numeric_limits::infinity()), - std::complex(0.5, std::numeric_limits::infinity()), - std::complex(1, std::numeric_limits::infinity()), - std::complex(2, std::numeric_limits::infinity()), - std::complex(std::numeric_limits::infinity(), std::numeric_limits::infinity()) +template +TEST_CONSTEXPR_CXX20 const std::complex testcases[] = { + std::complex(1.e-6, 1.e-6), + std::complex(-1.e-6, 1.e-6), + std::complex(-1.e-6, -1.e-6), + std::complex(1.e-6, -1.e-6), + + std::complex(1.e+6, 1.e-6), + std::complex(-1.e+6, 1.e-6), + std::complex(-1.e+6, -1.e-6), + std::complex(1.e+6, -1.e-6), + + std::complex(1.e-6, 1.e+6), + std::complex(-1.e-6, 1.e+6), + std::complex(-1.e-6, -1.e+6), + std::complex(1.e-6, -1.e+6), + + std::complex(1.e+6, 1.e+6), + std::complex(-1.e+6, 1.e+6), + std::complex(-1.e+6, -1.e+6), + std::complex(1.e+6, -1.e+6), + + std::complex(-0, -1.e-6), + std::complex(-0, 1.e-6), + std::complex(-0, 1.e+6), + std::complex(-0, -1.e+6), + std::complex(0, -1.e-6), + std::complex(0, 1.e-6), + std::complex(0, 1.e+6), + std::complex(0, -1.e+6), + + std::complex(-1.e-6, -0), + std::complex(1.e-6, -0), + std::complex(1.e+6, -0), + std::complex(-1.e+6, -0), + std::complex(-1.e-6, 0), + std::complex(1.e-6, 0), + std::complex(1.e+6, 0), + std::complex(-1.e+6, 0), + + std::complex(std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()), + std::complex(-std::numeric_limits::infinity(), std::numeric_limits::quiet_NaN()), + std::complex(-2, std::numeric_limits::quiet_NaN()), + std::complex(-1, std::numeric_limits::quiet_NaN()), + std::complex(-0.5, std::numeric_limits::quiet_NaN()), + std::complex(-0., std::numeric_limits::quiet_NaN()), + std::complex(+0., std::numeric_limits::quiet_NaN()), + std::complex(0.5, std::numeric_limits::quiet_NaN()), + std::complex(1, std::numeric_limits::quiet_NaN()), + std::complex(2, std::numeric_limits::quiet_NaN()), + std::complex(std::numeric_limits::infinity(), std::numeric_limits::quiet_NaN()), + + std::complex(std::numeric_limits::quiet_NaN(), -std::numeric_limits::infinity()), + std::complex(-std::numeric_limits::infinity(), -std::numeric_limits::infinity()), + std::complex(-2, -std::numeric_limits::infinity()), + std::complex(-1, -std::numeric_limits::infinity()), + std::complex(-0.5, -std::numeric_limits::infinity()), + std::complex(-0., -std::numeric_limits::infinity()), + std::complex(+0., -std::numeric_limits::infinity()), + std::complex(0.5, -std::numeric_limits::infinity()), + std::complex(1, -std::numeric_limits::infinity()), + std::complex(2, -std::numeric_limits::infinity()), + std::complex(std::numeric_limits::infinity(), -std::numeric_limits::infinity()), + + std::complex(std::numeric_limits::quiet_NaN(), -2), + std::complex(-std::numeric_limits::infinity(), -2), + std::complex(-2, -2), + std::complex(-1, -2), + std::complex(-0.5, -2), + std::complex(-0., -2), + std::complex(+0., -2), + std::complex(0.5, -2), + std::complex(1, -2), + std::complex(2, -2), + std::complex(std::numeric_limits::infinity(), -2), + + std::complex(std::numeric_limits::quiet_NaN(), -1), + std::complex(-std::numeric_limits::infinity(), -1), + std::complex(-2, -1), + std::complex(-1, -1), + std::complex(-0.5, -1), + std::complex(-0., -1), + std::complex(+0., -1), + std::complex(0.5, -1), + std::complex(1, -1), + std::complex(2, -1), + std::complex(std::numeric_limits::infinity(), -1), + + std::complex(std::numeric_limits::quiet_NaN(), -0.5), + std::complex(-std::numeric_limits::infinity(), -0.5), + std::complex(-2, -0.5), + std::complex(-1, -0.5), + std::complex(-0.5, -0.5), + std::complex(-0., -0.5), + std::complex(+0., -0.5), + std::complex(0.5, -0.5), + std::complex(1, -0.5), + std::complex(2, -0.5), + std::complex(std::numeric_limits::infinity(), -0.5), + + std::complex(std::numeric_limits::quiet_NaN(), -0.), + std::complex(-std::numeric_limits::infinity(), -0.), + std::complex(-2, -0.), + std::complex(-1, -0.), + std::complex(-0.5, -0.), + std::complex(-0., -0.), + std::complex(+0., -0.), + std::complex(0.5, -0.), + std::complex(1, -0.), + std::complex(2, -0.), + std::complex(std::numeric_limits::infinity(), -0.), + + std::complex(std::numeric_limits::quiet_NaN(), +0.), + std::complex(-std::numeric_limits::infinity(), +0.), + std::complex(-2, +0.), + std::complex(-1, +0.), + std::complex(-0.5, +0.), + std::complex(-0., +0.), + std::complex(+0., +0.), + std::complex(0.5, +0.), + std::complex(1, +0.), + std::complex(2, +0.), + std::complex(std::numeric_limits::infinity(), +0.), + + std::complex(std::numeric_limits::quiet_NaN(), 0.5), + std::complex(-std::numeric_limits::infinity(), 0.5), + std::complex(-2, 0.5), + std::complex(-1, 0.5), + std::complex(-0.5, 0.5), + std::complex(-0., 0.5), + std::complex(+0., 0.5), + std::complex(0.5, 0.5), + std::complex(1, 0.5), + std::complex(2, 0.5), + std::complex(std::numeric_limits::infinity(), 0.5), + + std::complex(std::numeric_limits::quiet_NaN(), 1), + std::complex(-std::numeric_limits::infinity(), 1), + std::complex(-2, 1), + std::complex(-1, 1), + std::complex(-0.5, 1), + std::complex(-0., 1), + std::complex(+0., 1), + std::complex(0.5, 1), + std::complex(1, 1), + std::complex(2, 1), + std::complex(std::numeric_limits::infinity(), 1), + + std::complex(std::numeric_limits::quiet_NaN(), 2), + std::complex(-std::numeric_limits::infinity(), 2), + std::complex(-2, 2), + std::complex(-1, 2), + std::complex(-0.5, 2), + std::complex(-0., 2), + std::complex(+0., 2), + std::complex(0.5, 2), + std::complex(1, 2), + std::complex(2, 2), + std::complex(std::numeric_limits::infinity(), 2), + + std::complex(std::numeric_limits::quiet_NaN(), std::numeric_limits::infinity()), + std::complex(-std::numeric_limits::infinity(), std::numeric_limits::infinity()), + std::complex(-2, std::numeric_limits::infinity()), + std::complex(-1, std::numeric_limits::infinity()), + std::complex(-0.5, std::numeric_limits::infinity()), + std::complex(-0., std::numeric_limits::infinity()), + std::complex(+0., std::numeric_limits::infinity()), + std::complex(0.5, std::numeric_limits::infinity()), + std::complex(1, std::numeric_limits::infinity()), + std::complex(2, std::numeric_limits::infinity()), + std::complex(std::numeric_limits::infinity(), std::numeric_limits::infinity()), + + std::complex(std::numeric_limits::max(), 1), + std::complex(std::numeric_limits::max(), -1), + std::complex(std::numeric_limits::lowest(), 1), + std::complex(std::numeric_limits::lowest(), -1), + + std::complex(1, std::numeric_limits::max()), + std::complex(1, std::numeric_limits::lowest()), + std::complex(-1, std::numeric_limits::max()), + std::complex(-1, std::numeric_limits::lowest()), + + std::complex(std::numeric_limits::max(), std::numeric_limits::max()), + std::complex(std::numeric_limits::max(), std::numeric_limits::lowest()), + std::complex(std::numeric_limits::lowest(), std::numeric_limits::max()), + std::complex(std::numeric_limits::lowest(), std::numeric_limits::lowest()), }; -enum {zero, non_zero, inf, NaN, non_zero_nan}; +enum { zero, non_zero, lowest_value, maximum_value, inf, NaN, non_zero_nan }; template ::value, int>::type = 0> TEST_CONSTEXPR_CXX20 bool test_isinf(T v) { @@ -227,20 +243,26 @@ classify(const std::complex& x) return NaN; return non_zero_nan; } + if (x.real() == std::numeric_limits::max() || x.imag() == std::numeric_limits::max()) + return maximum_value; + if (x.real() == std::numeric_limits::lowest() || x.imag() == std::numeric_limits::lowest()) + return lowest_value; return non_zero; } -inline -int -classify(double x) -{ - if (x == 0) - return zero; - if (std::isinf(x)) - return inf; - if (std::isnan(x)) - return NaN; - return non_zero; +template +inline int classify(T x) { + if (x == 0) + return zero; + if (std::isinf(x)) + return inf; + if (std::isnan(x)) + return NaN; + if (x == std::numeric_limits::max()) + return maximum_value; + if (x == std::numeric_limits::lowest()) + return lowest_value; + return non_zero; } void is_about(float x, float y) diff --git a/libcxx/test/std/numerics/complex.number/complex.ops/complex_divide_complex.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.ops/complex_divide_complex.pass.cpp index d12dfd994b0ae..b5539f03a6dff 100644 --- a/libcxx/test/std/numerics/complex.number/complex.ops/complex_divide_complex.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.ops/complex_divide_complex.pass.cpp @@ -12,7 +12,7 @@ // complex // operator/(const complex& lhs, const complex& rhs); // constexpr in C++20 -// ADDITIONAL_COMPILE_FLAGS(has-fconstexpr-steps): -fconstexpr-steps=2000000 +// ADDITIONAL_COMPILE_FLAGS(has-fconstexpr-steps): -fconstexpr-steps=2131685 #include #include @@ -34,24 +34,27 @@ test() return true; } -TEST_CONSTEXPR_CXX20 -bool -test_edges() -{ - const unsigned N = sizeof(testcases) / sizeof(testcases[0]); +template +TEST_CONSTEXPR_CXX20 bool test_edges() { + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); int classification[N]; for (unsigned i=0; i < N; ++i) - classification[i] = classify(testcases[i]); + classification[i] = classify(testcases[i]); for (unsigned i = 0; i < N; ++i) { + auto const x = testcases[i]; for (unsigned j = 0; j < N; ++j) { - std::complex r = testcases[i] / testcases[j]; + auto const y = testcases[j]; + std::complex r = x / y; switch (classification[i]) { case zero: switch (classification[j]) { case zero: assert(classify(r) == NaN); break; + case lowest_value: + case maximum_value: + continue; // not tested case non_zero: assert(classify(r) == zero); break; @@ -66,11 +69,17 @@ test_edges() break; } break; + case lowest_value: + case maximum_value: + continue; // not tested case non_zero: switch (classification[j]) { case zero: assert(classify(r) == inf); break; + case lowest_value: + case maximum_value: + continue; // not tested case non_zero: assert(classify(r) == non_zero); break; @@ -90,6 +99,9 @@ test_edges() case zero: assert(classify(r) == inf); break; + case lowest_value: + case maximum_value: + continue; // not tested case non_zero: assert(classify(r) == inf); break; @@ -109,6 +121,9 @@ test_edges() case zero: assert(classify(r) == NaN); break; + case lowest_value: + case maximum_value: + continue; // not tested case non_zero: assert(classify(r) == NaN); break; @@ -128,6 +143,9 @@ test_edges() case zero: assert(classify(r) == inf); break; + case lowest_value: + case maximum_value: + continue; // not tested case non_zero: assert(classify(r) == NaN); break; @@ -153,13 +171,17 @@ int main(int, char**) test(); test(); test(); - test_edges(); + test_edges(); + test_edges(); + test_edges(); #if TEST_STD_VER > 17 static_assert(test()); static_assert(test()); static_assert(test()); - static_assert(test_edges()); + static_assert(test_edges()); + static_assert(test_edges()); + static_assert(test_edges()); #endif return 0; diff --git a/libcxx/test/std/numerics/complex.number/complex.ops/complex_times_complex.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.ops/complex_times_complex.pass.cpp index 817d6cdf492d3..1ab89e13feb02 100644 --- a/libcxx/test/std/numerics/complex.number/complex.ops/complex_times_complex.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.ops/complex_times_complex.pass.cpp @@ -12,7 +12,7 @@ // complex // operator*(const complex& lhs, const complex& rhs); // constexpr in C++20 -// ADDITIONAL_COMPILE_FLAGS(has-fconstexpr-steps): -fconstexpr-steps=2000000 +// ADDITIONAL_COMPILE_FLAGS(has-fconstexpr-steps): -fconstexpr-steps=2131685 #include #include @@ -33,87 +33,95 @@ test() // test edges -TEST_CONSTEXPR_CXX20 bool test_edges() -{ - const unsigned N = sizeof(testcases) / sizeof(testcases[0]); - int classification[N]; - for (unsigned i=0; i < N; ++i) - classification[i] = classify(testcases[i]); +template +TEST_CONSTEXPR_CXX20 bool test_edges() { + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); + int classification[N]; + for (unsigned i = 0; i < N; ++i) + classification[i] = classify(testcases[i]); - for (unsigned i = 0; i < N; ++i) - { - for (unsigned j = 0; j < N; ++j) - { - std::complex r = testcases[i] * testcases[j]; - switch (classification[i]) - { - case zero: - switch (classification[j]) - { - case zero: - case non_zero: - assert(classify(r) == zero); - break; - case inf: - case NaN: - case non_zero_nan: - assert(classify(r) == NaN); - break; - } - break; - case non_zero: - switch (classification[j]) - { - case zero: - assert(classify(r) == zero); - break; - case non_zero: - assert(classify(r) == non_zero); - break; - case inf: - assert(classify(r) == inf); - break; - case NaN: - case non_zero_nan: - assert(classify(r) == NaN); - break; - } - break; - case inf: - switch (classification[j]) - { - case zero: - case NaN: - assert(classify(r) == NaN); - break; - case non_zero: - case inf: - case non_zero_nan: - assert(classify(r) == inf); - break; - } - break; - case NaN: - assert(classify(r) == NaN); - break; - case non_zero_nan: - switch (classification[j]) - { - case inf: - assert(classify(r) == inf); - break; - case zero: - case non_zero: - case NaN: - case non_zero_nan: - assert(classify(r) == NaN); - break; - } - break; - } + for (unsigned i = 0; i < N; ++i) { + for (unsigned j = 0; j < N; ++j) { + std::complex r = testcases[i] * testcases[j]; + switch (classification[i]) { + case zero: + switch (classification[j]) { + case lowest_value: + case maximum_value: + continue; // not tested + case zero: + case non_zero: + assert(classify(r) == zero); + break; + case inf: + case NaN: + case non_zero_nan: + assert(classify(r) == NaN); + break; + } + break; + case lowest_value: + case maximum_value: + continue; // not tested + case non_zero: + switch (classification[j]) { + case zero: + assert(classify(r) == zero); + break; + case lowest_value: + case maximum_value: + continue; // not tested + case non_zero: + assert(classify(r) == non_zero); + break; + case inf: + assert(classify(r) == inf); + break; + case NaN: + case non_zero_nan: + assert(classify(r) == NaN); + break; } + break; + case inf: + switch (classification[j]) { + case zero: + case NaN: + assert(classify(r) == NaN); + break; + case lowest_value: + case maximum_value: + continue; // not tested + case non_zero: + case inf: + case non_zero_nan: + assert(classify(r) == inf); + break; + } + break; + case NaN: + assert(classify(r) == NaN); + break; + case non_zero_nan: + switch (classification[j]) { + case inf: + assert(classify(r) == inf); + break; + case lowest_value: + case maximum_value: + continue; // not tested + case zero: + case non_zero: + case NaN: + case non_zero_nan: + assert(classify(r) == NaN); + break; + } + break; + } } - return true; + } + return true; } int main(int, char**) @@ -121,13 +129,17 @@ int main(int, char**) test(); test(); test(); - test_edges(); + test_edges(); + test_edges(); + test_edges(); #if TEST_STD_VER > 17 static_assert(test()); static_assert(test()); static_assert(test()); - static_assert(test_edges()); + static_assert(test_edges()); + static_assert(test_edges()); + static_assert(test_edges()); #endif return 0; diff --git a/libcxx/test/std/numerics/complex.number/complex.transcendentals/acos.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.transcendentals/acos.pass.cpp index 3158a3bc33d1c..dcf53d64c66da 100644 --- a/libcxx/test/std/numerics/complex.number/complex.transcendentals/acos.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.transcendentals/acos.pass.cpp @@ -32,102 +32,78 @@ test() test(std::complex(INFINITY, 1), std::complex(0, -INFINITY)); } -void test_edges() -{ - const double pi = std::atan2(+0., -0.); - const unsigned N = sizeof(testcases) / sizeof(testcases[0]); - for (unsigned i = 0; i < N; ++i) - { - std::complex r = acos(testcases[i]); - if (testcases[i].real() == 0 && testcases[i].imag() == 0) - { - is_about(r.real(), pi/2); - assert(r.imag() == 0); - assert(std::signbit(testcases[i].imag()) != std::signbit(r.imag())); - } - else if (testcases[i].real() == 0 && std::isnan(testcases[i].imag())) - { - is_about(r.real(), pi/2); - assert(std::isnan(r.imag())); - } - else if (std::isfinite(testcases[i].real()) && std::isinf(testcases[i].imag())) - { - is_about(r.real(), pi/2); - assert(std::isinf(r.imag())); - assert(std::signbit(testcases[i].imag()) != std::signbit(r.imag())); - } - else if (std::isfinite(testcases[i].real()) && testcases[i].real() != 0 && std::isnan(testcases[i].imag())) - { - assert(std::isnan(r.real())); - assert(std::isnan(r.imag())); - } - else if (std::isinf(testcases[i].real()) && testcases[i].real() < 0 && std::isfinite(testcases[i].imag())) - { - is_about(r.real(), pi); - assert(std::isinf(r.imag())); - assert(std::signbit(testcases[i].imag()) != std::signbit(r.imag())); - } - else if (std::isinf(testcases[i].real()) && testcases[i].real() > 0 && std::isfinite(testcases[i].imag())) - { - assert(r.real() == 0); - assert(!std::signbit(r.real())); - assert(std::isinf(r.imag())); - assert(std::signbit(testcases[i].imag()) != std::signbit(r.imag())); - } - else if (std::isinf(testcases[i].real()) && testcases[i].real() < 0 && std::isinf(testcases[i].imag())) - { - is_about(r.real(), 0.75 * pi); - assert(std::isinf(r.imag())); - assert(std::signbit(testcases[i].imag()) != std::signbit(r.imag())); - } - else if (std::isinf(testcases[i].real()) && testcases[i].real() > 0 && std::isinf(testcases[i].imag())) - { - is_about(r.real(), 0.25 * pi); - assert(std::isinf(r.imag())); - assert(std::signbit(testcases[i].imag()) != std::signbit(r.imag())); - } - else if (std::isinf(testcases[i].real()) && std::isnan(testcases[i].imag())) - { - assert(std::isnan(r.real())); - assert(std::isinf(r.imag())); - } - else if (std::isnan(testcases[i].real()) && std::isfinite(testcases[i].imag())) - { - assert(std::isnan(r.real())); - assert(std::isnan(r.imag())); - } - else if (std::isnan(testcases[i].real()) && std::isinf(testcases[i].imag())) - { - assert(std::isnan(r.real())); - assert(std::isinf(r.imag())); - assert(std::signbit(testcases[i].imag()) != std::signbit(r.imag())); - } - else if (std::isnan(testcases[i].real()) && std::isnan(testcases[i].imag())) - { - assert(std::isnan(r.real())); - assert(std::isnan(r.imag())); - } - else if (!std::signbit(testcases[i].real()) && !std::signbit(testcases[i].imag())) - { - assert(!std::signbit(r.real())); - assert( std::signbit(r.imag())); - } - else if (std::signbit(testcases[i].real()) && !std::signbit(testcases[i].imag())) - { - assert(!std::signbit(r.real())); - assert( std::signbit(r.imag())); - } - else if (std::signbit(testcases[i].real()) && std::signbit(testcases[i].imag())) - { - assert(!std::signbit(r.real())); - assert(!std::signbit(r.imag())); - } - else if (!std::signbit(testcases[i].real()) && std::signbit(testcases[i].imag())) - { - assert(!std::signbit(r.real())); - assert(!std::signbit(r.imag())); - } +template +void test_edges() { + const T pi = std::atan2(+0., -0.); + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); + for (unsigned i = 0; i < N; ++i) { + std::complex r = acos(testcases[i]); + if (testcases[i].real() == 0 && testcases[i].imag() == 0) { + is_about(r.real(), pi / 2); + assert(r.imag() == 0); + assert(std::signbit(testcases[i].imag()) != std::signbit(r.imag())); + } else if (testcases[i].real() == 0 && std::isnan(testcases[i].imag())) { + is_about(r.real(), pi / 2); + assert(std::isnan(r.imag())); + } else if (std::isfinite(testcases[i].real()) && std::isinf(testcases[i].imag())) { + is_about(r.real(), pi / 2); + assert(std::isinf(r.imag())); + assert(std::signbit(testcases[i].imag()) != std::signbit(r.imag())); + } else if (std::isfinite(testcases[i].real()) && testcases[i].real() != 0 && + std::isnan(testcases[i].imag())) { + assert(std::isnan(r.real())); + assert(std::isnan(r.imag())); + } else if (std::isinf(testcases[i].real()) && testcases[i].real() < 0 && + std::isfinite(testcases[i].imag())) { + is_about(r.real(), pi); + assert(std::isinf(r.imag())); + assert(std::signbit(testcases[i].imag()) != std::signbit(r.imag())); + } else if (std::isinf(testcases[i].real()) && testcases[i].real() > 0 && + std::isfinite(testcases[i].imag())) { + assert(r.real() == 0); + assert(!std::signbit(r.real())); + assert(std::isinf(r.imag())); + assert(std::signbit(testcases[i].imag()) != std::signbit(r.imag())); + } else if (std::isinf(testcases[i].real()) && testcases[i].real() < 0 && std::isinf(testcases[i].imag())) { + is_about(r.real(), T(0.75) * pi); + assert(std::isinf(r.imag())); + assert(std::signbit(testcases[i].imag()) != std::signbit(r.imag())); + } else if (std::isinf(testcases[i].real()) && testcases[i].real() > 0 && std::isinf(testcases[i].imag())) { + is_about(r.real(), T(0.25) * pi); + assert(std::isinf(r.imag())); + assert(std::signbit(testcases[i].imag()) != std::signbit(r.imag())); + } else if (std::isinf(testcases[i].real()) && std::isnan(testcases[i].imag())) { + assert(std::isnan(r.real())); + assert(std::isinf(r.imag())); + } else if (std::isnan(testcases[i].real()) && std::isfinite(testcases[i].imag())) { + assert(std::isnan(r.real())); + assert(std::isnan(r.imag())); + } else if (std::isnan(testcases[i].real()) && std::isinf(testcases[i].imag())) { + assert(std::isnan(r.real())); + assert(std::isinf(r.imag())); + assert(std::signbit(testcases[i].imag()) != std::signbit(r.imag())); + } else if (std::isnan(testcases[i].real()) && std::isnan(testcases[i].imag())) { + assert(std::isnan(r.real())); + assert(std::isnan(r.imag())); + } else if (!std::signbit(testcases[i].real()) && !std::signbit(testcases[i].imag())) { + assert(!std::signbit(r.real())); + assert(std::signbit(r.imag())); + } else if (std::signbit(testcases[i].real()) && !std::signbit(testcases[i].imag())) { + assert(!std::signbit(r.real())); + assert(std::signbit(r.imag())); + } else if (std::signbit(testcases[i].real()) && std::signbit(testcases[i].imag())) { + assert(!std::signbit(r.real())); + assert(!std::signbit(r.imag())); + } else if (!std::signbit(testcases[i].real()) && std::signbit(testcases[i].imag())) { + assert(!std::signbit(r.real())); + assert(!std::signbit(r.imag())); + } else { + assert(!std::isnan(r.real())); + assert(!std::isnan(r.imag())); + assert(std::signbit(r.real()) == std::signbit(testcases[i].real())); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); } + } } int main(int, char**) @@ -135,7 +111,9 @@ int main(int, char**) test(); test(); test(); - test_edges(); + test_edges(); + test_edges(); + test_edges(); - return 0; + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.transcendentals/acosh.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.transcendentals/acosh.pass.cpp index 424a3b1b82e1a..fe2e0c67cade0 100644 --- a/libcxx/test/std/numerics/complex.number/complex.transcendentals/acosh.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.transcendentals/acosh.pass.cpp @@ -32,113 +32,87 @@ test() test(std::complex(INFINITY, 1), std::complex(INFINITY, 0)); } -void test_edges() -{ - const double pi = std::atan2(+0., -0.); - const unsigned N = sizeof(testcases) / sizeof(testcases[0]); - for (unsigned i = 0; i < N; ++i) - { - std::complex r = acosh(testcases[i]); - if (testcases[i].real() == 0 && testcases[i].imag() == 0) - { - assert(!std::signbit(r.real())); - if (std::signbit(testcases[i].imag())) - is_about(r.imag(), -pi/2); - else - is_about(r.imag(), pi/2); - } - else if (testcases[i].real() == 1 && testcases[i].imag() == 0) - { - assert(r.real() == 0); - assert(!std::signbit(r.real())); - assert(r.imag() == 0); - assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); - } - else if (testcases[i].real() == -1 && testcases[i].imag() == 0) - { - assert(r.real() == 0); - assert(!std::signbit(r.real())); - if (std::signbit(testcases[i].imag())) - is_about(r.imag(), -pi); - else - is_about(r.imag(), pi); - } - else if (std::isfinite(testcases[i].real()) && std::isinf(testcases[i].imag())) - { - assert(std::isinf(r.real())); - assert(r.real() > 0); - if (std::signbit(testcases[i].imag())) - is_about(r.imag(), -pi/2); - else - is_about(r.imag(), pi/2); - } - else if (std::isfinite(testcases[i].real()) && std::isnan(testcases[i].imag())) - { - assert(std::isnan(r.real())); - assert(std::isnan(r.imag())); - } - else if (std::isinf(testcases[i].real()) && testcases[i].real() < 0 && std::isfinite(testcases[i].imag())) - { - assert(std::isinf(r.real())); - assert(r.real() > 0); - if (std::signbit(testcases[i].imag())) - is_about(r.imag(), -pi); - else - is_about(r.imag(), pi); - } - else if (std::isinf(testcases[i].real()) && testcases[i].real() > 0 && std::isfinite(testcases[i].imag())) - { - assert(std::isinf(r.real())); - assert(r.real() > 0); - assert(r.imag() == 0); - assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); - } - else if (std::isinf(testcases[i].real()) && testcases[i].real() < 0 && std::isinf(testcases[i].imag())) - { - assert(std::isinf(r.real())); - assert(r.real() > 0); - if (std::signbit(testcases[i].imag())) - is_about(r.imag(), -0.75 * pi); - else - is_about(r.imag(), 0.75 * pi); - } - else if (std::isinf(testcases[i].real()) && testcases[i].real() > 0 && std::isinf(testcases[i].imag())) - { - assert(std::isinf(r.real())); - assert(r.real() > 0); - if (std::signbit(testcases[i].imag())) - is_about(r.imag(), -0.25 * pi); - else - is_about(r.imag(), 0.25 * pi); - } - else if (std::isinf(testcases[i].real()) && std::isnan(testcases[i].imag())) - { - assert(std::isinf(r.real())); - assert(r.real() > 0); - assert(std::isnan(r.imag())); - } - else if (std::isnan(testcases[i].real()) && std::isfinite(testcases[i].imag())) - { - assert(std::isnan(r.real())); - assert(std::isnan(r.imag())); - } - else if (std::isnan(testcases[i].real()) && std::isinf(testcases[i].imag())) - { - assert(std::isinf(r.real())); - assert(r.real() > 0); - assert(std::isnan(r.imag())); - } - else if (std::isnan(testcases[i].real()) && std::isnan(testcases[i].imag())) - { - assert(std::isnan(r.real())); - assert(std::isnan(r.imag())); - } - else - { - assert(!std::signbit(r.real())); - assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); - } +template +void test_edges() { + const T pi = std::atan2(+0., -0.); + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); + for (unsigned i = 0; i < N; ++i) { + std::complex r = acosh(testcases[i]); + if (testcases[i].real() == 0 && testcases[i].imag() == 0) { + assert(!std::signbit(r.real())); + if (std::signbit(testcases[i].imag())) + is_about(r.imag(), -pi / 2); + else + is_about(r.imag(), pi / 2); + } else if (testcases[i].real() == 1 && testcases[i].imag() == 0) { + assert(r.real() == 0); + assert(!std::signbit(r.real())); + assert(r.imag() == 0); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); + } else if (testcases[i].real() == -1 && testcases[i].imag() == 0) { + assert(r.real() == 0); + assert(!std::signbit(r.real())); + if (std::signbit(testcases[i].imag())) + is_about(r.imag(), -pi); + else + is_about(r.imag(), pi); + } else if (std::isfinite(testcases[i].real()) && std::isinf(testcases[i].imag())) { + assert(std::isinf(r.real())); + assert(r.real() > 0); + if (std::signbit(testcases[i].imag())) + is_about(r.imag(), -pi / 2); + else + is_about(r.imag(), pi / 2); + } else if (std::isfinite(testcases[i].real()) && std::isnan(testcases[i].imag())) { + assert(std::isnan(r.real())); + assert(std::isnan(r.imag())); + } else if (std::isinf(testcases[i].real()) && testcases[i].real() < 0 && + std::isfinite(testcases[i].imag())) { + assert(std::isinf(r.real())); + assert(r.real() > 0); + if (std::signbit(testcases[i].imag())) + is_about(r.imag(), -pi); + else + is_about(r.imag(), pi); + } else if (std::isinf(testcases[i].real()) && testcases[i].real() > 0 && + std::isfinite(testcases[i].imag())) { + assert(std::isinf(r.real())); + assert(r.real() > 0); + assert(r.imag() == 0); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); + } else if (std::isinf(testcases[i].real()) && testcases[i].real() < 0 && std::isinf(testcases[i].imag())) { + assert(std::isinf(r.real())); + assert(r.real() > 0); + if (std::signbit(testcases[i].imag())) + is_about(r.imag(), T(-0.75) * pi); + else + is_about(r.imag(), T(0.75) * pi); + } else if (std::isinf(testcases[i].real()) && testcases[i].real() > 0 && std::isinf(testcases[i].imag())) { + assert(std::isinf(r.real())); + assert(r.real() > 0); + if (std::signbit(testcases[i].imag())) + is_about(r.imag(), T(-0.25 * pi)); + else + is_about(r.imag(), T(0.25 * pi)); + } else if (std::isinf(testcases[i].real()) && std::isnan(testcases[i].imag())) { + assert(std::isinf(r.real())); + assert(r.real() > 0); + assert(std::isnan(r.imag())); + } else if (std::isnan(testcases[i].real()) && std::isfinite(testcases[i].imag())) { + assert(std::isnan(r.real())); + assert(std::isnan(r.imag())); + } else if (std::isnan(testcases[i].real()) && std::isinf(testcases[i].imag())) { + assert(std::isinf(r.real())); + assert(r.real() > 0); + assert(std::isnan(r.imag())); + } else if (std::isnan(testcases[i].real()) && std::isnan(testcases[i].imag())) { + assert(std::isnan(r.real())); + assert(std::isnan(r.imag())); + } else { + assert(!std::signbit(r.real())); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); } + } } int main(int, char**) @@ -146,7 +120,9 @@ int main(int, char**) test(); test(); test(); - test_edges(); + test_edges(); + test_edges(); + test_edges(); - return 0; + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.transcendentals/asin.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.transcendentals/asin.pass.cpp index 51da1c002a294..5694a736b4ece 100644 --- a/libcxx/test/std/numerics/complex.number/complex.transcendentals/asin.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.transcendentals/asin.pass.cpp @@ -32,81 +32,59 @@ test() test(std::complex(0, 0), std::complex(0, 0)); } -void test_edges() -{ - const double pi = std::atan2(+0., -0.); - const unsigned N = sizeof(testcases) / sizeof(testcases[0]); - for (unsigned i = 0; i < N; ++i) - { - std::complex r = asin(testcases[i]); - if (testcases[i].real() == 0 && testcases[i].imag() == 0) - { - assert(std::signbit(r.real()) == std::signbit(testcases[i].real())); - assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); - } - else if (std::isfinite(testcases[i].real()) && std::isinf(testcases[i].imag())) - { - assert(r.real() == 0); - assert(std::signbit(testcases[i].real()) == std::signbit(r.real())); - assert(std::isinf(r.imag())); - assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); - } - else if ( testcases[i].real() == 0 && std::isnan(testcases[i].imag())) - { - assert(r.real() == 0); - assert(std::signbit(testcases[i].real()) == std::signbit(r.real())); - assert(std::isnan(r.imag())); - } - else if (std::isfinite(testcases[i].real()) && std::isnan(testcases[i].imag())) - { - assert(std::isnan(r.real())); - assert(std::isnan(r.imag())); - } - else if (std::isinf(testcases[i].real()) && std::isfinite(testcases[i].imag())) - { - if (testcases[i].real() > 0) - is_about(r.real(), pi/2); - else - is_about(r.real(), - pi/2); - assert(std::isinf(r.imag())); - assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); - } - else if (std::isinf(testcases[i].real()) && std::isinf(testcases[i].imag())) - { - if (std::signbit(testcases[i].real())) - is_about(r.real(), -pi/4); - else - is_about(r.real(), pi/4); - assert(std::isinf(r.imag())); - assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); - } - else if (std::isinf(testcases[i].real()) && std::isnan(testcases[i].imag())) - { - assert(std::isnan(r.real())); - assert(std::isinf(r.imag())); - assert(std::signbit(testcases[i].real()) != std::signbit(r.imag())); - } - else if (std::isnan(testcases[i].real()) && std::isfinite(testcases[i].imag())) - { - assert(std::isnan(r.real())); - assert(std::isnan(r.imag())); - } - else if (std::isnan(testcases[i].real()) && std::isinf(testcases[i].imag())) - { - assert(std::isnan(r.real())); - assert(std::isinf(r.imag())); - } - else if (std::isnan(testcases[i].real()) && std::isnan(testcases[i].imag())) - { - assert(std::isnan(r.real())); - assert(std::isnan(r.imag())); - } - else - { - assert(std::signbit(r.real()) == std::signbit(testcases[i].real())); - assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); - } +template +void test_edges() { + const T pi = std::atan2(+0., -0.); + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); + for (unsigned i = 0; i < N; ++i) { + std::complex r = asin(testcases[i]); + if (testcases[i].real() == 0 && testcases[i].imag() == 0) { + assert(std::signbit(r.real()) == std::signbit(testcases[i].real())); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); + } else if (std::isfinite(testcases[i].real()) && std::isinf(testcases[i].imag())) { + assert(r.real() == 0); + assert(std::signbit(testcases[i].real()) == std::signbit(r.real())); + assert(std::isinf(r.imag())); + assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); + } else if (testcases[i].real() == 0 && std::isnan(testcases[i].imag())) { + assert(r.real() == 0); + assert(std::signbit(testcases[i].real()) == std::signbit(r.real())); + assert(std::isnan(r.imag())); + } else if (std::isfinite(testcases[i].real()) && std::isnan(testcases[i].imag())) { + assert(std::isnan(r.real())); + assert(std::isnan(r.imag())); + } else if (std::isinf(testcases[i].real()) && std::isfinite(testcases[i].imag())) { + if (testcases[i].real() > 0) + is_about(r.real(), pi / 2); + else + is_about(r.real(), -pi / 2); + assert(std::isinf(r.imag())); + assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); + } else if (std::isinf(testcases[i].real()) && std::isinf(testcases[i].imag())) { + if (std::signbit(testcases[i].real())) + is_about(r.real(), -pi / 4); + else + is_about(r.real(), pi / 4); + assert(std::isinf(r.imag())); + assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); + } else if (std::isinf(testcases[i].real()) && std::isnan(testcases[i].imag())) { + assert(std::isnan(r.real())); + assert(std::isinf(r.imag())); + assert(std::signbit(testcases[i].real()) != std::signbit(r.imag())); + } else if (std::isnan(testcases[i].real()) && std::isfinite(testcases[i].imag())) { + assert(std::isnan(r.real())); + assert(std::isnan(r.imag())); + } else if (std::isnan(testcases[i].real()) && std::isinf(testcases[i].imag())) { + assert(std::isnan(r.real())); + assert(std::isinf(r.imag())); + } else if (std::isnan(testcases[i].real()) && std::isnan(testcases[i].imag())) { + assert(std::isnan(r.real())); + assert(std::isnan(r.imag())); + } else { + assert(std::signbit(r.real()) == std::signbit(testcases[i].real())); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); } + } } int main(int, char**) @@ -114,7 +92,9 @@ int main(int, char**) test(); test(); test(); - test_edges(); + test_edges(); + test_edges(); + test_edges(); - return 0; + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.transcendentals/asinh.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.transcendentals/asinh.pass.cpp index b53509242c378..e44040dfabb7a 100644 --- a/libcxx/test/std/numerics/complex.number/complex.transcendentals/asinh.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.transcendentals/asinh.pass.cpp @@ -32,90 +32,66 @@ test() test(std::complex(0, 0), std::complex(0, 0)); } -void test_edges() -{ - const double pi = std::atan2(+0., -0.); - const unsigned N = sizeof(testcases) / sizeof(testcases[0]); - for (unsigned i = 0; i < N; ++i) - { - std::complex r = asinh(testcases[i]); - if (testcases[i].real() == 0 && testcases[i].imag() == 0) - { - assert(std::signbit(r.real()) == std::signbit(testcases[i].real())); - assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); - } - else if (testcases[i].real() == 0 && std::abs(testcases[i].imag()) == 1) - { - assert(r.real() == 0); - assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); - if (std::signbit(testcases[i].imag())) - is_about(r.imag(), -pi/2); - else - is_about(r.imag(), pi/2); - } - else if (std::isfinite(testcases[i].real()) && std::isinf(testcases[i].imag())) - { - assert(std::isinf(r.real())); - assert(std::signbit(testcases[i].real()) == std::signbit(r.real())); - if (std::signbit(testcases[i].imag())) - is_about(r.imag(), -pi/2); - else - is_about(r.imag(), pi/2); - } - else if (std::isfinite(testcases[i].real()) && std::isnan(testcases[i].imag())) - { - assert(std::isnan(r.real())); - assert(std::isnan(r.imag())); - } - else if (std::isinf(testcases[i].real()) && std::isfinite(testcases[i].imag())) - { - assert(std::isinf(r.real())); - assert(std::signbit(testcases[i].real()) == std::signbit(r.real())); - assert(r.imag() == 0); - assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); - } - else if (std::isinf(testcases[i].real()) && std::isinf(testcases[i].imag())) - { - assert(std::isinf(r.real())); - assert(std::signbit(testcases[i].real()) == std::signbit(r.real())); - if (std::signbit(testcases[i].imag())) - is_about(r.imag(), -pi/4); - else - is_about(r.imag(), pi/4); - } - else if (std::isinf(testcases[i].real()) && std::isnan(testcases[i].imag())) - { - assert(std::isinf(r.real())); - assert(std::signbit(testcases[i].real()) == std::signbit(r.real())); - assert(std::isnan(r.imag())); - } - else if (std::isnan(testcases[i].real()) && testcases[i].imag() == 0) - { - assert(std::isnan(r.real())); - assert(r.imag() == 0); - assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); - } - else if (std::isnan(testcases[i].real()) && std::isfinite(testcases[i].imag())) - { - assert(std::isnan(r.real())); - assert(std::isnan(r.imag())); - } - else if (std::isnan(testcases[i].real()) && std::isinf(testcases[i].imag())) - { - assert(std::isinf(r.real())); - assert(std::isnan(r.imag())); - } - else if (std::isnan(testcases[i].real()) && std::isnan(testcases[i].imag())) - { - assert(std::isnan(r.real())); - assert(std::isnan(r.imag())); - } - else - { - assert(std::signbit(r.real()) == std::signbit(testcases[i].real())); - assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); - } +template +void test_edges() { + const T pi = std::atan2(+0., -0.); + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); + for (unsigned i = 0; i < N; ++i) { + std::complex r = asinh(testcases[i]); + if (testcases[i].real() == 0 && testcases[i].imag() == 0) { + assert(std::signbit(r.real()) == std::signbit(testcases[i].real())); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); + } else if (testcases[i].real() == 0 && std::abs(testcases[i].imag()) == 1) { + assert(r.real() == 0); + assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); + if (std::signbit(testcases[i].imag())) + is_about(r.imag(), -pi / 2); + else + is_about(r.imag(), pi / 2); + } else if (std::isfinite(testcases[i].real()) && std::isinf(testcases[i].imag())) { + assert(std::isinf(r.real())); + assert(std::signbit(testcases[i].real()) == std::signbit(r.real())); + if (std::signbit(testcases[i].imag())) + is_about(r.imag(), -pi / 2); + else + is_about(r.imag(), pi / 2); + } else if (std::isfinite(testcases[i].real()) && std::isnan(testcases[i].imag())) { + assert(std::isnan(r.real())); + assert(std::isnan(r.imag())); + } else if (std::isinf(testcases[i].real()) && std::isfinite(testcases[i].imag())) { + assert(std::isinf(r.real())); + assert(std::signbit(testcases[i].real()) == std::signbit(r.real())); + assert(r.imag() == 0); + assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); + } else if (std::isinf(testcases[i].real()) && std::isinf(testcases[i].imag())) { + assert(std::isinf(r.real())); + assert(std::signbit(testcases[i].real()) == std::signbit(r.real())); + if (std::signbit(testcases[i].imag())) + is_about(r.imag(), -pi / 4); + else + is_about(r.imag(), pi / 4); + } else if (std::isinf(testcases[i].real()) && std::isnan(testcases[i].imag())) { + assert(std::isinf(r.real())); + assert(std::signbit(testcases[i].real()) == std::signbit(r.real())); + assert(std::isnan(r.imag())); + } else if (std::isnan(testcases[i].real()) && testcases[i].imag() == 0) { + assert(std::isnan(r.real())); + assert(r.imag() == 0); + assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); + } else if (std::isnan(testcases[i].real()) && std::isfinite(testcases[i].imag())) { + assert(std::isnan(r.real())); + assert(std::isnan(r.imag())); + } else if (std::isnan(testcases[i].real()) && std::isinf(testcases[i].imag())) { + assert(std::isinf(r.real())); + assert(std::isnan(r.imag())); + } else if (std::isnan(testcases[i].real()) && std::isnan(testcases[i].imag())) { + assert(std::isnan(r.real())); + assert(std::isnan(r.imag())); + } else { + assert(std::signbit(r.real()) == std::signbit(testcases[i].real())); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); } + } } int main(int, char**) @@ -123,7 +99,9 @@ int main(int, char**) test(); test(); test(); - test_edges(); + test_edges(); + test_edges(); + test_edges(); - return 0; + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.transcendentals/atan.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.transcendentals/atan.pass.cpp index f0c801649509d..a8da42b0c0351 100644 --- a/libcxx/test/std/numerics/complex.number/complex.transcendentals/atan.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.transcendentals/atan.pass.cpp @@ -32,30 +32,27 @@ test() test(std::complex(0, 0), std::complex(0, 0)); } -void test_edges() -{ - const unsigned N = sizeof(testcases) / sizeof(testcases[0]); - for (unsigned i = 0; i < N; ++i) - { - std::complex r = atan(testcases[i]); - std::complex t1(-imag(testcases[i]), real(testcases[i])); - std::complex t2 = atanh(t1); - std::complex z(imag(t2), -real(t2)); - if (std::isnan(real(r))) - assert(std::isnan(real(z))); - else - { - assert(real(r) == real(z)); - assert(std::signbit(real(r)) == std::signbit(real(z))); - } - if (std::isnan(imag(r))) - assert(std::isnan(imag(z))); - else - { - assert(imag(r) == imag(z)); - assert(std::signbit(imag(r)) == std::signbit(imag(z))); - } +template +void test_edges() { + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); + for (unsigned i = 0; i < N; ++i) { + std::complex r = atan(testcases[i]); + std::complex t1(-imag(testcases[i]), real(testcases[i])); + std::complex t2 = atanh(t1); + std::complex z(imag(t2), -real(t2)); + if (std::isnan(real(r))) + assert(std::isnan(real(z))); + else { + assert(real(r) == real(z)); + assert(std::signbit(real(r)) == std::signbit(real(z))); + } + if (std::isnan(imag(r))) + assert(std::isnan(imag(z))); + else { + assert(imag(r) == imag(z)); + assert(std::signbit(imag(r)) == std::signbit(imag(z))); } + } } int main(int, char**) @@ -63,7 +60,9 @@ int main(int, char**) test(); test(); test(); - test_edges(); + test_edges(); + test_edges(); + test_edges(); - return 0; + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.transcendentals/atanh.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.transcendentals/atanh.pass.cpp index a126032bf8c24..c75ffad2ef51f 100644 --- a/libcxx/test/std/numerics/complex.number/complex.transcendentals/atanh.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.transcendentals/atanh.pass.cpp @@ -32,94 +32,70 @@ test() test(std::complex(0, 0), std::complex(0, 0)); } -void test_edges() -{ - const double pi = std::atan2(+0., -0.); - const unsigned N = sizeof(testcases) / sizeof(testcases[0]); - for (unsigned i = 0; i < N; ++i) - { - std::complex r = atanh(testcases[i]); - if (testcases[i].real() == 0 && testcases[i].imag() == 0) - { - assert(std::signbit(r.real()) == std::signbit(testcases[i].real())); - assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); - } - else if ( testcases[i].real() == 0 && std::isnan(testcases[i].imag())) - { - assert(r.real() == 0); - assert(std::signbit(testcases[i].real()) == std::signbit(r.real())); - assert(std::isnan(r.imag())); - } - else if (std::abs(testcases[i].real()) == 1 && testcases[i].imag() == 0) - { - assert(std::isinf(r.real())); - assert(std::signbit(testcases[i].real()) == std::signbit(r.real())); - assert(r.imag() == 0); - assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); - } - else if (std::isfinite(testcases[i].real()) && std::isinf(testcases[i].imag())) - { - assert(r.real() == 0); - assert(std::signbit(testcases[i].real()) == std::signbit(r.real())); - if (testcases[i].imag() > 0) - is_about(r.imag(), pi/2); - else - is_about(r.imag(), -pi/2); - } - else if (std::isfinite(testcases[i].real()) && std::isnan(testcases[i].imag())) - { - assert(std::isnan(r.real())); - assert(std::isnan(r.imag())); - } - else if (std::isinf(testcases[i].real()) && std::isfinite(testcases[i].imag())) - { - assert(r.real() == 0); - assert(std::signbit(testcases[i].real()) == std::signbit(r.real())); - if (std::signbit(testcases[i].imag())) - is_about(r.imag(), -pi/2); - else - is_about(r.imag(), pi/2); - } - else if (std::isinf(testcases[i].real()) && std::isinf(testcases[i].imag())) - { - assert(r.real() == 0); - assert(std::signbit(testcases[i].real()) == std::signbit(r.real())); - if (std::signbit(testcases[i].imag())) - is_about(r.imag(), -pi/2); - else - is_about(r.imag(), pi/2); - } - else if (std::isinf(testcases[i].real()) && std::isnan(testcases[i].imag())) - { - assert(r.real() == 0); - assert(std::signbit(testcases[i].real()) == std::signbit(r.real())); - assert(std::isnan(r.imag())); - } - else if (std::isnan(testcases[i].real()) && std::isfinite(testcases[i].imag())) - { - assert(std::isnan(r.real())); - assert(std::isnan(r.imag())); - } - else if (std::isnan(testcases[i].real()) && std::isinf(testcases[i].imag())) - { - assert(r.real() == 0); - assert(std::signbit(testcases[i].real()) == std::signbit(r.real())); - if (std::signbit(testcases[i].imag())) - is_about(r.imag(), -pi/2); - else - is_about(r.imag(), pi/2); - } - else if (std::isnan(testcases[i].real()) && std::isnan(testcases[i].imag())) - { - assert(std::isnan(r.real())); - assert(std::isnan(r.imag())); - } - else - { - assert(std::signbit(r.real()) == std::signbit(testcases[i].real())); - assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); - } +template +void test_edges() { + const T pi = std::atan2(+0., -0.); + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); + for (unsigned i = 0; i < N; ++i) { + std::complex r = atanh(testcases[i]); + if (testcases[i].real() == 0 && testcases[i].imag() == 0) { + assert(std::signbit(r.real()) == std::signbit(testcases[i].real())); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); + } else if (testcases[i].real() == 0 && std::isnan(testcases[i].imag())) { + assert(r.real() == 0); + assert(std::signbit(testcases[i].real()) == std::signbit(r.real())); + assert(std::isnan(r.imag())); + } else if (std::abs(testcases[i].real()) == 1 && testcases[i].imag() == 0) { + assert(std::isinf(r.real())); + assert(std::signbit(testcases[i].real()) == std::signbit(r.real())); + assert(r.imag() == 0); + assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); + } else if (std::isfinite(testcases[i].real()) && std::isinf(testcases[i].imag())) { + assert(r.real() == 0); + assert(std::signbit(testcases[i].real()) == std::signbit(r.real())); + if (testcases[i].imag() > 0) + is_about(r.imag(), pi / 2); + else + is_about(r.imag(), -pi / 2); + } else if (std::isfinite(testcases[i].real()) && std::isnan(testcases[i].imag())) { + assert(std::isnan(r.real())); + assert(std::isnan(r.imag())); + } else if (std::isinf(testcases[i].real()) && std::isfinite(testcases[i].imag())) { + assert(r.real() == 0); + assert(std::signbit(testcases[i].real()) == std::signbit(r.real())); + if (std::signbit(testcases[i].imag())) + is_about(r.imag(), -pi / 2); + else + is_about(r.imag(), pi / 2); + } else if (std::isinf(testcases[i].real()) && std::isinf(testcases[i].imag())) { + assert(r.real() == 0); + assert(std::signbit(testcases[i].real()) == std::signbit(r.real())); + if (std::signbit(testcases[i].imag())) + is_about(r.imag(), -pi / 2); + else + is_about(r.imag(), pi / 2); + } else if (std::isinf(testcases[i].real()) && std::isnan(testcases[i].imag())) { + assert(r.real() == 0); + assert(std::signbit(testcases[i].real()) == std::signbit(r.real())); + assert(std::isnan(r.imag())); + } else if (std::isnan(testcases[i].real()) && std::isfinite(testcases[i].imag())) { + assert(std::isnan(r.real())); + assert(std::isnan(r.imag())); + } else if (std::isnan(testcases[i].real()) && std::isinf(testcases[i].imag())) { + assert(r.real() == 0); + assert(std::signbit(testcases[i].real()) == std::signbit(r.real())); + if (std::signbit(testcases[i].imag())) + is_about(r.imag(), -pi / 2); + else + is_about(r.imag(), pi / 2); + } else if (std::isnan(testcases[i].real()) && std::isnan(testcases[i].imag())) { + assert(std::isnan(r.real())); + assert(std::isnan(r.imag())); + } else { + assert(std::signbit(r.real()) == std::signbit(testcases[i].real())); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); } + } } int main(int, char**) @@ -127,7 +103,9 @@ int main(int, char**) test(); test(); test(); - test_edges(); + test_edges(); + test_edges(); + test_edges(); - return 0; + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.transcendentals/cos.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.transcendentals/cos.pass.cpp index 0571363de50c3..9a9b3209e61be 100644 --- a/libcxx/test/std/numerics/complex.number/complex.transcendentals/cos.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.transcendentals/cos.pass.cpp @@ -32,29 +32,26 @@ test() test(std::complex(0, 0), std::complex(1, 0)); } -void test_edges() -{ - const unsigned N = sizeof(testcases) / sizeof(testcases[0]); - for (unsigned i = 0; i < N; ++i) - { - std::complex r = cos(testcases[i]); - std::complex t1(-imag(testcases[i]), real(testcases[i])); - std::complex z = cosh(t1); - if (std::isnan(real(r))) - assert(std::isnan(real(z))); - else - { - assert(real(r) == real(z)); - assert(std::signbit(real(r)) == std::signbit(real(z))); - } - if (std::isnan(imag(r))) - assert(std::isnan(imag(z))); - else - { - assert(imag(r) == imag(z)); - assert(std::signbit(imag(r)) == std::signbit(imag(z))); - } +template +void test_edges() { + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); + for (unsigned i = 0; i < N; ++i) { + std::complex r = cos(testcases[i]); + std::complex t1(-imag(testcases[i]), real(testcases[i])); + std::complex z = cosh(t1); + if (std::isnan(real(r))) + assert(std::isnan(real(z))); + else { + assert(real(r) == real(z)); + assert(std::signbit(real(r)) == std::signbit(real(z))); + } + if (std::isnan(imag(r))) + assert(std::isnan(imag(z))); + else { + assert(imag(r) == imag(z)); + assert(std::signbit(imag(r)) == std::signbit(imag(z))); } + } } int main(int, char**) @@ -62,7 +59,9 @@ int main(int, char**) test(); test(); test(); - test_edges(); + test_edges(); + test_edges(); + test_edges(); - return 0; + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.transcendentals/cosh.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.transcendentals/cosh.pass.cpp index ad437bf44b996..bdda26c561db3 100644 --- a/libcxx/test/std/numerics/complex.number/complex.transcendentals/cosh.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.transcendentals/cosh.pass.cpp @@ -32,79 +32,60 @@ test() test(std::complex(0, 0), std::complex(1, 0)); } -void test_edges() -{ - const unsigned N = sizeof(testcases) / sizeof(testcases[0]); - for (unsigned i = 0; i < N; ++i) - { - std::complex r = cosh(testcases[i]); - if (testcases[i].real() == 0 && testcases[i].imag() == 0) - { - assert(r.real() == 1); - assert(r.imag() == 0); - assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); - } - else if (testcases[i].real() == 0 && std::isinf(testcases[i].imag())) - { - assert(std::isnan(r.real())); - assert(r.imag() == 0); - } - else if (testcases[i].real() == 0 && std::isnan(testcases[i].imag())) - { - assert(std::isnan(r.real())); - assert(r.imag() == 0); - } - else if (std::isfinite(testcases[i].real()) && std::isinf(testcases[i].imag())) - { - assert(std::isnan(r.real())); - assert(std::isnan(r.imag())); - } - else if (std::isfinite(testcases[i].real()) && std::isnan(testcases[i].imag())) - { - assert(std::isnan(r.real())); - assert(std::isnan(r.imag())); - } - else if (std::isinf(testcases[i].real()) && testcases[i].imag() == 0) - { - assert(std::isinf(r.real())); - assert(!std::signbit(r.real())); - assert(r.imag() == 0); - assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); - } - else if (std::isinf(testcases[i].real()) && std::isfinite(testcases[i].imag())) - { - assert(std::isinf(r.real())); - assert(std::signbit(r.real()) == std::signbit(cos(testcases[i].imag()))); - assert(std::isinf(r.imag())); - assert(std::signbit(r.imag()) == std::signbit(testcases[i].real() * sin(testcases[i].imag()))); - } - else if (std::isinf(testcases[i].real()) && std::isinf(testcases[i].imag())) - { - assert(std::isinf(r.real())); - assert(std::isnan(r.imag())); - } - else if (std::isinf(testcases[i].real()) && std::isnan(testcases[i].imag())) - { - assert(std::isinf(r.real())); - assert(r.real() > 0); - assert(std::isnan(r.imag())); - } - else if (std::isnan(testcases[i].real()) && testcases[i].imag() == 0) - { - assert(std::isnan(r.real())); - assert(r.imag() == 0); - } - else if (std::isnan(testcases[i].real()) && std::isfinite(testcases[i].imag())) - { - assert(std::isnan(r.real())); - assert(std::isnan(r.imag())); - } - else if (std::isnan(testcases[i].real()) && std::isnan(testcases[i].imag())) - { - assert(std::isnan(r.real())); - assert(std::isnan(r.imag())); - } +template +void test_edges() { + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); + for (unsigned i = 0; i < N; ++i) { + std::complex r = cosh(testcases[i]); + if (testcases[i].real() == 0 && testcases[i].imag() == 0) { + assert(r.real() == 1); + assert(r.imag() == 0); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); + } else if (testcases[i].real() == 0 && std::isinf(testcases[i].imag())) { + assert(std::isnan(r.real())); + assert(r.imag() == 0); + } else if (testcases[i].real() == 0 && std::isnan(testcases[i].imag())) { + assert(std::isnan(r.real())); + assert(r.imag() == 0); + } else if (std::isfinite(testcases[i].real()) && std::isinf(testcases[i].imag())) { + assert(std::isnan(r.real())); + assert(std::isnan(r.imag())); + } else if (std::isfinite(testcases[i].real()) && std::isnan(testcases[i].imag())) { + assert(std::isnan(r.real())); + assert(std::isnan(r.imag())); + } else if (std::isinf(testcases[i].real()) && testcases[i].imag() == 0) { + assert(std::isinf(r.real())); + assert(!std::signbit(r.real())); + assert(r.imag() == 0); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); + } else if (std::isinf(testcases[i].real()) && std::isfinite(testcases[i].imag())) { + assert(std::isinf(r.real())); + assert(std::signbit(r.real()) == std::signbit(cos(testcases[i].imag()))); + assert(std::isinf(r.imag())); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].real() * sin(testcases[i].imag()))); + } else if (std::isinf(testcases[i].real()) && std::isinf(testcases[i].imag())) { + assert(std::isinf(r.real())); + assert(std::isnan(r.imag())); + } else if (std::isinf(testcases[i].real()) && std::isnan(testcases[i].imag())) { + assert(std::isinf(r.real())); + assert(r.real() > 0); + assert(std::isnan(r.imag())); + } else if (std::isnan(testcases[i].real()) && testcases[i].imag() == 0) { + assert(std::isnan(r.real())); + assert(r.imag() == 0); + } else if (std::isnan(testcases[i].real()) && std::isfinite(testcases[i].imag())) { + assert(std::isnan(r.real())); + assert(std::isnan(r.imag())); + } else if (std::isnan(testcases[i].real()) && std::isnan(testcases[i].imag())) { + assert(std::isnan(r.real())); + assert(std::isnan(r.imag())); + } else if (std::isfinite(testcases[i].real()) && std::isfinite(testcases[i].imag())) { + assert(!std::isnan(r.real())); + + bool const nan_okay = std::isinf(r.real()) && testcases[i].imag() == 0; // inf * 0 == NaN + assert(!std::isnan(r.imag()) || nan_okay); } + } } int main(int, char**) @@ -112,7 +93,9 @@ int main(int, char**) test(); test(); test(); - test_edges(); + test_edges(); + test_edges(); + test_edges(); - return 0; + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.transcendentals/exp.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.transcendentals/exp.pass.cpp index 5c9574e6399d9..81686a6a6b868 100644 --- a/libcxx/test/std/numerics/complex.number/complex.transcendentals/exp.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.transcendentals/exp.pass.cpp @@ -32,81 +32,56 @@ test() test(std::complex(0, 0), std::complex(1, 0)); } -void test_edges() -{ - const unsigned N = sizeof(testcases) / sizeof(testcases[0]); - for (unsigned i = 0; i < N; ++i) - { - std::complex r = exp(testcases[i]); - if (testcases[i].real() == 0 && testcases[i].imag() == 0) - { - assert(r.real() == 1.0); - assert(r.imag() == 0); - assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); - } - else if (std::isfinite(testcases[i].real()) && std::isinf(testcases[i].imag())) - { - assert(std::isnan(r.real())); - assert(std::isnan(r.imag())); - } - else if (std::isfinite(testcases[i].real()) && std::isnan(testcases[i].imag())) - { - assert(std::isnan(r.real())); - assert(std::isnan(r.imag())); - } - else if (std::isinf(testcases[i].real()) && testcases[i].real() > 0 && testcases[i].imag() == 0) - { - assert(std::isinf(r.real())); - assert(r.real() > 0); - assert(r.imag() == 0); - assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); - } - else if (std::isinf(testcases[i].real()) && testcases[i].real() < 0 && std::isinf(testcases[i].imag())) - { - assert(r.real() == 0); - assert(r.imag() == 0); - } - else if (std::isinf(testcases[i].real()) && testcases[i].real() > 0 && std::isinf(testcases[i].imag())) - { - assert(std::isinf(r.real())); - assert(std::isnan(r.imag())); - } - else if (std::isinf(testcases[i].real()) && testcases[i].real() < 0 && std::isnan(testcases[i].imag())) - { - assert(r.real() == 0); - assert(r.imag() == 0); - } - else if (std::isinf(testcases[i].real()) && testcases[i].real() > 0 && std::isnan(testcases[i].imag())) - { - assert(std::isinf(r.real())); - assert(std::isnan(r.imag())); - } - else if (std::isnan(testcases[i].real()) && testcases[i].imag() == 0) - { - assert(std::isnan(r.real())); - assert(r.imag() == 0); - assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); - } - else if (std::isnan(testcases[i].real()) && testcases[i].imag() != 0) - { - assert(std::isnan(r.real())); - assert(std::isnan(r.imag())); - } - else if (std::isnan(testcases[i].real()) && std::isnan(testcases[i].imag())) - { - assert(std::isnan(r.real())); - assert(std::isnan(r.imag())); - } - else if (std::isfinite(testcases[i].imag()) && std::abs(testcases[i].imag()) <= 1) - { - assert(!std::signbit(r.real())); - assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); - } - else if (std::isinf(r.real()) && testcases[i].imag() == 0) { - assert(r.imag() == 0); - assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); - } +template +void test_edges() { + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); + for (unsigned i = 0; i < N; ++i) { + std::complex r = exp(testcases[i]); + if (testcases[i].real() == 0 && testcases[i].imag() == 0) { + assert(r.real() == 1.0); + assert(r.imag() == 0); + assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); + } else if (std::isfinite(testcases[i].real()) && std::isinf(testcases[i].imag())) { + assert(std::isnan(r.real())); + assert(std::isnan(r.imag())); + } else if (std::isfinite(testcases[i].real()) && std::isnan(testcases[i].imag())) { + assert(std::isnan(r.real())); + assert(std::isnan(r.imag())); + } else if (std::isinf(testcases[i].real()) && testcases[i].real() > 0 && testcases[i].imag() == 0) { + assert(std::isinf(r.real())); + assert(r.real() > 0); + assert(r.imag() == 0); + assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); + } else if (std::isinf(testcases[i].real()) && testcases[i].real() < 0 && std::isinf(testcases[i].imag())) { + assert(r.real() == 0); + assert(r.imag() == 0); + } else if (std::isinf(testcases[i].real()) && testcases[i].real() > 0 && std::isinf(testcases[i].imag())) { + assert(std::isinf(r.real())); + assert(std::isnan(r.imag())); + } else if (std::isinf(testcases[i].real()) && testcases[i].real() < 0 && std::isnan(testcases[i].imag())) { + assert(r.real() == 0); + assert(r.imag() == 0); + } else if (std::isinf(testcases[i].real()) && testcases[i].real() > 0 && std::isnan(testcases[i].imag())) { + assert(std::isinf(r.real())); + assert(std::isnan(r.imag())); + } else if (std::isnan(testcases[i].real()) && testcases[i].imag() == 0) { + assert(std::isnan(r.real())); + assert(r.imag() == 0); + assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); + } else if (std::isnan(testcases[i].real()) && testcases[i].imag() != 0) { + assert(std::isnan(r.real())); + assert(std::isnan(r.imag())); + } else if (std::isnan(testcases[i].real()) && std::isnan(testcases[i].imag())) { + assert(std::isnan(r.real())); + assert(std::isnan(r.imag())); + } else if (std::isfinite(testcases[i].imag()) && std::abs(testcases[i].imag()) <= 1) { + assert(!std::signbit(r.real())); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); + } else if (std::isinf(r.real()) && testcases[i].imag() == 0) { + assert(r.imag() == 0); + assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); } + } } int main(int, char**) @@ -114,7 +89,9 @@ int main(int, char**) test(); test(); test(); - test_edges(); + test_edges(); + test_edges(); + test_edges(); return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.transcendentals/log.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.transcendentals/log.pass.cpp index 562d125e05323..94b348a962f1d 100644 --- a/libcxx/test/std/numerics/complex.number/complex.transcendentals/log.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.transcendentals/log.pass.cpp @@ -32,94 +32,73 @@ test() test(std::complex(0, 0), std::complex(-INFINITY, 0)); } -void test_edges() -{ - const double pi = std::atan2(+0., -0.); - const unsigned N = sizeof(testcases) / sizeof(testcases[0]); - for (unsigned i = 0; i < N; ++i) - { - std::complex r = log(testcases[i]); - if (testcases[i].real() == 0 && testcases[i].imag() == 0) - { - if (std::signbit(testcases[i].real())) - { - assert(std::isinf(r.real())); - assert(r.real() < 0); - if (std::signbit(testcases[i].imag())) - is_about(r.imag(), -pi); - else - is_about(r.imag(), pi); - } - else - { - assert(std::isinf(r.real())); - assert(r.real() < 0); - assert(r.imag() == 0); - assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); - } - } - else if (std::isfinite(testcases[i].real()) && std::isinf(testcases[i].imag())) - { - assert(std::isinf(r.real())); - assert(r.real() > 0); - if (testcases[i].imag() > 0) - is_about(r.imag(), pi/2); - else - is_about(r.imag(), -pi/2); - } - else if (std::isfinite(testcases[i].real()) && std::isnan(testcases[i].imag())) - { - assert(std::isnan(r.real())); - assert(std::isnan(r.imag())); - } - else if (std::isinf(testcases[i].real()) && testcases[i].real() < 0 && std::isfinite(testcases[i].imag())) - { - assert(std::isinf(r.real()) && r.real() > 0); - if (r.imag() > 0) - is_about(r.imag(), pi); - else - is_about(r.imag(), -pi); - } - else if (std::isinf(testcases[i].real()) && testcases[i].real() > 0 && std::isfinite(testcases[i].imag())) - { - assert(std::isinf(r.real()) && r.real() > 0); - assert(r.imag() == 0); - assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); - } - else if (testcases[i].real() == 1 && testcases[i].imag() == 0) - { - assert(r.real() == 0); - assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); - } - else if (testcases[i].real() == 0 && testcases[i].imag() == 1) - { - assert(r.real() == 0); - is_about(r.imag(), pi/2); - } - else if (testcases[i].real() == -1 && testcases[i].imag() == 0) - { - assert(r.real() == 0); - if (std::signbit(testcases[i].imag())) - is_about(r.imag(), -pi); - else - is_about(r.imag(), pi); - } - else if (testcases[i].real() == 0 && testcases[i].imag() == -1) - { - assert(r.real() == 0); - is_about(r.imag(), -pi/2); - } - else if (std::isfinite(testcases[i].real()) && std::isfinite(testcases[i].imag()) && abs(testcases[i]) < 1) - { - assert( std::signbit(r.real())); - assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); - } - else if (std::isfinite(testcases[i].real()) && std::isfinite(testcases[i].imag()) && abs(testcases[i]) > 1) - { - assert(!std::signbit(r.real())); - assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); - } +template +void test_edges() { + const T pi = std::atan2(+0., -0.); + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); + for (unsigned i = 0; i < N; ++i) { + std::complex r = log(testcases[i]); + if (testcases[i].real() == 0 && testcases[i].imag() == 0) { + if (std::signbit(testcases[i].real())) { + assert(std::isinf(r.real())); + assert(r.real() < 0); + if (std::signbit(testcases[i].imag())) + is_about(r.imag(), -pi); + else + is_about(r.imag(), pi); + } else { + assert(std::isinf(r.real())); + assert(r.real() < 0); + assert(r.imag() == 0); + assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); + } + } else if (std::isfinite(testcases[i].real()) && std::isinf(testcases[i].imag())) { + assert(std::isinf(r.real())); + assert(r.real() > 0); + if (testcases[i].imag() > 0) + is_about(r.imag(), pi / 2); + else + is_about(r.imag(), -pi / 2); + } else if (std::isfinite(testcases[i].real()) && std::isnan(testcases[i].imag())) { + assert(std::isnan(r.real())); + assert(std::isnan(r.imag())); + } else if (std::isinf(testcases[i].real()) && testcases[i].real() < 0 && + std::isfinite(testcases[i].imag())) { + assert(std::isinf(r.real()) && r.real() > 0); + if (r.imag() > 0) + is_about(r.imag(), pi); + else + is_about(r.imag(), -pi); + } else if (std::isinf(testcases[i].real()) && testcases[i].real() > 0 && + std::isfinite(testcases[i].imag())) { + assert(std::isinf(r.real()) && r.real() > 0); + assert(r.imag() == 0); + assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); + } else if (testcases[i].real() == 1 && testcases[i].imag() == 0) { + assert(r.real() == 0); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); + } else if (testcases[i].real() == 0 && testcases[i].imag() == 1) { + assert(r.real() == 0); + is_about(r.imag(), pi / 2); + } else if (testcases[i].real() == -1 && testcases[i].imag() == 0) { + assert(r.real() == 0); + if (std::signbit(testcases[i].imag())) + is_about(r.imag(), -pi); + else + is_about(r.imag(), pi); + } else if (testcases[i].real() == 0 && testcases[i].imag() == -1) { + assert(r.real() == 0); + is_about(r.imag(), -pi / 2); + } else if (std::isfinite(testcases[i].real()) && std::isfinite(testcases[i].imag()) && + abs(testcases[i]) < 1) { + assert(std::signbit(r.real())); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); + } else if (std::isfinite(testcases[i].real()) && std::isfinite(testcases[i].imag()) && + abs(testcases[i]) > 1) { + assert(!std::signbit(r.real())); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); } + } } int main(int, char**) @@ -127,7 +106,9 @@ int main(int, char**) test(); test(); test(); - test_edges(); + test_edges(); + test_edges(); + test_edges(); - return 0; + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.transcendentals/log10.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.transcendentals/log10.pass.cpp index 78818f0de15b2..3d0219b9a42c1 100644 --- a/libcxx/test/std/numerics/complex.number/complex.transcendentals/log10.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.transcendentals/log10.pass.cpp @@ -32,28 +32,25 @@ test() test(std::complex(0, 0), std::complex(-INFINITY, 0)); } -void test_edges() -{ - const unsigned N = sizeof(testcases) / sizeof(testcases[0]); - for (unsigned i = 0; i < N; ++i) - { - std::complex r = log10(testcases[i]); - std::complex z = log(testcases[i])/std::log(10); - if (std::isnan(real(r))) - assert(std::isnan(real(z))); - else - { - assert(real(r) == real(z)); - assert(std::signbit(real(r)) == std::signbit(real(z))); - } - if (std::isnan(imag(r))) - assert(std::isnan(imag(z))); - else - { - assert(imag(r) == imag(z)); - assert(std::signbit(imag(r)) == std::signbit(imag(z))); - } +template +void test_edges() { + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); + for (unsigned i = 0; i < N; ++i) { + std::complex r = log10(testcases[i]); + std::complex z = log(testcases[i]) / std::log(T(10)); + if (std::isnan(real(r))) + assert(std::isnan(real(z))); + else { + assert(real(r) == real(z)); + assert(std::signbit(real(r)) == std::signbit(real(z))); + } + if (std::isnan(imag(r))) + assert(std::isnan(imag(z))); + else { + assert(imag(r) == imag(z)); + assert(std::signbit(imag(r)) == std::signbit(imag(z))); } + } } int main(int, char**) @@ -61,7 +58,9 @@ int main(int, char**) test(); test(); test(); - test_edges(); + test_edges(); + test_edges(); + test_edges(); - return 0; + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.transcendentals/pow_complex_complex.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.transcendentals/pow_complex_complex.pass.cpp index 91754fac4d0a8..f10129466a114 100644 --- a/libcxx/test/std/numerics/complex.number/complex.transcendentals/pow_complex_complex.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.transcendentals/pow_complex_complex.pass.cpp @@ -34,31 +34,27 @@ test() test(std::complex(2, 3), std::complex(2, 0), std::complex(-5, 12)); } -void test_edges() -{ - const unsigned N = sizeof(testcases) / sizeof(testcases[0]); - for (unsigned i = 0; i < N; ++i) - { - for (unsigned j = 0; j < N; ++j) - { - std::complex r = pow(testcases[i], testcases[j]); - std::complex z = exp(testcases[j] * log(testcases[i])); - if (std::isnan(real(r))) - assert(std::isnan(real(z))); - else - { - assert(real(r) == real(z)); - assert(std::signbit(real(r)) == std::signbit(real(z))); - } - if (std::isnan(imag(r))) - assert(std::isnan(imag(z))); - else - { - assert(imag(r) == imag(z)); - assert(std::signbit(imag(r)) == std::signbit(imag(z))); - } - } +template +void test_edges() { + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); + for (unsigned i = 0; i < N; ++i) { + for (unsigned j = 0; j < N; ++j) { + std::complex r = pow(testcases[i], testcases[j]); + std::complex z = exp(testcases[j] * log(testcases[i])); + if (std::isnan(real(r))) + assert(std::isnan(real(z))); + else { + assert(real(r) == real(z)); + assert(std::signbit(real(r)) == std::signbit(real(z))); + } + if (std::isnan(imag(r))) + assert(std::isnan(imag(z))); + else { + assert(imag(r) == imag(z)); + assert(std::signbit(imag(r)) == std::signbit(imag(z))); + } } + } } int main(int, char**) @@ -66,7 +62,9 @@ int main(int, char**) test(); test(); test(); - test_edges(); + test_edges(); + test_edges(); + test_edges(); - return 0; + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.transcendentals/pow_complex_scalar.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.transcendentals/pow_complex_scalar.pass.cpp index 4b1aef23281db..919512fb21a6b 100644 --- a/libcxx/test/std/numerics/complex.number/complex.transcendentals/pow_complex_scalar.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.transcendentals/pow_complex_scalar.pass.cpp @@ -34,29 +34,25 @@ test() test(std::complex(2, 3), T(2), std::complex(-5, 12)); } -void test_edges() -{ - const unsigned N = sizeof(testcases) / sizeof(testcases[0]); - for (unsigned i = 0; i < N; ++i) - { - for (unsigned j = 0; j < N; ++j) - { - std::complex r = pow(testcases[i], real(testcases[j])); - std::complex z = exp(std::complex(real(testcases[j])) * log(testcases[i])); - if (std::isnan(real(r))) - assert(std::isnan(real(z))); - else - { - assert(real(r) == real(z)); - } - if (std::isnan(imag(r))) - assert(std::isnan(imag(z))); - else - { - assert(imag(r) == imag(z)); - } - } +template +void test_edges() { + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); + for (unsigned i = 0; i < N; ++i) { + for (unsigned j = 0; j < N; ++j) { + std::complex r = pow(testcases[i], real(testcases[j])); + std::complex z = exp(std::complex(real(testcases[j])) * log(testcases[i])); + if (std::isnan(real(r))) + assert(std::isnan(real(z))); + else { + assert(real(r) == real(z)); + } + if (std::isnan(imag(r))) + assert(std::isnan(imag(z))); + else { + assert(imag(r) == imag(z)); + } } + } } int main(int, char**) @@ -64,7 +60,9 @@ int main(int, char**) test(); test(); test(); - test_edges(); + test_edges(); + test_edges(); + test_edges(); - return 0; + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.transcendentals/pow_scalar_complex.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.transcendentals/pow_scalar_complex.pass.cpp index 6022fddfaa755..d41e8defb8a61 100644 --- a/libcxx/test/std/numerics/complex.number/complex.transcendentals/pow_scalar_complex.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.transcendentals/pow_scalar_complex.pass.cpp @@ -34,29 +34,25 @@ test() test(T(2), std::complex(2), std::complex(4)); } -void test_edges() -{ - const unsigned N = sizeof(testcases) / sizeof(testcases[0]); - for (unsigned i = 0; i < N; ++i) - { - for (unsigned j = 0; j < N; ++j) - { - std::complex r = pow(real(testcases[i]), testcases[j]); - std::complex z = exp(testcases[j] * log(std::complex(real(testcases[i])))); - if (std::isnan(real(r))) - assert(std::isnan(real(z))); - else - { - assert(real(r) == real(z)); - } - if (std::isnan(imag(r))) - assert(std::isnan(imag(z))); - else - { - assert(imag(r) == imag(z)); - } - } +template +void test_edges() { + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); + for (unsigned i = 0; i < N; ++i) { + for (unsigned j = 0; j < N; ++j) { + std::complex r = pow(real(testcases[i]), testcases[j]); + std::complex z = exp(testcases[j] * log(std::complex(real(testcases[i])))); + if (std::isnan(real(r))) + assert(std::isnan(real(z))); + else { + assert(real(r) == real(z)); + } + if (std::isnan(imag(r))) + assert(std::isnan(imag(z))); + else { + assert(imag(r) == imag(z)); + } } + } } int main(int, char**) @@ -64,7 +60,9 @@ int main(int, char**) test(); test(); test(); - test_edges(); + test_edges(); + test_edges(); + test_edges(); - return 0; + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.transcendentals/sin.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.transcendentals/sin.pass.cpp index ceececa46f7cf..1876cf4437984 100644 --- a/libcxx/test/std/numerics/complex.number/complex.transcendentals/sin.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.transcendentals/sin.pass.cpp @@ -32,30 +32,27 @@ test() test(std::complex(0, 0), std::complex(0, 0)); } -void test_edges() -{ - const unsigned N = sizeof(testcases) / sizeof(testcases[0]); - for (unsigned i = 0; i < N; ++i) - { - std::complex r = sin(testcases[i]); - std::complex t1(-imag(testcases[i]), real(testcases[i])); - std::complex t2 = sinh(t1); - std::complex z(imag(t2), -real(t2)); - if (std::isnan(real(r))) - assert(std::isnan(real(z))); - else - { - assert(real(r) == real(z)); - assert(std::signbit(real(r)) == std::signbit(real(z))); - } - if (std::isnan(imag(r))) - assert(std::isnan(imag(z))); - else - { - assert(imag(r) == imag(z)); - assert(std::signbit(imag(r)) == std::signbit(imag(z))); - } +template +void test_edges() { + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); + for (unsigned i = 0; i < N; ++i) { + std::complex r = sin(testcases[i]); + std::complex t1(-imag(testcases[i]), real(testcases[i])); + std::complex t2 = sinh(t1); + std::complex z(imag(t2), -real(t2)); + if (std::isnan(real(r))) + assert(std::isnan(real(z))); + else { + assert(real(r) == real(z)); + assert(std::signbit(real(r)) == std::signbit(real(z))); + } + if (std::isnan(imag(r))) + assert(std::isnan(imag(z))); + else { + assert(imag(r) == imag(z)); + assert(std::signbit(imag(r)) == std::signbit(imag(z))); } + } } int main(int, char**) @@ -63,7 +60,9 @@ int main(int, char**) test(); test(); test(); - test_edges(); + test_edges(); + test_edges(); + test_edges(); - return 0; + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.transcendentals/sinh.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.transcendentals/sinh.pass.cpp index 933ff71d8a09b..cf38b6aa7d91c 100644 --- a/libcxx/test/std/numerics/complex.number/complex.transcendentals/sinh.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.transcendentals/sinh.pass.cpp @@ -32,80 +32,61 @@ test() test(std::complex(0, 0), std::complex(0, 0)); } -void test_edges() -{ - const unsigned N = sizeof(testcases) / sizeof(testcases[0]); - for (unsigned i = 0; i < N; ++i) - { - std::complex r = sinh(testcases[i]); - if (testcases[i].real() == 0 && testcases[i].imag() == 0) - { - assert(r.real() == 0); - assert(std::signbit(r.real()) == std::signbit(testcases[i].real())); - assert(r.imag() == 0); - assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); - } - else if (testcases[i].real() == 0 && std::isinf(testcases[i].imag())) - { - assert(r.real() == 0); - assert(std::isnan(r.imag())); - } - else if (std::isfinite(testcases[i].real()) && std::isinf(testcases[i].imag())) - { - assert(std::isnan(r.real())); - assert(std::isnan(r.imag())); - } - else if (testcases[i].real() == 0 && std::isnan(testcases[i].imag())) - { - assert(r.real() == 0); - assert(std::isnan(r.imag())); - } - else if (std::isfinite(testcases[i].real()) && std::isnan(testcases[i].imag())) - { - assert(std::isnan(r.real())); - assert(std::isnan(r.imag())); - } - else if (std::isinf(testcases[i].real()) && testcases[i].imag() == 0) - { - assert(std::isinf(r.real())); - assert(std::signbit(r.real()) == std::signbit(testcases[i].real())); - assert(r.imag() == 0); - assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); - } - else if (std::isinf(testcases[i].real()) && std::isfinite(testcases[i].imag())) - { - assert(std::isinf(r.real())); - assert(std::signbit(r.real()) == std::signbit(testcases[i].real() * cos(testcases[i].imag()))); - assert(std::isinf(r.imag())); - assert(std::signbit(r.imag()) == std::signbit(sin(testcases[i].imag()))); - } - else if (std::isinf(testcases[i].real()) && std::isinf(testcases[i].imag())) - { - assert(std::isinf(r.real())); - assert(std::isnan(r.imag())); - } - else if (std::isinf(testcases[i].real()) && std::isnan(testcases[i].imag())) - { - assert(std::isinf(r.real())); - assert(std::isnan(r.imag())); - } - else if (std::isnan(testcases[i].real()) && testcases[i].imag() == 0) - { - assert(std::isnan(r.real())); - assert(r.imag() == 0); - assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); - } - else if (std::isnan(testcases[i].real()) && std::isfinite(testcases[i].imag())) - { - assert(std::isnan(r.real())); - assert(std::isnan(r.imag())); - } - else if (std::isnan(testcases[i].real()) && std::isnan(testcases[i].imag())) - { - assert(std::isnan(r.real())); - assert(std::isnan(r.imag())); - } +template +void test_edges() { + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); + for (unsigned i = 0; i < N; ++i) { + std::complex r = sinh(testcases[i]); + if (testcases[i].real() == 0 && testcases[i].imag() == 0) { + assert(r.real() == 0); + assert(std::signbit(r.real()) == std::signbit(testcases[i].real())); + assert(r.imag() == 0); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); + } else if (testcases[i].real() == 0 && std::isinf(testcases[i].imag())) { + assert(r.real() == 0); + assert(std::isnan(r.imag())); + } else if (std::isfinite(testcases[i].real()) && std::isinf(testcases[i].imag())) { + assert(std::isnan(r.real())); + assert(std::isnan(r.imag())); + } else if (testcases[i].real() == 0 && std::isnan(testcases[i].imag())) { + assert(r.real() == 0); + assert(std::isnan(r.imag())); + } else if (std::isfinite(testcases[i].real()) && std::isnan(testcases[i].imag())) { + assert(std::isnan(r.real())); + assert(std::isnan(r.imag())); + } else if (std::isinf(testcases[i].real()) && testcases[i].imag() == 0) { + assert(std::isinf(r.real())); + assert(std::signbit(r.real()) == std::signbit(testcases[i].real())); + assert(r.imag() == 0); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); + } else if (std::isinf(testcases[i].real()) && std::isfinite(testcases[i].imag())) { + assert(std::isinf(r.real())); + assert(std::signbit(r.real()) == std::signbit(testcases[i].real() * cos(testcases[i].imag()))); + assert(std::isinf(r.imag())); + assert(std::signbit(r.imag()) == std::signbit(sin(testcases[i].imag()))); + } else if (std::isinf(testcases[i].real()) && std::isinf(testcases[i].imag())) { + assert(std::isinf(r.real())); + assert(std::isnan(r.imag())); + } else if (std::isinf(testcases[i].real()) && std::isnan(testcases[i].imag())) { + assert(std::isinf(r.real())); + assert(std::isnan(r.imag())); + } else if (std::isnan(testcases[i].real()) && testcases[i].imag() == 0) { + assert(std::isnan(r.real())); + assert(r.imag() == 0); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); + } else if (std::isnan(testcases[i].real()) && std::isfinite(testcases[i].imag())) { + assert(std::isnan(r.real())); + assert(std::isnan(r.imag())); + } else if (std::isnan(testcases[i].real()) && std::isnan(testcases[i].imag())) { + assert(std::isnan(r.real())); + assert(std::isnan(r.imag())); + } else if (std::isfinite(testcases[i].real()) && std::isfinite(testcases[i].imag())) { + assert(!std::isnan(r.real())); + + bool const nan_okay = std::isinf(r.real()) && testcases[i].imag() == 0; // inf * 0 == NaN + assert(!std::isnan(r.imag()) || nan_okay); } + } } int main(int, char**) @@ -113,7 +94,9 @@ int main(int, char**) test(); test(); test(); - test_edges(); + test_edges(); + test_edges(); + test_edges(); - return 0; + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.transcendentals/sqrt.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.transcendentals/sqrt.pass.cpp index 12fd9a2c0440a..58b4ee2545852 100644 --- a/libcxx/test/std/numerics/complex.number/complex.transcendentals/sqrt.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.transcendentals/sqrt.pass.cpp @@ -14,6 +14,7 @@ #include #include +#include #include "test_macros.h" #include "../cases.h" @@ -34,70 +35,76 @@ test() test(std::complex(64, 0), std::complex(8, 0)); } -void test_edges() -{ - const unsigned N = sizeof(testcases) / sizeof(testcases[0]); - for (unsigned i = 0; i < N; ++i) - { - std::complex r = sqrt(testcases[i]); - if (testcases[i].real() == 0 && testcases[i].imag() == 0) - { - assert(!std::signbit(r.real())); - assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); - } - else if (std::isinf(testcases[i].imag())) - { - assert(std::isinf(r.real())); - assert(r.real() > 0); - assert(std::isinf(r.imag())); - assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); - } - else if (std::isfinite(testcases[i].real()) && std::isnan(testcases[i].imag())) - { - assert(std::isnan(r.real())); - assert(std::isnan(r.imag())); - } - else if (std::isinf(testcases[i].real()) && testcases[i].real() < 0 && std::isfinite(testcases[i].imag())) - { - assert(r.real() == 0); - assert(!std::signbit(r.real())); - assert(std::isinf(r.imag())); - assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); - } - else if (std::isinf(testcases[i].real()) && testcases[i].real() > 0 && std::isfinite(testcases[i].imag())) - { - assert(std::isinf(r.real())); - assert(r.real() > 0); - assert(r.imag() == 0); - assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); - } - else if (std::isinf(testcases[i].real()) && testcases[i].real() < 0 && std::isnan(testcases[i].imag())) - { - assert(std::isnan(r.real())); - assert(std::isinf(r.imag())); - } - else if (std::isinf(testcases[i].real()) && testcases[i].real() > 0 && std::isnan(testcases[i].imag())) - { - assert(std::isinf(r.real())); - assert(r.real() > 0); - assert(std::isnan(r.imag())); - } - else if (std::isnan(testcases[i].real()) && (std::isfinite(testcases[i].imag()) || std::isnan(testcases[i].imag()))) - { - assert(std::isnan(r.real())); - assert(std::isnan(r.imag())); - } - else if (std::signbit(testcases[i].imag())) - { - assert(!std::signbit(r.real())); - assert(std::signbit(r.imag())); - } - else - { - assert(!std::signbit(r.real())); - assert(!std::signbit(r.imag())); - } +// cosine calculations for std::arg terminate at different times based on the precision of T, +// and can produce a very small negative number instead of a very small positive one, so we +// should actually check that we're really close to zero instead of positive. +template +bool approaching_zero(const T value) { + auto in_range = [value](const T low, const T high) { return low < value && value < high; }; + if constexpr (std::is_same_v) { + return value == -0.0f || in_range(-4.38e-5f, 4.38e-5f); + } else if constexpr (std::is_same_v) { + return false; + } else if constexpr (std::is_same_v) { + return value == -0.0f || in_range(-3.0e-17L, 3.0e-17L); + } else { + std::abort(); + } +} + +template +void test_edges() { + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); + for (unsigned i = 0; i < N; ++i) { + std::complex r = sqrt(testcases[i]); + if (testcases[i].real() == 0 && testcases[i].imag() == 0) { + assert(!std::signbit(r.real()) || approaching_zero(r.real())); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); + } else if (std::isinf(testcases[i].imag())) { + assert(std::isinf(r.real())); + assert(r.real() > 0); + assert(std::isinf(r.imag())); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); + } else if (std::isfinite(testcases[i].real()) && std::isnan(testcases[i].imag())) { + assert(std::isnan(r.real())); + assert(std::isnan(r.imag())); + } else if (std::isinf(testcases[i].real()) && testcases[i].real() < 0 && + std::isfinite(testcases[i].imag())) { + assert(r.real() == 0); + assert(!std::signbit(r.real())); + assert(std::isinf(r.imag())); + assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); + } else if (std::isinf(testcases[i].real()) && testcases[i].real() > 0 && + std::isfinite(testcases[i].imag())) { + assert(std::isinf(r.real())); + assert(r.real() > 0); + assert(r.imag() == 0); + assert(std::signbit(testcases[i].imag()) == std::signbit(r.imag())); + } else if (std::isinf(testcases[i].real()) && testcases[i].real() < 0 && std::isnan(testcases[i].imag())) { + assert(std::isnan(r.real())); + assert(std::isinf(r.imag())); + } else if (std::isinf(testcases[i].real()) && testcases[i].real() > 0 && std::isnan(testcases[i].imag())) { + assert(std::isinf(r.real())); + assert(r.real() > 0); + assert(std::isnan(r.imag())); + } else if (std::isnan(testcases[i].real()) && + (std::isfinite(testcases[i].imag()) || std::isnan(testcases[i].imag()))) { + assert(std::isnan(r.real())); + assert(std::isnan(r.imag())); + } else if (std::signbit(testcases[i].imag())) { + // FIXME(https://github.com/llvm/llvm-project/issues/122172): move `expected_pass` into + // assert once #122172 is fixed. + const bool expected_pass = !std::signbit(r.real()) || approaching_zero(r.real()); + assert((i != 156 || std::is_same::value) ? expected_pass : !expected_pass); + assert(std::signbit(r.imag())); + } else { + // FIXME(https://github.com/llvm/llvm-project/issues/122172): move `expected_pass` into + // assert once #122172 is fixed. + const bool expected_pass = !std::signbit(r.real()) || approaching_zero(r.real()); + assert((i != 155 || std::is_same::value) ? expected_pass : !expected_pass); + assert(!std::signbit(r.imag())); } + } } int main(int, char**) @@ -105,7 +112,9 @@ int main(int, char**) test(); test(); test(); - test_edges(); + test_edges(); + test_edges(); + test_edges(); - return 0; + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.transcendentals/tan.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.transcendentals/tan.pass.cpp index 5c1f61ef644d3..5b881fe8f3f07 100644 --- a/libcxx/test/std/numerics/complex.number/complex.transcendentals/tan.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.transcendentals/tan.pass.cpp @@ -33,30 +33,27 @@ test() test(std::complex(10000, -10000), std::complex(0, -1)); } -void test_edges() -{ - const unsigned N = sizeof(testcases) / sizeof(testcases[0]); - for (unsigned i = 0; i < N; ++i) - { - std::complex r = tan(testcases[i]); - std::complex t1(-imag(testcases[i]), real(testcases[i])); - std::complex t2 = tanh(t1); - std::complex z(imag(t2), -real(t2)); - if (std::isnan(real(r))) - assert(std::isnan(real(z))); - else - { - assert(real(r) == real(z)); - assert(std::signbit(real(r)) == std::signbit(real(z))); - } - if (std::isnan(imag(r))) - assert(std::isnan(imag(z))); - else - { - assert(imag(r) == imag(z)); - assert(std::signbit(imag(r)) == std::signbit(imag(z))); - } +template +void test_edges() { + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); + for (unsigned i = 0; i < N; ++i) { + std::complex r = tan(testcases[i]); + std::complex t1(-imag(testcases[i]), real(testcases[i])); + std::complex t2 = tanh(t1); + std::complex z(imag(t2), -real(t2)); + if (std::isnan(real(r))) + assert(std::isnan(real(z))); + else { + assert(real(r) == real(z)); + assert(std::signbit(real(r)) == std::signbit(real(z))); + } + if (std::isnan(imag(r))) + assert(std::isnan(imag(z))); + else { + assert(imag(r) == imag(z)); + assert(std::signbit(imag(r)) == std::signbit(imag(z))); } + } } int main(int, char**) @@ -64,7 +61,9 @@ int main(int, char**) test(); test(); test(); - test_edges(); + test_edges(); + test_edges(); + test_edges(); - return 0; + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.transcendentals/tanh.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.transcendentals/tanh.pass.cpp index f48cc88c6a38d..5d9b64923938b 100644 --- a/libcxx/test/std/numerics/complex.number/complex.transcendentals/tanh.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.transcendentals/tanh.pass.cpp @@ -32,62 +32,48 @@ test() test(std::complex(0, 0), std::complex(0, 0)); } -void test_edges() -{ - const unsigned N = sizeof(testcases) / sizeof(testcases[0]); - for (unsigned i = 0; i < N; ++i) - { - std::complex r = tanh(testcases[i]); - if (testcases[i].real() == 0 && testcases[i].imag() == 0) - { - assert(r.real() == 0); - assert(std::signbit(r.real()) == std::signbit(testcases[i].real())); - assert(r.imag() == 0); - assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); - } - else if (std::isfinite(testcases[i].real()) && std::isinf(testcases[i].imag())) - { - assert(std::isnan(r.real())); - assert(std::isnan(r.imag())); - } - else if (std::isfinite(testcases[i].real()) && std::isnan(testcases[i].imag())) - { - assert(std::isnan(r.real())); - assert(std::isnan(r.imag())); - } - else if (std::isinf(testcases[i].real()) && std::isfinite(testcases[i].imag())) - { - assert(r.real() == (testcases[i].real() > 0 ? 1 : -1)); - assert(r.imag() == 0); - assert(std::signbit(r.imag()) == std::signbit(sin(2 * testcases[i].imag()))); - } - else if (std::isinf(testcases[i].real()) && std::isinf(testcases[i].imag())) - { - assert(r.real() == (testcases[i].real() > 0 ? 1 : -1)); - assert(r.imag() == 0); - } - else if (std::isinf(testcases[i].real()) && std::isnan(testcases[i].imag())) - { - assert(r.real() == (testcases[i].real() > 0 ? 1 : -1)); - assert(r.imag() == 0); - } - else if (std::isnan(testcases[i].real()) && testcases[i].imag() == 0) - { - assert(std::isnan(r.real())); - assert(r.imag() == 0); - assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); - } - else if (std::isnan(testcases[i].real()) && std::isfinite(testcases[i].imag())) - { - assert(std::isnan(r.real())); - assert(std::isnan(r.imag())); - } - else if (std::isnan(testcases[i].real()) && std::isnan(testcases[i].imag())) - { - assert(std::isnan(r.real())); - assert(std::isnan(r.imag())); - } +template +void test_edges() { + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); + for (unsigned i = 0; i < N; ++i) { + std::complex r = tanh(testcases[i]); + if (testcases[i].real() == 0 && testcases[i].imag() == 0) { + assert(r.real() == 0); + assert(std::signbit(r.real()) == std::signbit(testcases[i].real())); + assert(r.imag() == 0); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); + } else if (std::isfinite(testcases[i].real()) && std::isinf(testcases[i].imag())) { + assert(std::isnan(r.real())); + assert(std::isnan(r.imag())); + } else if (std::isfinite(testcases[i].real()) && std::isnan(testcases[i].imag())) { + assert(std::isnan(r.real())); + assert(std::isnan(r.imag())); + } else if (std::isinf(testcases[i].real()) && std::isfinite(testcases[i].imag())) { + assert(r.real() == (testcases[i].real() > 0 ? 1 : -1)); + assert(r.imag() == 0); + assert(std::signbit(r.imag()) == std::signbit(sin(2 * testcases[i].imag()))); + } else if (std::isinf(testcases[i].real()) && std::isinf(testcases[i].imag())) { + assert(r.real() == (testcases[i].real() > 0 ? 1 : -1)); + assert(r.imag() == 0); + } else if (std::isinf(testcases[i].real()) && std::isnan(testcases[i].imag())) { + assert(r.real() == (testcases[i].real() > 0 ? 1 : -1)); + assert(r.imag() == 0); + } else if (std::isnan(testcases[i].real()) && testcases[i].imag() == 0) { + assert(std::isnan(r.real())); + assert(r.imag() == 0); + assert(std::signbit(r.imag()) == std::signbit(testcases[i].imag())); + } else if (std::isnan(testcases[i].real()) && std::isfinite(testcases[i].imag())) { + assert(std::isnan(r.real())); + assert(std::isnan(r.imag())); + } else if (std::isnan(testcases[i].real()) && std::isnan(testcases[i].imag())) { + assert(std::isnan(r.real())); + assert(std::isnan(r.imag())); + } else if (std::isfinite(testcases[i].real()) && std::isfinite(testcases[i].imag())) { + [[maybe_unused]] auto const x = testcases[i]; + assert(!std::isnan(r.real())); + assert(!std::isnan(r.imag())); } + } } int main(int, char**) @@ -95,7 +81,9 @@ int main(int, char**) test(); test(); test(); - test_edges(); + test_edges(); + test_edges(); + test_edges(); - return 0; + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.value.ops/abs.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.value.ops/abs.pass.cpp index d5ed2a6ba148c..2f56e7d621c56 100644 --- a/libcxx/test/std/numerics/complex.number/complex.value.ops/abs.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.value.ops/abs.pass.cpp @@ -26,32 +26,44 @@ test() assert(abs(z) == 5); } -void test_edges() -{ - const unsigned N = sizeof(testcases) / sizeof(testcases[0]); - for (unsigned i = 0; i < N; ++i) - { - double r = abs(testcases[i]); - switch (classify(testcases[i])) - { - case zero: - assert(r == 0); - assert(!std::signbit(r)); - break; - case non_zero: - assert(std::isfinite(r) && r > 0); - break; - case inf: - assert(std::isinf(r) && r > 0); - break; - case NaN: - assert(std::isnan(r)); - break; - case non_zero_nan: - assert(std::isnan(r)); - break; - } +template +void test_edges() { + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); + for (unsigned i = 0; i < N; ++i) { + T r = abs(testcases[i]); + switch (classify(testcases[i])) { + case zero: + assert(r == 0); + assert(!std::signbit(r)); + break; + case lowest_value: { + // It appears that `lowest - relatively_small_number == lowest`, so we check to + // make sure that abs was actually effective before asserting that it should be infinity. + bool const ineffective_abs = testcases[i].real() + testcases[i].imag() == -r; + assert((std::isinf(r) && r > 0) || ineffective_abs); + break; + } + case maximum_value: { + // It appears that `max + relatively_small_number == max`, so we check to + // make sure that abs was actually effective before asserting that it should be infinity. + bool const ineffective_abs = testcases[i].real() + testcases[i].imag() == r; + assert((std::isinf(r) && r > 0) || ineffective_abs); + break; + } + case non_zero: + assert(std::isfinite(r) && r > 0); + break; + case inf: + assert(std::isinf(r) && r > 0); + break; + case NaN: + assert(std::isnan(r)); + break; + case non_zero_nan: + assert(std::isnan(r)); + break; } + } } int main(int, char**) @@ -59,7 +71,9 @@ int main(int, char**) test(); test(); test(); - test_edges(); + test_edges(); + test_edges(); + test_edges(); - return 0; + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.value.ops/arg.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.value.ops/arg.pass.cpp index 49c54372a8e00..40e2a4940d273 100644 --- a/libcxx/test/std/numerics/complex.number/complex.value.ops/arg.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.value.ops/arg.pass.cpp @@ -26,104 +26,82 @@ test() assert(arg(z) == 0); } -void test_edges() -{ - const double pi = std::atan2(+0., -0.); - const unsigned N = sizeof(testcases) / sizeof(testcases[0]); - for (unsigned i = 0; i < N; ++i) - { - double r = arg(testcases[i]); - if (std::isnan(testcases[i].real()) || std::isnan(testcases[i].imag())) - assert(std::isnan(r)); +template +void test_edges() { + const T pi = std::atan2(T(+0.), T(-0.)); + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); + for (unsigned i = 0; i < N; ++i) { + T r = arg(testcases[i]); + if (std::isnan(testcases[i].real()) || std::isnan(testcases[i].imag())) + assert(std::isnan(r)); + else { + switch (classify(testcases[i])) { + case zero: + if (std::signbit(testcases[i].real())) { + if (std::signbit(testcases[i].imag())) + is_about(r, -pi); + else + is_about(r, pi); + } else { + assert(std::signbit(testcases[i].imag()) == std::signbit(r)); + } + break; + case lowest_value: + case maximum_value: + case non_zero: + if (testcases[i].real() == 0) { + if (testcases[i].imag() < 0) + is_about(r, -pi / 2); + else + is_about(r, pi / 2); + } else if (testcases[i].imag() == 0) { + if (testcases[i].real() < 0) { + if (std::signbit(testcases[i].imag())) + is_about(r, -pi); + else + is_about(r, pi); + } else { + assert(r == 0); + assert(std::signbit(testcases[i].imag()) == std::signbit(r)); + } + } else if (testcases[i].imag() > 0) + assert(r > 0); else - { - switch (classify(testcases[i])) - { - case zero: - if (std::signbit(testcases[i].real())) - { - if (std::signbit(testcases[i].imag())) - is_about(r, -pi); - else - is_about(r, pi); - } - else - { - assert(std::signbit(testcases[i].imag()) == std::signbit(r)); - } - break; - case non_zero: - if (testcases[i].real() == 0) - { - if (testcases[i].imag() < 0) - is_about(r, -pi/2); - else - is_about(r, pi/2); - } - else if (testcases[i].imag() == 0) - { - if (testcases[i].real() < 0) - { - if (std::signbit(testcases[i].imag())) - is_about(r, -pi); - else - is_about(r, pi); - } - else - { - assert(r == 0); - assert(std::signbit(testcases[i].imag()) == std::signbit(r)); - } - } - else if (testcases[i].imag() > 0) - assert(r > 0); - else - assert(r < 0); - break; - case inf: - if (std::isinf(testcases[i].real()) && std::isinf(testcases[i].imag())) - { - if (testcases[i].real() < 0) - { - if (testcases[i].imag() > 0) - is_about(r, 0.75 * pi); - else - is_about(r, -0.75 * pi); - } - else - { - if (testcases[i].imag() > 0) - is_about(r, 0.25 * pi); - else - is_about(r, -0.25 * pi); - } - } - else if (std::isinf(testcases[i].real())) - { - if (testcases[i].real() < 0) - { - if (std::signbit(testcases[i].imag())) - is_about(r, -pi); - else - is_about(r, pi); - } - else - { - assert(r == 0); - assert(std::signbit(r) == std::signbit(testcases[i].imag())); - } - } - else - { - if (testcases[i].imag() < 0) - is_about(r, -pi/2); - else - is_about(r, pi/2); - } - break; - } + assert(r < 0); + break; + case inf: + if (std::isinf(testcases[i].real()) && std::isinf(testcases[i].imag())) { + if (testcases[i].real() < 0) { + if (testcases[i].imag() > 0) + is_about(r, T(0.75) * pi); + else + is_about(r, T(-0.75) * pi); + } else { + if (testcases[i].imag() > 0) + is_about(r, T(0.25) * pi); + else + is_about(r, T(-0.25) * pi); + } + } else if (std::isinf(testcases[i].real())) { + if (testcases[i].real() < 0) { + if (std::signbit(testcases[i].imag())) + is_about(r, -pi); + else + is_about(r, pi); + } else { + assert(r == 0); + assert(std::signbit(r) == std::signbit(testcases[i].imag())); + } + } else { + if (testcases[i].imag() < 0) + is_about(r, -pi / 2); + else + is_about(r, pi / 2); } + break; + } } + } } int main(int, char**) @@ -131,7 +109,9 @@ int main(int, char**) test(); test(); test(); - test_edges(); + test_edges(); + test_edges(); + test_edges(); - return 0; + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.value.ops/norm.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.value.ops/norm.pass.cpp index 6e6dc10f1928d..f0d481d50617e 100644 --- a/libcxx/test/std/numerics/complex.number/complex.value.ops/norm.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.value.ops/norm.pass.cpp @@ -26,32 +26,32 @@ test() assert(norm(z) == 25); } -void test_edges() -{ - const unsigned N = sizeof(testcases) / sizeof(testcases[0]); - for (unsigned i = 0; i < N; ++i) - { - double r = norm(testcases[i]); - switch (classify(testcases[i])) - { - case zero: - assert(r == 0); - assert(!std::signbit(r)); - break; - case non_zero: - assert(std::isfinite(r) && r > 0); - break; - case inf: - assert(std::isinf(r) && r > 0); - break; - case NaN: - assert(std::isnan(r)); - break; - case non_zero_nan: - assert(std::isnan(r)); - break; - } +template +void test_edges() { + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); + for (unsigned i = 0; i < N; ++i) { + T r = norm(testcases[i]); + switch (classify(testcases[i])) { + case zero: + assert(r == 0); + assert(!std::signbit(r)); + break; + case non_zero: + assert(std::isfinite(r) && r > 0); + break; + case lowest_value: + case maximum_value: + case inf: + assert(std::isinf(r) && r > 0); + break; + case NaN: + assert(std::isnan(r)); + break; + case non_zero_nan: + assert(std::isnan(r)); + break; } + } } int main(int, char**) @@ -59,7 +59,9 @@ int main(int, char**) test(); test(); test(); - test_edges(); + test_edges(); + test_edges(); + test_edges(); - return 0; + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.value.ops/polar.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.value.ops/polar.pass.cpp index 2b9c764abb591..91c5f439dcfdd 100644 --- a/libcxx/test/std/numerics/complex.number/complex.value.ops/polar.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.value.ops/polar.pass.cpp @@ -44,63 +44,51 @@ test() test(T(100), T(0), std::complex(100, 0)); } -void test_edges() -{ - const unsigned N = sizeof(testcases) / sizeof(testcases[0]); - for (unsigned i = 0; i < N; ++i) - { - double r = real(testcases[i]); - double theta = imag(testcases[i]); - std::complex z = std::polar(r, theta); - switch (classify(r)) - { - case zero: - if (std::signbit(r) || classify(theta) == inf || classify(theta) == NaN) - { - int c = classify(z); - assert(c == NaN || c == non_zero_nan); - } - else - { - assert(z == std::complex()); - } - break; - case non_zero: - if (std::signbit(r) || classify(theta) == inf || classify(theta) == NaN) - { - int c = classify(z); - assert(c == NaN || c == non_zero_nan); - } - else - { - is_about(std::abs(z), r); - } - break; - case inf: - if (r < 0) - { - int c = classify(z); - assert(c == NaN || c == non_zero_nan); - } - else - { - assert(classify(z) == inf); - if (classify(theta) != NaN && classify(theta) != inf) - { - assert(classify(real(z)) != NaN); - assert(classify(imag(z)) != NaN); - } - } - break; - case NaN: - case non_zero_nan: - { - int c = classify(z); - assert(c == NaN || c == non_zero_nan); - } - break; +template +void test_edges() { + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); + for (unsigned i = 0; i < N; ++i) { + T r = real(testcases[i]); + T theta = imag(testcases[i]); + std::complex z = std::polar(r, theta); + switch (classify(r)) { + case zero: + if (std::signbit(r) || classify(theta) == inf || classify(theta) == NaN) { + int c = classify(z); + assert(c == NaN || c == non_zero_nan); + } else { + assert(z == std::complex()); + } + break; + case lowest_value: + case maximum_value: + case non_zero: + if (std::signbit(r) || classify(theta) == inf || classify(theta) == NaN) { + int c = classify(z); + assert(c == NaN || c == non_zero_nan); + } else { + is_about(std::abs(z), r); + } + break; + case inf: + if (r < 0) { + int c = classify(z); + assert(c == NaN || c == non_zero_nan); + } else { + assert(classify(z) == inf); + if (classify(theta) != NaN && classify(theta) != inf) { + assert(classify(real(z)) != NaN); + assert(classify(imag(z)) != NaN); } + } + break; + case NaN: + case non_zero_nan: { + int c = classify(z); + assert(c == NaN || c == non_zero_nan); + } break; } + } } int main(int, char**) @@ -108,7 +96,9 @@ int main(int, char**) test(); test(); test(); - test_edges(); + test_edges(); + test_edges(); + test_edges(); - return 0; + return 0; } diff --git a/libcxx/test/std/numerics/complex.number/complex.value.ops/proj.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.value.ops/proj.pass.cpp index e118613b8dd31..91fc87fc14cc9 100644 --- a/libcxx/test/std/numerics/complex.number/complex.value.ops/proj.pass.cpp +++ b/libcxx/test/std/numerics/complex.number/complex.value.ops/proj.pass.cpp @@ -35,31 +35,31 @@ test() test(std::complex(-1, -2), std::complex(-1, -2)); } -void test_edges() -{ - const unsigned N = sizeof(testcases) / sizeof(testcases[0]); - for (unsigned i = 0; i < N; ++i) - { - std::complex r = proj(testcases[i]); - switch (classify(testcases[i])) - { - case zero: - case non_zero: - assert(r == testcases[i]); - assert(std::signbit(real(r)) == std::signbit(real(testcases[i]))); - assert(std::signbit(imag(r)) == std::signbit(imag(testcases[i]))); - break; - case inf: - assert(std::isinf(real(r)) && real(r) > 0); - assert(imag(r) == 0); - assert(std::signbit(imag(r)) == std::signbit(imag(testcases[i]))); - break; - case NaN: - case non_zero_nan: - assert(classify(r) == classify(testcases[i])); - break; - } +template +void test_edges() { + const unsigned N = sizeof(testcases) / sizeof(testcases[0]); + for (unsigned i = 0; i < N; ++i) { + std::complex r = proj(testcases[i]); + switch (classify(testcases[i])) { + case zero: + case non_zero: + case lowest_value: + case maximum_value: + assert(r == testcases[i]); + assert(std::signbit(real(r)) == std::signbit(real(testcases[i]))); + assert(std::signbit(imag(r)) == std::signbit(imag(testcases[i]))); + break; + case inf: + assert(std::isinf(real(r)) && real(r) > 0); + assert(imag(r) == 0); + assert(std::signbit(imag(r)) == std::signbit(imag(testcases[i]))); + break; + case NaN: + case non_zero_nan: + assert(classify(r) == classify(testcases[i])); + break; } + } } int main(int, char**) @@ -67,7 +67,9 @@ int main(int, char**) test(); test(); test(); - test_edges(); + test_edges(); + test_edges(); + test_edges(); - return 0; + return 0; }