Today, I had a problem with a subtle effect.
We know that Maxima preserves the type in numerical addition:
(%i1) 0.0 + 1/10;
(%o1) 0.1
(%i2) 1/10 + 0.0;
(%o2) 0.1
But when I use the macro add in Lisp code I get the following. The type
is not preserved, if the floating point number is the first argument:
(%i3) ?add(0.0,1/10);
(%o3) 1/10
(%i4) ?add(1/10,0.0);
(%o4) 0.1
I call this a bug and it is a very subtle one.
This is the responsible code in opers.lisp:
(defmfun add2 (x y)
(cond ((numberp x)
(cond ((numberp y) (+ x y))
((zerop x) y)
(t (simplifya `((mplus) ,x ,y) t))))
((eql y 0) x)
(t (simplifya `((mplus) ,x ,y) t))))
A possible correction is to specialize the first test for a zero
argument:
(defmfun add2 (x y)
(cond ((numberp x)
(cond ((numberp y) (+ x y))
((eql x 0) y)
(t (simplifya `((mplus) ,x ,y) t))))
((eql y 0) x)
(t (simplifya `((mplus) ,x ,y) t))))
Or we can use the test function =0:
(defmfun add2 (x y)
(cond ((numberp x)
(cond ((numberp y) (+ x y))
((=0 x) y)
(t (simplifya `((mplus) ,x ,y) t))))
((=0 y) x)
(t (simplifya `((mplus) ,x ,y) t))))
A more drastic solution would be not to bypass the simplifier at all:
(defmfun add2 (x y)
(simplifya `((mplus) ,x ,y) t)))
We do not have the problem with other routines of the file opers.lisp.
All other routines have code which bypasses the simplifier too, but
these routines do a test with =0 or =1.
Dieter Kaiser