diff --git a/include/boost/math/complex/acos.hpp b/include/boost/math/complex/acos.hpp index a023f4123..466dcc63f 100644 --- a/include/boost/math/complex/acos.hpp +++ b/include/boost/math/complex/acos.hpp @@ -38,11 +38,15 @@ std::complex acos(const std::complex& z) static const T half = static_cast(0.5L); static const T a_crossover = static_cast(1.5L); static const T b_crossover = static_cast(0.6417L); - static const T s_pi = static_cast(3.141592653589793238462643383279502884197L); - static const T half_pi = static_cast(1.57079632679489661923132169163975144L); - static const T log_two = static_cast(0.69314718055994530941723212145817657L); - static const T quarter_pi = static_cast(0.78539816339744830961566084581987572L); + static const T s_pi = boost::math::constants::pi(); + static const T half_pi = s_pi / 2; + static const T log_two = boost::math::constants::ln_two(); + static const T quarter_pi = s_pi / 4; +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable:4127) +#endif // // Get real and imaginary parts, discard the signs as we can // figure out the sign of the result later: @@ -58,14 +62,14 @@ std::complex acos(const std::complex& z) // but doing it this way prevents overflow/underflow arithmetic // in the main body of the logic, which may trip up some machines: // - if(std::numeric_limits::has_infinity && (x == std::numeric_limits::infinity())) + if((boost::math::isinf)(x)) { - if(y == std::numeric_limits::infinity()) + if((boost::math::isinf)(y)) { real = quarter_pi; imag = std::numeric_limits::infinity(); } - else if(detail::test_is_nan(y)) + else if((boost::math::isnan)(y)) { return std::complex(y, -std::numeric_limits::infinity()); } @@ -76,18 +80,18 @@ std::complex acos(const std::complex& z) imag = std::numeric_limits::infinity(); } } - else if(detail::test_is_nan(x)) + else if((boost::math::isnan)(x)) { - if(y == std::numeric_limits::infinity()) - return std::complex(x, (z.imag() < 0) ? std::numeric_limits::infinity() : -std::numeric_limits::infinity()); + if((boost::math::isinf)(y)) + return std::complex(x, ((boost::math::signbit)(z.imag())) ? std::numeric_limits::infinity() : -std::numeric_limits::infinity()); return std::complex(x, x); } - else if(std::numeric_limits::has_infinity && (y == std::numeric_limits::infinity())) + else if((boost::math::isinf)(y)) { real = half_pi; imag = std::numeric_limits::infinity(); } - else if(detail::test_is_nan(y)) + else if((boost::math::isnan)(y)) { return std::complex((x == 0) ? half_pi : y, y); } @@ -98,7 +102,7 @@ std::complex acos(const std::complex& z) // begin with the special case for real numbers: // if((y == 0) && (x <= one)) - return std::complex((x == 0) ? half_pi : std::acos(z.real())); + return std::complex((x == 0) ? half_pi : std::acos(z.real()), (boost::math::changesign)(z.imag())); // // Figure out if our input is within the "safe area" identified by Hull et al. // This would be more efficient with portable floating point exception handling; @@ -222,12 +226,15 @@ std::complex acos(const std::complex& z) // // Finish off by working out the sign of the result: // - if(z.real() < 0) + if((boost::math::signbit)(z.real())) real = s_pi - real; - if(z.imag() > 0) - imag = -imag; + if(!(boost::math::signbit)(z.imag())) + imag = (boost::math::changesign)(imag); return std::complex(real, imag); +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif } } } // namespaces diff --git a/include/boost/math/complex/acosh.hpp b/include/boost/math/complex/acosh.hpp index 24ed1f12f..4f987cbee 100644 --- a/include/boost/math/complex/acosh.hpp +++ b/include/boost/math/complex/acosh.hpp @@ -24,7 +24,7 @@ inline std::complex acosh(const std::complex& z) // as well as compatibility with C99. // std::complex result = boost::math::acos(z); - if(!detail::test_is_nan(result.imag()) && result.imag() <= 0) + if(!(boost::math::isnan)(result.imag()) && signbit(result.imag())) return detail::mult_i(result); return detail::mult_minus_i(result); } diff --git a/include/boost/math/complex/asin.hpp b/include/boost/math/complex/asin.hpp index 57c1dfc2a..1d2079521 100644 --- a/include/boost/math/complex/asin.hpp +++ b/include/boost/math/complex/asin.hpp @@ -38,11 +38,14 @@ inline std::complex asin(const std::complex& z) static const T half = static_cast(0.5L); static const T a_crossover = static_cast(1.5L); static const T b_crossover = static_cast(0.6417L); - //static const T pi = static_cast(3.141592653589793238462643383279502884197L); - static const T half_pi = static_cast(1.57079632679489661923132169163975144L); - static const T log_two = static_cast(0.69314718055994530941723212145817657L); - static const T quarter_pi = static_cast(0.78539816339744830961566084581987572L); - + static const T s_pi = boost::math::constants::pi(); + static const T half_pi = s_pi / 2; + static const T log_two = boost::math::constants::ln_two(); + static const T quarter_pi = s_pi / 4; +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable:4127) +#endif // // Get real and imaginary parts, discard the signs as we can // figure out the sign of the result later: @@ -57,11 +60,11 @@ inline std::complex asin(const std::complex& z) // below, but handling it as a special case prevents overflow/underflow // arithmetic which may trip up some machines: // - if(detail::test_is_nan(x)) + if((boost::math::isnan)(x)) { - if(detail::test_is_nan(y)) + if((boost::math::isnan)(y)) return std::complex(x, x); - if(std::numeric_limits::has_infinity && (y == std::numeric_limits::infinity())) + if((boost::math::isinf)(y)) { real = x; imag = std::numeric_limits::infinity(); @@ -69,14 +72,14 @@ inline std::complex asin(const std::complex& z) else return std::complex(x, x); } - else if(detail::test_is_nan(y)) + else if((boost::math::isnan)(y)) { if(x == 0) { real = 0; imag = y; } - else if(std::numeric_limits::has_infinity && (x == std::numeric_limits::infinity())) + else if((boost::math::isinf)(x)) { real = y; imag = std::numeric_limits::infinity(); @@ -84,9 +87,9 @@ inline std::complex asin(const std::complex& z) else return std::complex(y, y); } - else if(std::numeric_limits::has_infinity && (x == std::numeric_limits::infinity())) + else if((boost::math::isinf)(x)) { - if(y == std::numeric_limits::infinity()) + if((boost::math::isinf)(y)) { real = quarter_pi; imag = std::numeric_limits::infinity(); @@ -97,7 +100,7 @@ inline std::complex asin(const std::complex& z) imag = std::numeric_limits::infinity(); } } - else if(std::numeric_limits::has_infinity && (y == std::numeric_limits::infinity())) + else if((boost::math::isinf)(y)) { real = 0; imag = std::numeric_limits::infinity(); @@ -108,7 +111,7 @@ inline std::complex asin(const std::complex& z) // special case for real numbers: // if((y == 0) && (x <= one)) - return std::complex(std::asin(z.real())); + return std::complex(std::asin(z.real()), z.imag()); // // Figure out if our input is within the "safe area" identified by Hull et al. // This would be more efficient with portable floating point exception handling; @@ -174,7 +177,7 @@ inline std::complex asin(const std::complex& z) if(x < one) { real = std::asin(x); - imag = y / std::sqrt(xp1*xm1); + imag = y / std::sqrt(-xp1*xm1); } else { @@ -232,12 +235,15 @@ inline std::complex asin(const std::complex& z) // // Finish off by working out the sign of the result: // - if(z.real() < 0) - real = -real; - if(z.imag() < 0) - imag = -imag; + if((boost::math::signbit)(z.real())) + real = (boost::math::changesign)(real); + if((boost::math::signbit)(z.imag())) + imag = (boost::math::changesign)(imag); return std::complex(real, imag); +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif } } } // namespaces diff --git a/include/boost/math/complex/atanh.hpp b/include/boost/math/complex/atanh.hpp index 438243701..4ecb4e199 100644 --- a/include/boost/math/complex/atanh.hpp +++ b/include/boost/math/complex/atanh.hpp @@ -37,14 +37,19 @@ std::complex atanh(const std::complex& z) // at : http://jove.prohosting.com/~skripty/toc.htm // - static const T half_pi = static_cast(1.57079632679489661923132169163975144L); - static const T pi = static_cast(3.141592653589793238462643383279502884197L); + static const T pi = boost::math::constants::pi(); + static const T half_pi = pi / 2; static const T one = static_cast(1.0L); static const T two = static_cast(2.0L); static const T four = static_cast(4.0L); static const T zero = static_cast(0); static const T a_crossover = static_cast(0.3L); +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable:4127) +#endif + T x = std::fabs(z.real()); T y = std::fabs(z.imag()); @@ -56,20 +61,20 @@ std::complex atanh(const std::complex& z) // // Begin by handling the special cases specified in C99: // - if(detail::test_is_nan(x)) + if((boost::math::isnan)(x)) { - if(detail::test_is_nan(y)) + if((boost::math::isnan)(y)) return std::complex(x, x); - else if(std::numeric_limits::has_infinity && (y == std::numeric_limits::infinity())) - return std::complex(0, ((z.imag() < 0) ? -half_pi : half_pi)); + else if((boost::math::isinf)(y)) + return std::complex(0, ((boost::math::signbit)(z.imag()) ? -half_pi : half_pi)); else return std::complex(x, x); } - else if(detail::test_is_nan(y)) + else if((boost::math::isnan)(y)) { if(x == 0) return std::complex(x, y); - if(std::numeric_limits::has_infinity && (x == std::numeric_limits::infinity())) + if((boost::math::isinf)(x)) return std::complex(0, y); else return std::complex(y, y); @@ -104,7 +109,7 @@ std::complex atanh(const std::complex& z) T alpha = two*x / (one + xx + yy); if(alpha < a_crossover) { - real = boost::math::log1p(alpha) - boost::math::log1p(-alpha); + real = boost::math::log1p(alpha) - boost::math::log1p((boost::math::changesign)(alpha)); } else { @@ -112,13 +117,13 @@ std::complex atanh(const std::complex& z) real = boost::math::log1p(x2 + xx + yy) - std::log(xm1*xm1 + yy); } real /= four; - if(z.real() < 0) - real = -real; + if((boost::math::signbit)(z.real())) + real = (boost::math::changesign)(real); imag = std::atan2((y * two), (one - xx - yy)); imag /= two; if(z.imag() < 0) - imag = -imag; + imag = (boost::math::changesign)(imag); } else { @@ -133,9 +138,7 @@ std::complex atanh(const std::complex& z) T alpha = 0; if(x >= safe_upper) { - // this is really a test for infinity, - // but we may not have the necessary numeric_limits support: - if((x > (std::numeric_limits::max)()) || (y > (std::numeric_limits::max)())) + if((boost::math::isinf)(x) || (boost::math::isinf)(y)) { alpha = 0; } @@ -180,7 +183,7 @@ std::complex atanh(const std::complex& z) } if(alpha < a_crossover) { - real = boost::math::log1p(alpha) - boost::math::log1p(-alpha); + real = boost::math::log1p(alpha) - boost::math::log1p((boost::math::changesign)(alpha)); } else { @@ -194,8 +197,8 @@ std::complex atanh(const std::complex& z) } real /= four; - if(z.real() < 0) - real = -real; + if((boost::math::signbit)(z.real())) + real = (boost::math::changesign)(real); // // Now handle imaginary part, this is much easier, @@ -234,10 +237,13 @@ std::complex atanh(const std::complex& z) imag = std::atan2(two*y, 1 - x*x); } imag /= two; - if(z.imag() < 0) - imag = -imag; + if((boost::math::signbit)(z.imag())) + imag = (boost::math::changesign)(imag); } return std::complex(real, imag); +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif } } } // namespaces diff --git a/include/boost/math/complex/details.hpp b/include/boost/math/complex/details.hpp index cf9907f1e..46c61f141 100644 --- a/include/boost/math/complex/details.hpp +++ b/include/boost/math/complex/details.hpp @@ -16,6 +16,10 @@ #include #include // isnan where available #include +#include +#include +#include +#include #ifdef BOOST_NO_STDC_NAMESPACE namespace std{ using ::sqrt; } @@ -23,22 +27,10 @@ namespace std{ using ::sqrt; } namespace boost{ namespace math{ namespace detail{ -template -inline bool test_is_nan(T t) -{ - // Comparisons with Nan's always fail: - return std::numeric_limits::has_infinity && (!(t <= std::numeric_limits::infinity()) || !(t >= -std::numeric_limits::infinity())); -} -#ifdef isnan -template<> inline bool test_is_nan(float t) { return isnan(t); } -template<> inline bool test_is_nan(double t) { return isnan(t); } -template<> inline bool test_is_nan(long double t) { return isnan(t); } -#endif - template inline T mult_minus_one(const T& t) { - return test_is_nan(t) ? t : -t; + return (boost::math::isnan)(t) ? t : (boost::math::changesign)(t); } template diff --git a/test/complex_test.cpp b/test/complex_test.cpp index e6ff09629..7a2f84873 100644 --- a/test/complex_test.cpp +++ b/test/complex_test.cpp @@ -77,6 +77,15 @@ bool check_complex(const std::complex& a, const std::complex& b, int max_e } } + if((boost::math::isnan)(a.real())) + { + BOOST_ERROR("Found non-finite value for real part: " << a); + } + if((boost::math::isnan)(a.imag())) + { + BOOST_ERROR("Found non-finite value for inaginary part: " << a); + } + T rel = boost::math::fabs((b-a)/b) / eps; if( rel > max_error) { @@ -276,7 +285,7 @@ void check_spots(const T&) // but an attempt to access it will terminate the program!!!! if(std::numeric_limits::has_quiet_NaN) nan = std::numeric_limits::quiet_NaN(); - if(boost::math::detail::test_is_nan(nan)) + if((boost::math::isnan)(nan)) test_nan = true; #endif #if defined(__DECCXX) && !defined(_IEEE_FP) @@ -303,11 +312,11 @@ void check_spots(const T&) { result = boost::math::acos(ct(zero,nan)); BOOST_CHECK_CLOSE(result.real(), half_pi, eps*200); - BOOST_CHECK(boost::math::detail::test_is_nan(result.imag())); + BOOST_CHECK((boost::math::isnan)(result.imag())); result = boost::math::acos(ct(mzero,nan)); BOOST_CHECK_CLOSE(result.real(), half_pi, eps*200); - BOOST_CHECK(boost::math::detail::test_is_nan(result.imag())); + BOOST_CHECK((boost::math::isnan)(result.imag())); } if(test_infinity) { @@ -323,8 +332,8 @@ void check_spots(const T&) if(test_nan) { result = boost::math::acos(ct(one, nan)); - BOOST_CHECK(boost::math::detail::test_is_nan(result.real())); - BOOST_CHECK(boost::math::detail::test_is_nan(result.imag())); + BOOST_CHECK((boost::math::isnan)(result.real())); + BOOST_CHECK((boost::math::isnan)(result.imag())); } if(test_infinity) { @@ -363,41 +372,70 @@ void check_spots(const T&) if(test_nan) { result = boost::math::acos(ct(infinity, nan)); - BOOST_CHECK(boost::math::detail::test_is_nan(result.real())); + BOOST_CHECK((boost::math::isnan)(result.real())); BOOST_CHECK(std::fabs(result.imag()) == infinity); result = boost::math::acos(ct(-infinity, nan)); - BOOST_CHECK(boost::math::detail::test_is_nan(result.real())); + BOOST_CHECK((boost::math::isnan)(result.real())); BOOST_CHECK(std::fabs(result.imag()) == infinity); result = boost::math::acos(ct(nan, zero)); - BOOST_CHECK(boost::math::detail::test_is_nan(result.real())); - BOOST_CHECK(boost::math::detail::test_is_nan(result.imag())); + BOOST_CHECK((boost::math::isnan)(result.real())); + BOOST_CHECK((boost::math::isnan)(result.imag())); result = boost::math::acos(ct(nan, -zero)); - BOOST_CHECK(boost::math::detail::test_is_nan(result.real())); - BOOST_CHECK(boost::math::detail::test_is_nan(result.imag())); + BOOST_CHECK((boost::math::isnan)(result.real())); + BOOST_CHECK((boost::math::isnan)(result.imag())); result = boost::math::acos(ct(nan, one)); - BOOST_CHECK(boost::math::detail::test_is_nan(result.real())); - BOOST_CHECK(boost::math::detail::test_is_nan(result.imag())); + BOOST_CHECK((boost::math::isnan)(result.real())); + BOOST_CHECK((boost::math::isnan)(result.imag())); result = boost::math::acos(ct(nan, -one)); - BOOST_CHECK(boost::math::detail::test_is_nan(result.real())); - BOOST_CHECK(boost::math::detail::test_is_nan(result.imag())); + BOOST_CHECK((boost::math::isnan)(result.real())); + BOOST_CHECK((boost::math::isnan)(result.imag())); result = boost::math::acos(ct(nan, nan)); - BOOST_CHECK(boost::math::detail::test_is_nan(result.real())); - BOOST_CHECK(boost::math::detail::test_is_nan(result.imag())); + BOOST_CHECK((boost::math::isnan)(result.real())); + BOOST_CHECK((boost::math::isnan)(result.imag())); result = boost::math::acos(ct(nan, infinity)); - BOOST_CHECK(boost::math::detail::test_is_nan(result.real())); + BOOST_CHECK((boost::math::isnan)(result.real())); BOOST_CHECK(result.imag() == -infinity); result = boost::math::acos(ct(nan, -infinity)); - BOOST_CHECK(boost::math::detail::test_is_nan(result.real())); + BOOST_CHECK((boost::math::isnan)(result.real())); BOOST_CHECK(result.imag() == infinity); } + if(boost::math::signbit(mzero)) + { + result = boost::math::acos(ct(-1.25f, zero)); + BOOST_CHECK(result.real() > 0); + BOOST_CHECK(result.imag() < 0); + result = boost::math::asin(ct(-1.75f, mzero)); + BOOST_CHECK(result.real() < 0); + BOOST_CHECK(result.imag() < 0); + result = boost::math::atan(ct(mzero, -1.75f)); + BOOST_CHECK(result.real() < 0); + BOOST_CHECK(result.imag() < 0); + + result = boost::math::acos(ct(zero, zero)); + BOOST_CHECK(result.real() > 0); + BOOST_CHECK(result.imag() == 0); + BOOST_CHECK((boost::math::signbit)(result.imag())); + result = boost::math::acos(ct(zero, mzero)); + BOOST_CHECK(result.real() > 0); + BOOST_CHECK(result.imag() == 0); + BOOST_CHECK(0 == (boost::math::signbit)(result.imag())); + result = boost::math::acos(ct(mzero, zero)); + BOOST_CHECK(result.real() > 0); + BOOST_CHECK(result.imag() == 0); + BOOST_CHECK((boost::math::signbit)(result.imag())); + result = boost::math::acos(ct(mzero, mzero)); + BOOST_CHECK(result.real() > 0); + BOOST_CHECK(result.imag() == 0); + BOOST_CHECK(0 == (boost::math::signbit)(result.imag())); + } // // C99 spot tests for acosh: @@ -408,7 +446,7 @@ void check_spots(const T&) result = boost::math::acosh(ct(zero, mzero)); BOOST_CHECK(result.real() == 0); - BOOST_CHECK_CLOSE(result.imag(), half_pi, eps*200); + BOOST_CHECK_CLOSE(result.imag(), -half_pi, eps*200); result = boost::math::acosh(ct(mzero, zero)); BOOST_CHECK(result.real() == 0); @@ -416,7 +454,7 @@ void check_spots(const T&) result = boost::math::acosh(ct(mzero, mzero)); BOOST_CHECK(result.real() == 0); - BOOST_CHECK_CLOSE(result.imag(), half_pi, eps*200); + BOOST_CHECK_CLOSE(result.imag(), -half_pi, eps*200); if(test_infinity) { @@ -432,8 +470,8 @@ void check_spots(const T&) if(test_nan) { result = boost::math::acosh(ct(one, nan)); - BOOST_CHECK(boost::math::detail::test_is_nan(result.real())); - BOOST_CHECK(boost::math::detail::test_is_nan(result.imag())); + BOOST_CHECK((boost::math::isnan)(result.real())); + BOOST_CHECK((boost::math::isnan)(result.imag())); } if(test_infinity) { @@ -474,31 +512,37 @@ void check_spots(const T&) { result = boost::math::acosh(ct(infinity, nan)); BOOST_CHECK(result.real() == infinity); - BOOST_CHECK(boost::math::detail::test_is_nan(result.imag())); + BOOST_CHECK((boost::math::isnan)(result.imag())); result = boost::math::acosh(ct(-infinity, nan)); BOOST_CHECK(result.real() == infinity); - BOOST_CHECK(boost::math::detail::test_is_nan(result.imag())); + BOOST_CHECK((boost::math::isnan)(result.imag())); result = boost::math::acosh(ct(nan, one)); - BOOST_CHECK(boost::math::detail::test_is_nan(result.real())); - BOOST_CHECK(boost::math::detail::test_is_nan(result.imag())); + BOOST_CHECK((boost::math::isnan)(result.real())); + BOOST_CHECK((boost::math::isnan)(result.imag())); result = boost::math::acosh(ct(nan, infinity)); BOOST_CHECK(result.real() == infinity); - BOOST_CHECK(boost::math::detail::test_is_nan(result.imag())); + BOOST_CHECK((boost::math::isnan)(result.imag())); result = boost::math::acosh(ct(nan, -one)); - BOOST_CHECK(boost::math::detail::test_is_nan(result.real())); - BOOST_CHECK(boost::math::detail::test_is_nan(result.imag())); + BOOST_CHECK((boost::math::isnan)(result.real())); + BOOST_CHECK((boost::math::isnan)(result.imag())); result = boost::math::acosh(ct(nan, -infinity)); BOOST_CHECK(result.real() == infinity); - BOOST_CHECK(boost::math::detail::test_is_nan(result.imag())); + BOOST_CHECK((boost::math::isnan)(result.imag())); result = boost::math::acosh(ct(nan, nan)); - BOOST_CHECK(boost::math::detail::test_is_nan(result.real())); - BOOST_CHECK(boost::math::detail::test_is_nan(result.imag())); + BOOST_CHECK((boost::math::isnan)(result.real())); + BOOST_CHECK((boost::math::isnan)(result.imag())); + } + if(boost::math::signbit(mzero)) + { + result = boost::math::acosh(ct(-2.5f, zero)); + BOOST_CHECK(result.real() > 0); + BOOST_CHECK(result.imag() > 0); } // // C99 spot checks for asinh: @@ -541,16 +585,16 @@ void check_spots(const T&) if(test_nan) { result = boost::math::asinh(ct(one, nan)); - BOOST_CHECK(boost::math::detail::test_is_nan(result.real())); - BOOST_CHECK(boost::math::detail::test_is_nan(result.imag())); + BOOST_CHECK((boost::math::isnan)(result.real())); + BOOST_CHECK((boost::math::isnan)(result.imag())); result = boost::math::asinh(ct(-one, nan)); - BOOST_CHECK(boost::math::detail::test_is_nan(result.real())); - BOOST_CHECK(boost::math::detail::test_is_nan(result.imag())); + BOOST_CHECK((boost::math::isnan)(result.real())); + BOOST_CHECK((boost::math::isnan)(result.imag())); result = boost::math::asinh(ct(zero, nan)); - BOOST_CHECK(boost::math::detail::test_is_nan(result.real())); - BOOST_CHECK(boost::math::detail::test_is_nan(result.imag())); + BOOST_CHECK((boost::math::isnan)(result.real())); + BOOST_CHECK((boost::math::isnan)(result.imag())); } if(test_infinity) @@ -592,39 +636,45 @@ void check_spots(const T&) { result = boost::math::asinh(ct(infinity, nan)); BOOST_CHECK(result.real() == infinity); - BOOST_CHECK(boost::math::detail::test_is_nan(result.imag())); + BOOST_CHECK((boost::math::isnan)(result.imag())); result = boost::math::asinh(ct(-infinity, nan)); BOOST_CHECK(result.real() == -infinity); - BOOST_CHECK(boost::math::detail::test_is_nan(result.imag())); + BOOST_CHECK((boost::math::isnan)(result.imag())); result = boost::math::asinh(ct(nan, zero)); - BOOST_CHECK(boost::math::detail::test_is_nan(result.real())); + BOOST_CHECK((boost::math::isnan)(result.real())); BOOST_CHECK(result.imag() == 0); result = boost::math::asinh(ct(nan, mzero)); - BOOST_CHECK(boost::math::detail::test_is_nan(result.real())); + BOOST_CHECK((boost::math::isnan)(result.real())); BOOST_CHECK(result.imag() == 0); result = boost::math::asinh(ct(nan, one)); - BOOST_CHECK(boost::math::detail::test_is_nan(result.real())); - BOOST_CHECK(boost::math::detail::test_is_nan(result.imag())); + BOOST_CHECK((boost::math::isnan)(result.real())); + BOOST_CHECK((boost::math::isnan)(result.imag())); result = boost::math::asinh(ct(nan, -one)); - BOOST_CHECK(boost::math::detail::test_is_nan(result.real())); - BOOST_CHECK(boost::math::detail::test_is_nan(result.imag())); + BOOST_CHECK((boost::math::isnan)(result.real())); + BOOST_CHECK((boost::math::isnan)(result.imag())); result = boost::math::asinh(ct(nan, nan)); - BOOST_CHECK(boost::math::detail::test_is_nan(result.real())); - BOOST_CHECK(boost::math::detail::test_is_nan(result.imag())); + BOOST_CHECK((boost::math::isnan)(result.real())); + BOOST_CHECK((boost::math::isnan)(result.imag())); result = boost::math::asinh(ct(nan, infinity)); BOOST_CHECK(std::fabs(result.real()) == infinity); - BOOST_CHECK(boost::math::detail::test_is_nan(result.imag())); + BOOST_CHECK((boost::math::isnan)(result.imag())); result = boost::math::asinh(ct(nan, -infinity)); BOOST_CHECK(std::fabs(result.real()) == infinity); - BOOST_CHECK(boost::math::detail::test_is_nan(result.imag())); + BOOST_CHECK((boost::math::isnan)(result.imag())); + } + if(boost::math::signbit(mzero)) + { + result = boost::math::asinh(ct(zero, 1.5f)); + BOOST_CHECK(result.real() > 0); + BOOST_CHECK(result.imag() > 0); } // @@ -650,11 +700,11 @@ void check_spots(const T&) { result = boost::math::atanh(ct(zero, nan)); BOOST_CHECK(result.real() == zero); - BOOST_CHECK(boost::math::detail::test_is_nan(result.imag())); + BOOST_CHECK((boost::math::isnan)(result.imag())); result = boost::math::atanh(ct(-zero, nan)); BOOST_CHECK(result.real() == zero); - BOOST_CHECK(boost::math::detail::test_is_nan(result.imag())); + BOOST_CHECK((boost::math::isnan)(result.imag())); } if(test_infinity) @@ -694,12 +744,12 @@ void check_spots(const T&) if(test_nan) { result = boost::math::atanh(ct(pi, nan)); - BOOST_CHECK(boost::math::detail::test_is_nan(result.real())); - BOOST_CHECK(boost::math::detail::test_is_nan(result.imag())); + BOOST_CHECK((boost::math::isnan)(result.real())); + BOOST_CHECK((boost::math::isnan)(result.imag())); result = boost::math::atanh(ct(-pi, nan)); - BOOST_CHECK(boost::math::detail::test_is_nan(result.real())); - BOOST_CHECK(boost::math::detail::test_is_nan(result.imag())); + BOOST_CHECK((boost::math::isnan)(result.real())); + BOOST_CHECK((boost::math::isnan)(result.imag())); } if(test_infinity) @@ -741,19 +791,19 @@ void check_spots(const T&) { result = boost::math::atanh(ct(infinity, nan)); BOOST_CHECK(result.real() == 0); - BOOST_CHECK(boost::math::detail::test_is_nan(result.imag())); + BOOST_CHECK((boost::math::isnan)(result.imag())); result = boost::math::atanh(ct(-infinity, nan)); BOOST_CHECK(result.real() == 0); - BOOST_CHECK(boost::math::detail::test_is_nan(result.imag())); + BOOST_CHECK((boost::math::isnan)(result.imag())); result = boost::math::atanh(ct(nan, pi)); - BOOST_CHECK(boost::math::detail::test_is_nan(result.real())); - BOOST_CHECK(boost::math::detail::test_is_nan(result.imag())); + BOOST_CHECK((boost::math::isnan)(result.real())); + BOOST_CHECK((boost::math::isnan)(result.imag())); result = boost::math::atanh(ct(nan, -pi)); - BOOST_CHECK(boost::math::detail::test_is_nan(result.real())); - BOOST_CHECK(boost::math::detail::test_is_nan(result.imag())); + BOOST_CHECK((boost::math::isnan)(result.real())); + BOOST_CHECK((boost::math::isnan)(result.imag())); result = boost::math::atanh(ct(nan, infinity)); BOOST_CHECK(result.real() == 0); @@ -764,10 +814,16 @@ void check_spots(const T&) BOOST_CHECK_CLOSE(result.imag(), -half_pi, eps*200); result = boost::math::atanh(ct(nan, nan)); - BOOST_CHECK(boost::math::detail::test_is_nan(result.real())); - BOOST_CHECK(boost::math::detail::test_is_nan(result.imag())); + BOOST_CHECK((boost::math::isnan)(result.real())); + BOOST_CHECK((boost::math::isnan)(result.imag())); } + if(boost::math::signbit(mzero)) + { + result = boost::math::atanh(ct(-2.0f, mzero)); + BOOST_CHECK(result.real() < 0); + BOOST_CHECK(result.imag() < 0); + } } //