egallesio / STklos

STklos Scheme
http://stklos.net
GNU General Public License v2.0
69 stars 17 forks source link

Make `expt` work with complex exponents, and adjust to one R7RS requirement #531

Closed jpellegrini closed 1 year ago

jpellegrini commented 1 year ago

The following condition in the primitive definition for expt:

  if (negativep(y))
    return div2(MAKE_INT(1),
                my_expt(x, sub2(MAKE_INT(0), y)));

was preventing it from working with complex exponents, because negativep will trigger an error for complexes. Adding !COMPLEXP(y) fixes it.

However, there is another issue that we also fix with this PR: R7RS says that

"The value of $0^z$ is $1$ if (zero? z), $0$ if (real-part z) is positive, and an error otherwise. Similarly for $0.0^z$, with inexact results."

But the current code would not do the "zero when (real-part z) is positive", so we also fix this in my_expt.

Then, we add some tests. And adjust one test from SRFI 70:

(test "expr.4" 1    (expt (sqrt 3) 0))

This won't work with R7RS, because (sqrt 3) is inexact, and then expt is required to return an inexact number. So we do this instead:

(test "expr.4" 1.0    (expt (sqrt 3) 0)) ; because sqrt(3) is inexact
(test "expr.5" 1      (expt (sqrt 4) 0)) ; because sqrt(4) is exact

(And actually, as far as I can see, SRFI 70 doesn't really require that the result from (expt (sqrt 3) 0) be exact).

jpellegrini commented 1 year ago

Then, we add some tests. And adjust one test from SRFI 70:

Actually... I'm not sure. I wrote that (and proposed the change in the test) because R7RS says that "inexactness is a contagious property of a number" -- but that doesn't sound necessary for $x^0$, when $x\neq 0$...

And there doesn't seem to be a consensus -- look:

(expt 1.5 0)
  => 1   (Biwa)
  => 1   (Chez)
  => 1   (Gambit)
  => 1   (Guile)
  => 1   (Racket)
  => 1   (Ypsilon)
  => 1.0 (Bigloo)
  => 1.0 (Chibi)
  => 1.0 (Chicken)
  => 1.0 (Gauche)
  => 1.0 (Kawa)
  => 1.0 (MIT)
  => 1.0 (Sagittarius)
  => 1.0 (SCM)

@egallesio what do you prefer?

egallesio commented 1 year ago

@egallesio what do you prefer?

1 is probably better, since the value is exactly known.

jpellegrini commented 1 year ago

Ok @egallesio - changed that!

egallesio commented 1 year ago

Great fix. Thanks. It is merged now.