Raymond Toy pushed to branch master at cmucl / cmucl

Commits:

2 changed files:

Changes:

  • src/code/irrat.lisp
    --- a/src/code/irrat.lisp
    +++ b/src/code/irrat.lisp
    @@ -252,6 +252,13 @@
         (return-from intexp base))
       (when (eql base -1)
         (return-from intexp (if (oddp power) -1 1)))
    +
    +  ;; Handle 0 raised to a power.  Return 0 if the power is
    +  ;; non-negative or signal a divide-by-zero if the power is negative.
    +  (when (zerop base)
    +    (if (minusp power)
    +	(error 'division-by-zero)
    +	(return-from intexp base)))
       
       (when (> (abs power) *intexp-maximum-exponent*)
         ;; Allow user the option to continue with calculation, possibly
    

  • tests/irrat.lisp
    --- a/tests/irrat.lisp
    +++ b/tests/irrat.lisp
    @@ -152,3 +152,23 @@
     	for logx = (kernel::dd-%log2 x)
     	for log1/x = (kernel::dd-%log2 (/ x))
     	do (assert-true (<= (abs (+ logx log1/x)) (* 1 double-float-epsilon)))))
    +
    +(define-test expt-integer
    +  (let ((power (1+ kernel::*intexp-maximum-exponent*)))
    +    ;; Make sure we error out in the usual case with the power too
    +    ;; large.
    +    (assert-error 'kernel::intexp-limit-error
    +		  (expt 2 power))
    +    (assert-error 'kernel::intexp-limit-error
    +		  (expt 2 (- power)))
    +    ;; But raising 0 or 1 to a power shouldn't signal anything, except
    +    ;; the obvious division-by-zero.
    +    (assert-eql 1 (expt 1 power))
    +    (cond ((evenp power)
    +	   (assert-eql 1 (expt -1 power))
    +	   (assert-eql -1 (expt -1 (1+ power))))
    +	  (t
    +	   (assert-eql -1 (expt -1 power))
    +	   (assert-eql 1 (expt -1 (1+ power)))))
    +    (assert-eql 0 (expt 0 power))
    +    (assert-error 'division-by-zero (expt 0 (- power)))))