From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Mark H Weaver Newsgroups: gmane.lisp.guile.devel Subject: Re: fix for expt bug Date: Wed, 03 Nov 2010 12:22:04 -0400 Message-ID: <87wrouwf6b.fsf@yeeloong.netris.org> References: <8762whnc4d.fsf@yeeloong.netris.org> <87r5f4l3yt.fsf@yeeloong.netris.org> <87aalrxim7.fsf@yeeloong.netris.org> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: dough.gmane.org 1288801361 8012 80.91.229.12 (3 Nov 2010 16:22:41 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Wed, 3 Nov 2010 16:22:41 +0000 (UTC) Cc: guile-devel To: Ramakrishnan Muthukrishnan Original-X-From: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Wed Nov 03 17:22:35 2010 Return-path: Envelope-to: guile-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1PDg6d-00033y-A4 for guile-devel@m.gmane.org; Wed, 03 Nov 2010 17:22:35 +0100 Original-Received: from localhost ([127.0.0.1]:35235 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PDg6c-0006ZV-9Q for guile-devel@m.gmane.org; Wed, 03 Nov 2010 12:22:34 -0400 Original-Received: from [140.186.70.92] (port=36804 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PDg6W-0006Y5-QQ for guile-devel@gnu.org; Wed, 03 Nov 2010 12:22:29 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PDg6V-0000Tx-MS for guile-devel@gnu.org; Wed, 03 Nov 2010 12:22:28 -0400 Original-Received: from world.peace.net ([216.204.32.208]:43358) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PDg6V-0000TP-F0 for guile-devel@gnu.org; Wed, 03 Nov 2010 12:22:27 -0400 Original-Received: from ip68-9-118-38.ri.ri.cox.net ([68.9.118.38] helo=freedomincluded) by world.peace.net with esmtpa (Exim 4.69) (envelope-from ) id 1PDg6P-0002nX-VT; Wed, 03 Nov 2010 12:22:22 -0400 Original-Received: from mhw by freedomincluded with local (Exim 4.69) (envelope-from ) id 1PDg6I-00062f-Ci; Wed, 03 Nov 2010 12:22:14 -0400 In-Reply-To: (Ramakrishnan Muthukrishnan's message of "Wed, 3 Nov 2010 15:11:46 +0530") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-BeenThere: guile-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Developers list for Guile, the GNU extensibility library" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Errors-To: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.lisp.guile.devel:11109 Archived-At: Ramakrishnan and others, I just realized that there is a better way to fix these bugs. We don't need a new top-level case in expt after all. Instead, we generalize the scm_integer_expt case to support inexact integer exponents. Within that case, if the exponent is an inexact integer, then we make it exact and make the base inexact, and then call scm_integer_expt. I think this strategy is better for these reasons: * Fewer top-level cases to check, thus making expt faster. * More precise answers in the case of inexact integer exponents. * More cases handled without spurious imaginary parts turning up, for example (expt +234234234.5i 4.0) * Simpler code Something like the code below. (WARNING: UNTESTED!) What do you all think? Can you see any problems with this strategy? Best, Mark index fbc6cc8..f38772e 100644 --- a/libguile/numbers.c +++ b/libguile/numbers.c @@ -5445,8 +5445,14 @@ SCM_DEFINE (scm_expt, "expt", 2, 0, 0, "Return @var{x} raised to the power of @var{y}.") #define FUNC_NAME s_scm_expt { - if (scm_is_true (scm_exact_p (x)) && scm_is_integer (y)) - return scm_integer_expt (x, y); + if (scm_is_integer (y)) + { + if (scm_is_true (scm_exact_p (y))) + return scm_integer_expt (x, y); + else + return scm_integer_expt (scm_exact_to_inexact(x), + scm_inexact_to_exact(y)); + } else if (scm_is_real (x) && scm_is_real (y) && scm_to_double (x) >= 0.0) { return scm_from_double (pow (scm_to_double (x), scm_to_double (y)));