From: Andy Brezing
Subject: EXPT
Date: 
Message-ID: <3475967A.41C6@gia.rwth-aachen.de>
Hi!

A short question about the EXPT function in CL:
Can anybody explain the following behaviour to me ?

> (EXPT -2.0 2)
4.0

> (EXPT -2.0 2.0)
#C(4.0 6.993822E-7)

> (EXPT 2.0 2.0)
4.0

Why returns EXPT a complex number if there's a negative base and a
floating power ?

Cheers

Andy

******** Geodaetisches Institut, RWTH Aachen, Templergraben 55, D-52056
Aachen
  ****** TEL: +49 (0)241 80-5283 FAX: +49 (0)241 8888-142
    **** E-MAIL: ·······@gia.rwth-aachen.de

From: Federico Hernandez-Pueschel
Subject: Re: EXPT
Date: 
Message-ID: <3478a5c2.22387720@news.tu-darmstadt.de>
Hi,

On Fri, 21 Nov 1997 15:11:06 +0100, Andy Brezing
<·······@gia.rwth-aachen.de> wrote:
>Why returns EXPT a complex number if there's a negative base and a
>floating power ?

I want to quote the Common Lisp Hyper Spec (available through
www.harlequin.com):
-----------------------[CL Hyper Spec]---------------------------------
...
expt base-number power-number => result
...
expt returns base-number raised to the power power-number. If the
base-number is a rational and power-number is an integer, the calculation
is exact and the result will be of type rational; otherwise a
floating-point approximation might result. For expt of a complex rational
to an integer power, the calculation must be exact and the result is of
type (or rational (complex rational)). 

The result of expt can be a complex, even when neither argument is a
complex, if base-number is negative and power-number is not an integer. The
result is always the principal complex value.
....
-----------------------[CL Hyper Spec]---------------------------------

You will find the same explanation in CLTL2 on pages 300/301.

Greetings

Federico
From: [Invalid-From-Line]
Subject: Re: EXPT
Date: 
Message-ID: <vytpvnuynct.fsf@soggy-fibers.i-have-a-misconfigured-system-so-shoot-me>
········@hrzpub.tu-darmstadt.de (Federico Hernandez-Pueschel) writes:
> On Fri, 21 Nov 1997 15:11:06 +0100, Andy Brezing
> <·······@gia.rwth-aachen.de> wrote:
> >Why returns EXPT a complex number if there's a negative base and a
> >floating power ?
> -----------------------[CL Hyper Spec]---------------------------------
...
> The result of expt can be a complex, even when neither argument is a
> complex, if base-number is negative and power-number is not an integer. The
> result is always the principal complex value.
> ....
> -----------------------[CL Hyper Spec]---------------------------------
> 

As a description of the implementation, this quote is not terribly
satisfying, mathematically.  It is important to note that a
floating-point power-number is an approximation.  In this case, 2.0
represents all reals between approximately 1.99999997 and 2.00000003.
It should be clear that -2.0 to the power of most of those reals will
be complex.

> (EXPT -2.0 2.0)
#C(4.0 6.993822E-7)

Whether #C(4.0 6.993822E-7) is the "best" representative from the
region described by the given expression I'll leave to those who can
do complex mappings better than I.

		- Patrick
From: Kent M Pitman
Subject: Re: EXPT
Date: 
Message-ID: <sfwiutlrckj.fsf@world.std.com>
Andy Brezing <·······@gia.rwth-aachen.de> writes:

> Hi!
> 
> A short question about the EXPT function in CL:
> Can anybody explain the following behaviour to me ?
> 
> (EXPT -2.0 2  ) => 4.0
> (EXPT -2.0 2.0) => #C(4.0 6.993822E-7)
> (EXPT  2.0 2.0) => 4.0
> 
> Why returns EXPT a complex number if there's a negative base and a
> floating power ?

It's important to separate two questions here:

(a) What are floats mathematically?   I may not be the best person
    to answer since math was never my strongest suit, but my best
    understanding is that they are most appropriately viewed as
    rational numbers sparsely and irregularly spaced in a plane
    such that they serve as proxies for all nearby numbers, whether
    rational or irrational.  When dealing in complex floats, the
    notion of "nearby" becomes even more (if you'll pardon the pun)
    complex.  One hopes that the very nearest float to the 
    mathematically correct one will be found, but one also hopes
    that this decision will be made with no additional computation
    in the blink of an eye.  (Seems to me that given the irregular
    placement of represented numbers in the total space of numbers,
    it's virtually magic that this can ever be done correctly, much
    less in a constant, extremely small amount of time.)  But
    sometimes one presumably misses and sometimes errors accumulate
    so presumably even the optimal mathematical result is tough to
    discern without knowing the whole space of subsequent operations
    you plan to do so that errors could be designed to cancel each
    other rather than magnify each other.  Of course, I guess the
    problem is that being "just a little bit complex" has implications
    that may be non-trivial.  In cases where you have reason to believe
    a result would be better off not "going complex" I suppose you
    could anticipate that little bit of imaginary and lop it off;
    maybe you have enough additional information about your domain to
    know this is safe where you seem to be expecting the Lisp system
    to do it but it can't because it doesn't have that extra bit of
    domain knowledge... (Then again, maybe you're just confused and
    Lisp is reminding you it's not as clear as you're thinking. :-)

(b) What is the difference between a language and an implementation?
    Even if you know the answer you want, a given processor might
    or might not have an operation that gives it.  The spec often
    leaves a considerable latitude to the implementation in order
    to allow the implementation to use its native arithmetic and
    system libraries instead of forcing time-consuming simulation,
    possibly requiring expensive hand-coding.  One should NEVER
    try a function a few times, observe experimentally the result,
    and then conclude something like (as above) "returns a complex
    if there's a negative base and a floating power".  As painful as
    it seems, you should say "appears to return a complex in some
    particular release of some particular implementation on some
    particular hardware under some particular operating system
    if there's a negative base and a floating power".  That is, the
    function EXPT is a linguistic entity defined externally of the
    language.  It does precisely what the definition says because
    it is a constraint, not an implementation, and because an
    implementor is free to move among techniques that do not violate
    the constraints.  Also, there may be things you're not seeing,
    so unless you are sure you've exhaustively tried all possible
    inputs under all possible circumstances, it's unwise to 
    generalize without at least noting that you've done so.  And,
    finally, if Lisp calls out to the operating system and hardware,
    the answer may be in those elements, and not Lisp at all.
    As a designer of Lisp (the language) myself, I routinely get 
    questions which sound like "language questions" but really 
    turn out to be "implementation questions".  That is, why did 
    the implementor choose to inhabit this part of the space and
    not that.  My answer is always, "Because he was permitted to
    inhabit any part of the space he wanted to."  I can't tell if
    you're saying the space is too large (that would be a language
    issue) or the choice is just puzzling (no one's bug, but an
    implementor's job to answer) or the choice is a bad position in
    the space (maybe a language issue, but often more easily 
    controlled by bug reports to the vendor than bug reports to
    the language--often the language prefers to leave "efficiency"
    choices to the free market to sort out) or...

Well, I hope those two perspectives help you somewhat in sorting
this out.