|
From: Raymond T. <toy...@gm...> - 2025-12-05 14:47:06
|
On 12/5/25 4:55 AM, Barton Willis wrote: > Another thing: Although |bfhalf| automatically updates when |fpprec > |changes, some special variables defined in |globals.lisp| do not. > Examples: > > (%i1) :lisp(print bigfloat%pi) > > ((BIGFLOAT SIMP 56) 56593902016227522 2) > ((BIGFLOAT SIMP 56) 56593902016227522 2) > > (%i1) fpprec : 57$ > > (%i2) :lisp(print bigfloat%pi) > > ((BIGFLOAT SIMP 56) 56593902016227522 2) > ((BIGFLOAT SIMP 56) 56593902016227522 2) Yeah, this is confusing. I'm not sure what should happen here. But AFAICT, |bigfloat%pi| is only used in gamma.lisp, and it recomputes a value via |($bfloat '$%pi)|. Fortunately, that will use a memoized value if available. Updating these constants when changing fpprec is potentially very expensive since computing pi, e, gamma, and log2 can be rather expensive, even if they are memoized. On the other hand, the uses of pi, e, and gamma are always recomputed as needed so these special variables can probably be removed (for the best!). And |bigfloat_log2| doesn't seem to be used anywhere. I'll file a bug on this. > ------------------------------------------------------------------------ > *From:* Raymond Toy <toy...@gm...> > *Sent:* Thursday, December 4, 2025 5:44 PM > *To:* Barton Willis <wi...@un...>; > max...@li... > <max...@li...> > *Subject:* Re: [Maxima-discuss] sometimes 1//2 =/= 1/2 > > > Caution: Non-NU Email > > > On 12/4/25 8:51 AM, Barton Willis wrote: > >> I have tested changing (let ((1//2 ... to (let ((bfhalf .... It >> fixes the trouble and eliminates the need for the macro half that is >> used in absarg. I hope to commit this fix along with a few others >> in a few weeks. > > Hmm. float.lisp defines |bfhalf| spec var. And it's value is updated > whenever fpprec1 is called. Maybe you don't need that at all. > > And we should probably rename |bfhalf| to |*bfhalf*| along with the > other spec vars updated in fpprec1. And rename |1//2| to |*1/2*|. Or > make |1//2| a |defconstant|. But sbcl is really picky about what can > be a |defconstant|. > >> >> >> ------------------------------------------------------------------------ >> *From:* Raymond Toy <toy...@gm...> >> <mailto:toy...@gm...> >> *Sent:* Thursday, December 4, 2025 10:28 AM >> *To:* max...@li... >> <mailto:max...@li...> >> <max...@li...> >> <mailto:max...@li...> >> *Subject:* Re: [Maxima-discuss] sometimes 1//2 =/= 1/2 >> >> >> Caution: Non-NU Email >> >> >> On 12/4/25 5:43 AM, Barton Willis via Maxima-discuss wrote: >> >>> OK, maybe I found the culprit: >>> >>> (defun bfloat-erf (z) >>> ;; Warning! This has round-off problems when abs(z) is very small. >>> (let ((1//2 ($bfloat '((rat simp) 1 2)))) >>> ;; The argument is real, the result is real too >>> ($realpart >>> (mul >>> (simplify (list '(%signum) z)) >>> (sub 1 >>> (mul >>> (div 1 (power ($bfloat '$%pi) 1//2)) >>> (bfloat-gamma-incomplete 1//2 ($bfloat (power z 2))))))))) >>> >>> >>> >>> And similarly for |complex-bfloat-erf| . Changing 1//2 to bfhalf in >>> this code didn't result in any testsuite failures, but I have a few >>> pending changes to the function |absarg.| >> Nice bit of detective work! Yeah, renaming 1//2 to something else >> should take care of the problem. >>> >>> |Also, loading gamma.lisp gives the warning: (SBCL)| >>> >>> in: DEFUN GAMMA-INCOMPLETE >>> ; (COND ((COMPLEXP MAXIMA::X) #C(0.0d0 0.0d0)) ((REALP >>> MAXIMA::X) 0.0d0)) >> >> I think there are lots of these. >> >> The issue here is that the compiler doesn't know what X is, so the >> |cond| cases of |complexp| and |realp| covers the case of numbers, >> but there are lots of other types which aren't covered. >> >> This can be fixed in two ways. Add |(declare (number x))|. Add a |T| >> clause to |cond|. This should probably signal an error. >> >> Or maybe even replace the |cond| with |etypecase|? >> >> ​ > ​ ​ |