Re: +-Inf and NaN
Raymond Toy <[email protected]> Fri, 21 Feb 2025 10:37:53 -0800
| Newsgroups | gmane.lisp.gcl.devel,gmane.comp.mathematics.maxima.general |
|---|---|
| Message-ID | <[email protected]> |
On 2/21/25 9:59 AM, Matt Kaufmann wrote: > Hi Camm, > > Thanks for your persistence in getting GCL 2.7 ready! > > One thing I noticed about floating-point computations in GCL -- both > 2.6.15pre and 2.7.0, both CLtL1 and ANSI -- is that rationalize > appears to be the same as rational, at least on input (float 1/3 > 0.0d0). > >> (rationalize (float 1/3 0.0d0)) > 6004799503160661/18014398509481984 > > I don't think that's an error, but it's maybe not what one would > expect of rationalize, as (rationalize (float 1/3 0.0d0)) evaluates to > 1/3 in all the other Lisps I checked (CCL, SBCL, LispWorks, CMUCL, and > ALlegro CL). That does seem kind of unfortunate. If |rationalize| is really missing, gcl could borrow the very nice implementation from clisp. > -- Matt > Camm Maguire<[email protected]> writes: > >> Greetings! I just thought I'd post on the resolution of this old >> thread. >> >> In summary, GCL 2.7.0 chose option 1) as previously described, namely >> NaNs are floats and do not trigger errors unless trapping is explicitly >> set. For posterity, option 2) was unworkable as if NaNs were not floats >> and not numbers, one could not get them to traverse the typecases >> correctly when one wished to disable the error. >> >> (/= x x) and the like will be optimized away if and only if the compiler >> can determine the value is not a NaN, see below. This is identical >> behavior for gcc. >> >> I had to rework the type system a bit to accommodate unordered floats. In >> sum, (or (long-float 0) (long-float * 0)) is a subtype of, but not equal >> to, long-float. As NaNs were not envisioned in the spec (apparently), >> I've taken the liberty of defining (long-float si::unordered) to refer >> to the and of the latter and the not of the former. The interested soul >> can experiment with NaNs in types passed to 'si::resolve-type to their >> heart's content to see how this works out. >> >> This was the last obstacle for GCL 2.7.0 release. AFAICS GCL master >> supports current master of ACL2, maxima, axiom, fricas, and hol88 and is >> ready for release. If anyone has any extremely minor suggestions in the >> next week or so please send them my way. No unicode changes made it >> into this release. >> >> If anyone has access to gcc-15, it would be helpful if they could >> confirm that GCL master builds with -std=gnu17 passed to CFLAGS. I do >> not yet have access to this compiler for testing, but it is coming and it would be >> great if GCL worked out of the box. >> >> Separately there are some improvements to the maxima build procedure >> available via the new function si::do-recomp to avoid recompiling the >> whole tree twice. I will try to commit a patch soon. >> >> Take care, >> >> ============================================================================= >> (disassemble '(lambda (x y) (declare ((float 0 ) x y)) (/= x x))) >> >> ;; Compiling /tmp/gazonk_890403_0.lsp. >> ;; When compiling (DEFUN CMP-ANON) >> INTERNAL-SIMPLE-STYLE-WARNING: The variable Y is not used. >> ;; End of Pass 1. >> ;; End of Pass 2. >> OPTIMIZE levels: Safety=0 (No runtime error checking), Space=0, Speed=3 >> ;; Finished compiling /tmp/gazonk_890403_0.o. >> >> #include "gazonk_890403_0.h" >> void init_code(){do_init((void *)VV);} >> /* local entry for function COMPILER::CMP-ANON */ >> >> static object LI1__CMP_ANON___gazonk_890403_0(object V3,object V4) >> { VMB1 VMS1 VMV1 >> {object V5 = Cnil; >> VMR1(V5);} >> } >> (1 (MAPC 'EVAL *COMPILER-COMPILE-DATA*)) >> static object LI1__CMP_ANON___gazonk_890403_0(object V3,object V4) >> ; >> #define VMB1 >> #define VMS1 >> #define VMV1 >> #define VMRV1(a_,b_) return((object )a_); >> #define VMR1(a_) VMRV1(a_,0); >> #define VM1 0 >> static void * VVi[1]={ >> #define Cdata VV[0] >> (void *)(LI1__CMP_ANON___gazonk_890403_0) >> }; >> #define VV (VVi) >> NIL >> >> COMPILER>(disassemble '(lambda (x y) (declare ((float ) x y)) (/= x x))) >> >> ;; Compiling /tmp/gazonk_890403_0.lsp. >> ;; When compiling (DEFUN CMP-ANON) >> INTERNAL-SIMPLE-STYLE-WARNING: The variable Y is not used. >> ;; End of Pass 1. >> ;; End of Pass 2. >> OPTIMIZE levels: Safety=0 (No runtime error checking), Space=0, Speed=3 >> ;; Finished compiling /tmp/gazonk_890403_0.o. >> >> #include "gazonk_890403_0.h" >> void init_code(){do_init((void *)VV);} >> /* local entry for function COMPILER::CMP-ANON */ >> >> static object LI1__CMP_ANON___gazonk_890403_0(object V3,object V4) >> { VMB1 VMS1 VMV1 >> {object V5 = (immnum_ne((V3),(V3))?Ct:Cnil); >> VMR1(V5);} >> } >> (1 (MAPC 'EVAL *COMPILER-COMPILE-DATA*)) >> static object LI1__CMP_ANON___gazonk_890403_0(object V3,object V4) >> ; >> #define VMB1 >> #define VMS1 >> #define VMV1 >> #define VMRV1(a_,b_) return((object )a_); >> #define VMR1(a_) VMRV1(a_,0); >> #define VM1 0 >> static void * VVi[1]={ >> #define Cdata VV[0] >> (void *)(LI1__CMP_ANON___gazonk_890403_0) >> }; >> #define VV (VVi) >> NIL >> >> COMPILER>(disassemble '(lambda (x y) (declare ((short-float ) x y)) (/= x x))) >> >> ;; Compiling /tmp/gazonk_890403_0.lsp. >> ;; When compiling (DEFUN CMP-ANON) >> INTERNAL-SIMPLE-STYLE-WARNING: The variable Y is not used. >> ;; End of Pass 1. >> ;; End of Pass 2. >> OPTIMIZE levels: Safety=0 (No runtime error checking), Space=0, Speed=3 >> ;; Finished compiling /tmp/gazonk_890403_0.o. >> >> #include "gazonk_890403_0.h" >> void init_code(){do_init((void *)VV);} >> /* local entry for function COMPILER::CMP-ANON */ >> >> static object LI1__CMP_ANON___gazonk_890403_0(object V3,object V4) >> { VMB1 VMS1 VMV1 >> {object V5 = ((sf(V3))!=(sf(V3))?Ct:Cnil); >> VMR1(V5);} >> } >> (1 (MAPC 'EVAL *COMPILER-COMPILE-DATA*)) >> static object LI1__CMP_ANON___gazonk_890403_0(object V3,object V4) >> ; >> #define VMB1 >> #define VMS1 >> #define VMV1 >> #define VMRV1(a_,b_) return((object )a_); >> #define VMR1(a_) VMRV1(a_,0); >> #define VM1 0 >> static void * VVi[1]={ >> #define Cdata VV[0] >> (void *)(LI1__CMP_ANON___gazonk_890403_0) >> }; >> #define VV (VVi) >> NIL >> >> COMPILER>============================================================================= >> >> >> Camm Maguire<[email protected]> writes: >> >>> Greetings! >>> >>> Matt Kaufmann<[email protected]> writes: >>> >>>> Hi Camm, >>>> >>>> Excellent. ACL2 will evaluate the following at start-up. >>>> >>>> (fpe:break-on-floating-point-exceptions >>>> :floating-point-overflow t >>>> :division-by-zero t ; not sure this is actually needed >>>> :floating-point-invalid-operation t) >>>> >>> Sounds good, but you might want to consider adding the other two with a >>> setting of nil so your behavior is immune to GCL changes in its default >>> configuration. I don't plan on enabling traps by default at the moment >>> as it appears controversial, but that could change. >>> >>> >>>> That said, consider the following from the Common Lisp Hyperspec, >>>> Section 12.1.4.4 (Rule of Float Precision Contagion). >>>> >>>> The result of a numerical function is a float of the largest format >>>> among all the floating-point arguments to the function. >>>> >>>> This seems to argue for proposal 1), since when a NaN results from the >>>> application of a numerical function to double-float arguments, that >>>> NaN would apparently need to be of type double-float. >>> Yeah, I think 1) is the way to go for now, but the reading of this >>> section depends to my mind on whether NaN is a valid return, in which >>> case it is a number/float/long-float, or an error indicator, which can >>> be trapped or not. Conceptually you might as well replace the NaN with >>> a common-lisp condition akin to >>> >>> >>>> (arithmetic-error-operands (make-condition 'floating-point-invalid-operation :operands (list compiler::nan 1.0))) >>> (#<nan> 1.0) >>> >>> and return this when not trapping, but defining some additional cell >>> containing the NaN result for use in subsequent processing. The chief >>> argument against this appears to be performance. >>> >>> Take care, >> -- >> Camm Maguire [email protected] >> ========================================================================== >> "The earth is but one country, and mankind its citizens." -- Baha'u'llah ​