1 /* some tests for non-numeric floats
2 * these are only meaningful for Lisps which support such values
3 * GCL, ECL, SBCL, maybe others;
5 * SBCL: allows both inf/-inf and NaN; enable via:
6 * :lisp (sb-vm::set-floating-point-modes :traps nil)
8 * GCL: allows both inf/-inf and NaN;
9 * requires *PRINT-NAN* = T but that's already enabled by Maxima
11 * ECL: allows only inf/-inf, not NaN
12 * (although maybe in a future version)
13 * no special action needed to enable, as far as I know
19 (is_sbcl : is (ssearch ("SBCL", build_info()@lisp_name) # false),
20 is_gcl : is (ssearch ("GCL", build_info()@lisp_name) # false),
21 is_ecl : is (ssearch ("ECL", build_info()@lisp_name) # false),
22 is (is_sbcl or is_gcl or is_ecl));
25 (x:1e300, i:x*x, if not is_ecl then n:i-i, minusi:-i, 0);
28 /* Maxima "=" calls ALIKE1 which compares atoms with EQUAL.
29 * As long as that's the case, we expect is(n=n) => true.
31 [is(x=x), is(i=i), if is_ecl then [] else is(n=n), is(minusi=minusi)];
32 [true, true, true, true];
34 /* Lisp "=" yields false for NaN. */
35 [?\=(x, x), ?\=(i, i), if is_ecl then [] else ?\=(n, n), ?\=(minusi, minusi)];
36 [true, true, false, true];
38 /* bfloat and rat should trigger an error on non-numeric floats */
43 if is_ecl then false else errcatch(bfloat(n));
46 errcatch(bfloat(minusi));
49 /* GCL: rat(nonnumeric) => hangs; SF bug report # !! */
51 if not is_gcl then errcatch(rat(i));
54 if is_ecl then false else if not is_gcl then errcatch(rat(n));
57 if not is_gcl then errcatch(rat(minusi));
60 /* Fortran output should produce INF/-INF or NAN */
62 map (fortran, ' ['x = x, 'i = i, 'n = n, 'minusi = minusi]);
63 [done, done, done, done];
65 /* At present, Maxima will output implementation-dependent
66 * representations of non-numeric floats.
70 ''(if is_sbcl then "x = 1.0e+300"
71 elseif is_gcl then "x = 1.0E+300"
72 elseif is_ecl then "x = 1.0e+300");
75 ''(if is_sbcl then "i = #.SB-EXT:DOUBLE-FLOAT-POSITIVE-INFINITY"
76 elseif is_gcl then "i = #<inf>"
77 elseif is_ecl then "i = #.ext::double-float-positive-infinity");
80 ''(if is_sbcl then "n = #<DOUBLE-FLOAT quiet NaN>"
81 elseif is_gcl then "n = #<nan>");
83 string('minusi = minusi);
84 ''(if is_sbcl then "minusi = #.SB-EXT:DOUBLE-FLOAT-NEGATIVE-INFINITY"
85 elseif is_gcl then "minusi = #<-inf>"
86 elseif is_ecl then "minusi = #.ext::double-float-negative-infinity");
88 /* SF bug report #2680: "1000!^0.01 gives i.nfE+6166368" */
89 errcatch (string (1000!^0.01));
90 ''(if is_sbcl then ["#.SB-EXT:DOUBLE-FLOAT-POSITIVE-INFINITY"]
91 elseif is_gcl then ["#<inf>"]
92 elseif is_ecl then ["#.ext::double-float-positive-infinity"]);
94 /* SF bug report #2749: "Float evaluation of sinh causes Lisp error instead of overflowing to bigfloat" */
96 errcatch(string(sinh(1e3)));
97 ''(if is_sbcl then ["#.SB-EXT:DOUBLE-FLOAT-POSITIVE-INFINITY"]
98 elseif is_gcl then ["#<inf>"]
99 elseif is_ecl then ["#.ext::double-float-positive-infinity"]);
101 errcatch(string(cosh(1e3)));
102 ''(if is_sbcl then ["#.SB-EXT:DOUBLE-FLOAT-POSITIVE-INFINITY"]
103 elseif is_gcl then ["#<inf>"]
104 elseif is_ecl then ["#.ext::double-float-positive-infinity"]);
106 /* SF bug report #3081: abs(...) -> "bfloat: attempted conversion of floating-point infinity." */
108 [abs(%e^(10000/3)+1), abs(%e^10000+1), abs(%e^(10000/3))];
109 [abs(%e^(10000/3)+1), abs(%e^10000+1), abs(%e^(10000/3))];
111 errcatch(string(ev(exp(10000/3),numer)));
112 ''(if is_sbcl then ["#.SB-EXT:DOUBLE-FLOAT-POSITIVE-INFINITY"]
113 elseif is_gcl then ["#<inf>"]
114 elseif is_ecl then ["#.ext::double-float-positive-infinity"]);
116 errcatch(string(ev(exp(10000/3),numer,%enumer)));
117 ''(if is_sbcl then ["#.SB-EXT:DOUBLE-FLOAT-POSITIVE-INFINITY"]
118 elseif is_gcl then ["#<inf>"]
119 elseif is_ecl then ["#.ext::double-float-positive-infinity"]);
121 float_infinity_p (i);
124 float_infinity_p (minusi);
142 map (float_infinity_p, [n, 0, 1.0, %pi, 'foo('blurf)]);
143 [false, false, false, false, false];
145 map (float_nan_p, [i, minusi, 0, 1.0, %pi, 'foo('blurf)]);
146 [false, false, false, false, false, false];