From f56c72c53dd8d9384475d28e0c1e29448c5db43d Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Fri, 23 Dec 2011 02:43:32 +0000 Subject: [PATCH] core: fix the sign of a negative real number raised to an even power, and add the corresponding unit test. --- src/real.cpp | 6 ++++++ test/unit/real.cpp | 11 +++++++++++ 2 files changed, 17 insertions(+) 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 */