From c23939a1c2b7bfe1b3cf20abb6a7b431699281a1 Mon Sep 17 00:00:00 2001 From: Ramakrishnan Muthukrishnan Date: Sun, 31 Oct 2010 23:22:52 +0530 Subject: [PATCH] Fix for bug #31464. expt needs to treat negative bases specially. Also adding test-suite cases for expt. * libguile/numbers.c: if base is negative, find the absolute value of the base, find log and then later reapply the negative sign. The bug was caused by the fact that log of a negative number is undefined. * test-suite/tests/numbers.test: Two new test cases for expt. For cases where the base is negative and the power to be raised is not an integer, the result should be a complex number. --- libguile/numbers.c | 11 +++++++++++ test-suite/tests/numbers.test | 7 ++++++- 2 files changed, 17 insertions(+), 1 deletions(-) diff --git a/libguile/numbers.c b/libguile/numbers.c index fbc6cc8..07ae95d 100644 --- a/libguile/numbers.c +++ b/libguile/numbers.c @@ -5451,6 +5451,17 @@ SCM_DEFINE (scm_expt, "expt", 2, 0, 0, { return scm_from_double (pow (scm_to_double (x), scm_to_double (y))); } + else if (scm_is_real (x) && + scm_is_real (y) && + (scm_to_double (x) < 0) && + !SCM_FRACTIONP (y)) + { + SCM x_abs; + + x_abs = scm_abs (x); + return scm_product(scm_from_double (-1.0), + scm_exp (scm_product (scm_log (x_abs), y))); + } else return scm_exp (scm_product (scm_log (x), y)); } diff --git a/test-suite/tests/numbers.test b/test-suite/tests/numbers.test index 3c3e14f..3d53bbe 100644 --- a/test-suite/tests/numbers.test +++ b/test-suite/tests/numbers.test @@ -2892,7 +2892,12 @@ (pass-if "(= 1 (expt 0 0))" (= 1 (expt 0 0))) (pass-if "(= 1 (expt 0 0.0))" (= 1 (expt 0 0.0))) (pass-if "(= 1 (expt 0.0 0))" (= 1 (expt 0.0 0))) - (pass-if "(= 1 (expt 0.0 0.0))" (= 1 (expt 0.0 0.0)))) + (pass-if "(= 1 (expt 0.0 0.0))" (= 1 (expt 0.0 0.0))) + ;; tests for non zero values of base and exponent. + (pass-if "(eqv-loosely? -2742638075.5 (expt -2742638075.5 1)" + (eqv-loosely? -2742638075.5 (expt -2742638075.5 1))) + (pass-if "(eqv-loosely? 1.0000000000000002+1.7320508075688772i (expt -8 1/3)" + (eqv-loosely? 1.0000000000000002+1.7320508075688772i (expt -8 1/3)))) ;;; ;;; asinh -- 1.7.2.3