improve expt on exact non-integer second argument

Correct the case that converting the second argument to an inexact
numbe produces an integer by losing precision.

original commit: 467db7fa1f1d068e9bad250b93044d157cd3806d
This commit is contained in:
Matthew Flatt 2019-06-28 14:33:18 -06:00
parent 35a0dfcafe
commit d31368fc09
2 changed files with 14 additions and 1 deletions

View File

@ -2477,6 +2477,10 @@
(cfl~= (expt 7.7-11.11i -2.0) (* (/ 1.0 7.7-11.11i) (/ 1.0 7.7-11.11i)))
(~= (expt 11 1/2) (sqrt 11))
(fl~= (expt 1.5e-20 0.5) (sqrt 1.5e-20))
(cfl~= -0.0+0.0i (expt -0.1 1000000000000001/3)) ; inexact approx of second arg is non-integer
(eqv? +inf.0+inf.0i (expt -0.1 -1000000000000001/3)) ; inexact approx of second arg is non-integer
(cfl~= -0.0+0.0i (expt -0.1 100000000000000000001/3)) ; inexact approx of second arg is integer
(eqv? -inf.0-inf.0i (expt -0.1 -100000000000000000001/3)) ; inexact approx of second arg is integer
; test cp0 handling of expt
(begin
(define $probably-should-not-use

View File

@ -1519,7 +1519,16 @@
0
($impoops 'expt "undefined for values ~s and ~s" x y))]
[(eq? x 1) 1]
[(floatable? y) (expt x (inexact y))]
[(and (floatable? y)
(let ([y (inexact y)])
;; Don't use this case if `(inexact y)` loses
;; precision and becomes an an integer, in which
;; case the result would be real (but should be
;; non-real complex)
(and (not (and (flonum? y)
($flinteger? y)))
y)))
=> (lambda (y) (expt x y))]
[else (exp (* y (log x)))])]
[else (nonnumber-error 'expt y)])))