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). -- Matt Camm Maguire <c...@maguirefamily.org> 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 <c...@maguirefamily.org> writes: > >> Greetings! >> >> Matt Kaufmann <kaufm...@cs.utexas.edu> 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 c...@maguirefamily.org > ========================================================================== > "The earth is but one country, and mankind its citizens." -- Baha'u'llah