Hi Camm, Since this thread has discussed floating-point exceptions, I'll weigh in only by requesting that such behavior will continue to be configurable. Specifically, in ACL2 built using GCL 2.6.12 (Version_2_6_13pre131), where compilation uses safety 0, then evaluation of the following form at start-up gives the behavior I want -- in particular, an error when there is floating-point overflow or division by zero.
(fpe:break-on-floating-point-exceptions :floating-point-overflow t :floating-point-invalid-operation t) For example, when I evaluate the definitions (defun f () (let ((y (* most-positive-double-float most-positive-double-float))) (= (- y y) 0.0d0))) and (defun g () (= (/ 0.0d0 0.0d0) 0.0d0)) and then compile f and g, then the evaluations of (f) and (g) both cause errors, which is what I want. (If f and g are compiled in gcl with safety 0 but are called without first calling fpe:break-on-floating-point-exceptions, then there is no error.) By the way, you asked, regarding other Lisps: > Can one access/manipulate nan at the lisp prompt level? See attached, which I think answers your question positively for LispWorks, Allegro CL, and CCL, but perhaps negatively for SBCL and CMUCL. Thanks, Matt Camm Maguire <c...@maguirefamily.org> writes: > Greetings! > > Richard Fateman <fate...@gmail.com> writes: > >> I think that using exactly the same argument conventions and names as the >> library would be best. >> so you overwrite one (or more) of the inputs, for the same reasons as mpfr >> does it, >> to save memory allocation when possible. >> >> Possible glitch: it assumes you will only pass arguments that are in >> memory, not on a stack. >> Thus for actual use you may need to have a functional style program >> interface that puts the >> arguments in memory. I think that mpfr number structures have a size >> [maximum length] and >> an actual size in use. So numbers and comparisons of them etc. must be >> done by mpfr. > > Yes this is the rub, and I believe the basic issues are the same with > floats as integers. GCL stores immediate fixnums in one format, other > fixnums in another, and bignums in a format directly accessible to gmp. > We could expose both the raw gmp interface and the 'functional' > interface which would load the first two into the third, but whether > done under the hood or by the user directly, there is nothing to > overwrite if fixnums are supplied as output arguments. At the C level > we have 5 bignum 'registers' which we do not expose to lisp, as if they > contain fixnums the logic pertaining to the same will fail. I suppose > an expert user could make use of the registers and be careful not to > refer to them until the gmp calculation is done. > > Take care, > >> RJF >> >> On Wed, Feb 28, 2024 at 12:55 PM Camm Maguire <c...@maguirefamily.org> wrote: >> >> Greetings! >> >> Richard Fateman <fate...@gmail.com> writes: >> >> > Several of us here have worked on arbitrary-precision floats in Lisp >> > (generally used for longer than double, though I suppose shorter could >> > also be specified...), and I think the real win would be to make use >> > of the mpfr library (written in C with various assembly-language hacks >> > for different CPUs). >> >> mpfr would be a straightforward extension to GCL, as we already use the >> gmp integer library, integrate it with our gbc/memory management, and >> export the functions at the lisp user level: >> >> >(gmp:mpz_mul most-positive-fixnum most-positive-fixnum) >> >> 85070591730234615847396907784232501249 >> >> The only sensible way to interface to a library like this is to keep all >> the function names and calling syntax the same. GMP is written with >> 'side-effects', i.e. destructive modification of the supplied arguments >> one or more of which are considered outputs. This is so the savvy user >> can avoid unnecessary allocations, which are effectively all that matter >> for performance. Lisp is so functionally oriented, however, that it >> seemed better to me to take only input variables as arguments. The >> natural alternative to the call above would take three arguments, >> overwrite the first, and return no values. Your thoughts? >> >> Take care, >> -- >> Camm Maguire c...@maguirefamily.org >> ========================================================================== >> "The earth is but one country, and mankind its citizens." -- Baha'u'llah >> > > -- > Camm Maguire c...@maguirefamily.org > ========================================================================== > "The earth is but one country, and mankind its citizens." -- Baha'u'llah
...... LispWorks ...... CL-USER 2 > (let ((x (* most-positive-double-float most-positive-double-float))) (- x x)) 1D+-0 #| 1D+-0 is double-float not-a-number |# CL-USER 3 > 1D+-0 1D+-0 #| 1D+-0 is double-float not-a-number |# CL-USER 4 > ...... Allegro CL ...... CL-USER(1): (let ((x (* most-positive-double-float most-positive-double-float))) (- x x)) #.*NAN-DOUBLE* CL-USER(2): *NAN-DOUBLE* #.*NAN-DOUBLE* CL-USER(3): ...... CCL ...... ? (set-fpu-mode :overflow nil :division-by-zero nil :invalid nil) 8064 ? (let ((x (* most-positive-double-float most-positive-double-float))) (- x x)) 1D+-0 #| not-a-number |# ? 1D+-0 1D+-0 #| not-a-number |# ? ...... SBCL ...... * (sb-int:set-floating-point-modes :traps nil) * (let ((x (* most-positive-double-float most-positive-double-float))) (- x x)) #<DOUBLE-FLOAT quiet NaN> * ...... CMUCL ...... * (set-floating-point-modes :traps nil) * (let ((x (* most-positive-double-float most-positive-double-float))) (- x x)) #<DOUBLE-FLOAT Quiet NaN> *