diff --git a/include/boost/math/cstdfloat/cstdfloat_complex_std.hpp b/include/boost/math/cstdfloat/cstdfloat_complex_std.hpp index 495ad88b6..72df8b395 100644 --- a/include/boost/math/cstdfloat/cstdfloat_complex_std.hpp +++ b/include/boost/math/cstdfloat/cstdfloat_complex_std.hpp @@ -509,7 +509,37 @@ inline complex pow(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& x, const complex& a) { - return std::exp(a * std::log(x)); + complex result; + + if(x > BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0)) + { + result = std::exp(a * std::log(x)); + } + else if(x < BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0)) + { + using std::atan2; + using std::log; + + const complex + cpx_lg_x + ( + log(-x), + atan2(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0), BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(-1)) + ); + + result = std::exp(a * cpx_lg_x); + } + else + { + result = + complex + ( + -std::numeric_limits::infinity(), + BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0) + ); + } + + return result; } inline complex sinh(const complex& x) diff --git a/test/float128/test_std_lib.cpp b/test/float128/test_std_lib.cpp index f488c20e7..84333fc98 100644 --- a/test/float128/test_std_lib.cpp +++ b/test/float128/test_std_lib.cpp @@ -219,10 +219,15 @@ BOOST_AUTO_TEST_CASE( test_main ) BOOST_CHECK_CLOSE_FRACTION(imag(pow(cm, 45)), BOOST_FLOATMAX_C(-3.03446103291767290317331113291188915967941284179687500000000e28), tol); BOOST_CHECK_CLOSE_FRACTION(real(pow(cm, BOOST_FLOATMAX_C(-6.25))), BOOST_FLOATMAX_C(0.0001033088262386741675929555572265687059620746178809486273109638), tol); BOOST_CHECK_CLOSE_FRACTION(imag(pow(cm, BOOST_FLOATMAX_C(-6.25))), BOOST_FLOATMAX_C(0.000036807924520680371147635577932953977554657684086220380643819), 10*tol); + + // N[(25/10)^((25/10)+((35/10) I)), 64] BOOST_CHECK_CLOSE_FRACTION(real(pow(BOOST_FLOATMAX_C(2.5), cm)), BOOST_FLOATMAX_C(-9.860975431021437225534259171616709024536334105813829385335979923), tol); BOOST_CHECK_CLOSE_FRACTION(imag(pow(BOOST_FLOATMAX_C(2.5), cm)), BOOST_FLOATMAX_C(-0.646075497748970766828440914855071509282691334478027454136282670), 10*tol); - BOOST_CHECK_CLOSE_FRACTION(real(pow(BOOST_FLOATMAX_C(-2.5), cm)), BOOST_FLOATMAX_C(0.00001083842139839216288187166202164756258624282654265584086879886), tol); - BOOST_CHECK_CLOSE_FRACTION(imag(pow(BOOST_FLOATMAX_C(-2.5), cm)), BOOST_FLOATMAX_C(-0.00016542556944657384392896635407718049618447196348313181759043262), 10*tol); + + // N[(-25/10)^((25/10)+((35/10) I)), 64] + BOOST_CHECK_CLOSE_FRACTION(real(pow(BOOST_FLOATMAX_C(-2.5), cm)), BOOST_FLOATMAX_C(0.0000108384213983921628818716620216475625862428265426558408687988615), tol); + BOOST_CHECK_CLOSE_FRACTION(imag(pow(BOOST_FLOATMAX_C(-2.5), cm)), BOOST_FLOATMAX_C(-0.0001654255694465738439289663540771804961844719634831318175904326223), 10*tol); + BOOST_CHECK_CLOSE_FRACTION(real(pow(BOOST_FLOATMAX_C(23.125), cm)), BOOST_FLOATMAX_C(-6.10574617260000071495777483951769228578270070743952693687), 500*tol); BOOST_CHECK_CLOSE_FRACTION(imag(pow(BOOST_FLOATMAX_C(23.125), cm)), BOOST_FLOATMAX_C(-2571.59829653692515304089117319850284971907684832627401081405), tol);