Subject: sign(exp(2009)) --> floating point overflow
From: Dieter Kaiser
Date: Sun, 18 Oct 2009 15:55:07 +0200
Am Samstag, den 17.10.2009, 17:12 -0500 schrieb Barton Willis:
> In sign1, I see some code that looks broken. I commented it out and
> then sign(exp(2009)) --> pos. I'm not claiming that a good fix is to
> comment out this code--it's just a place I might start looking. Also,
> the signbfloat scheme is fundamentally broken.
>
> (defun sign1 (x)
> (setq x (specrepcheck x))
> (setq x (infsimp* x))
> (when (and *complexsign* (atom x) (eq x '$infinity))
> ;; In Complex Mode the sign of infinity is complex.
> (when *debug-compar* (format t "~& in sign1 detect $infintiy.~%"))
> (return-from sign1 '$complex))
> (if (member x '($und $ind $infinity) :test #'eq)
> (if limitp '$pnz (merror (intl:gettext "sign: sign of ~:M is
> undefined.") x)))
> (prog (dum exp)
> (setq dum (constp x) exp x)
> (cond ((or (numberp x) (ratnump x)))
> ((eq dum 'bigfloat)
> (if (prog2 (setq dum ($bfloat x)) ($bfloatp dum))
> (setq exp dum)))
> ((eq dum 'float)
> (if (and (setq dum (numer x)) (numberp dum)) (setq exp dum)))
> ((and (member dum '(numer symbol) :test #'eq) ;; <---- looks bogus to
> me (especially the (< (abs dum) 1.0e-6))
> (prog2 (setq dum (numer x))
> (or (null dum)
> (and (numberp dum)
> (prog2 (setq exp dum)
> (< (abs dum) 1.0e-6)))))) ;; <---- surely this is bogus.
> (cond ($signbfloat
> (and (setq dum ($bfloat x)) ($bfloatp dum) (setq exp dum)))
> (t (setq sign '$pnz evens nil odds (ncons x) minus nil)
> (return sign)))))
> (or (and (not (atom x)) (not (mnump x)) (equal x exp)
> (let (s o e m lhs rhs)
> (compsplt x)
> (dcompare lhs rhs)
> (cond ((member sign '($pos $neg $zero) :test #'eq))
> ((eq sign '$pnz) nil)
> (t (setq s sign o odds e evens m minus)
> (sign x)
> (if (not (strongp sign s))
> (if (and (eq sign '$pnz) (eq s '$pn))
> (setq sign s)
> (setq sign s odds o evens e minus m)))
> t))))
> (sign exp))
> (return sign)))
Because of the line
(member dum '(numer symbol) :test #'eq)
all expressions with a constant like %e, %pi, ... are converted to a
float. Therefore, we have the bug for sign(%pi^2009) too.
This code is needed to get answers for expressions which involve the
numerical constants.
Interestingly, it is working in Maxima 19.2 (GCL on Windows). But if I
trace the routines sign1, constp, numer, $float I get a Lisp Error too.
Perhaps we have to look at the routine $float and the return value for
the case we have an overflow.
Dieter Kaiser