diff --git a/src/real.cpp b/src/real.cpp index f62b5ec9..c0a01da7 100644 --- a/src/real.cpp +++ b/src/real.cpp @@ -692,8 +692,14 @@ real pow(real const &x, real const &y) return exp(y * log(x)); else /* x < 0 */ { + /* Odd integer exponent */ + if (y == (round(y >> 1) << 1)) + return exp(y * log(-x)); + + /* Even integer exponent */ if (y == round(y)) return -exp(y * log(-x)); + /* FIXME: negative nth root */ return real::R_0; } diff --git a/test/unit/real.cpp b/test/unit/real.cpp index 70612ef9..b64c3e3b 100644 --- a/test/unit/real.cpp +++ b/test/unit/real.cpp @@ -326,6 +326,17 @@ LOLUNIT_FIXTURE(RealTest) LOLUNIT_ASSERT_EQUAL(b2, a2); } } + + LOLUNIT_TEST(Pow) + { + double a1 = pow(-real::R_2, real::R_2); + double b1 = 4.0; + LOLUNIT_ASSERT_DOUBLES_EQUAL(a1, b1, 1.0e-13); + + double a2 = pow(-real::R_2, real::R_3); + double b2 = -8.0; + LOLUNIT_ASSERT_DOUBLES_EQUAL(a2, b2, 1.0e-13); + } }; } /* namespace lol */