1 /* Primitive operations on floating point for GNU Emacs Lisp interpreter.
2 Copyright (C) 1988, 1993 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
21 /* ANSI C requires only these float functions:
22 acos, asin, atan, atan2, ceil, cos, cosh, exp, fabs, floor, fmod,
23 frexp, ldexp, log, log10, modf, pow, sin, sinh, sqrt, tan, tanh.
25 Define HAVE_INVERSE_HYPERBOLIC if you have acosh, asinh, and atanh.
26 Define HAVE_CBRT if you have cbrt.
27 Define HAVE_RINT if you have rint.
28 If you don't define these, then the appropriate routines will be simulated.
30 Define HAVE_MATHERR if on a system supporting the SysV matherr callback.
31 (This should happen automatically.)
33 Define FLOAT_CHECK_ERRNO if the float library routines set errno.
34 This has no effect if HAVE_MATHERR is defined.
36 Define FLOAT_CATCH_SIGILL if the float library routines signal SIGILL.
37 (What systems actually do this? Please let us know.)
39 Define FLOAT_CHECK_DOMAIN if the float library doesn't handle errors by
40 either setting errno, or signalling SIGFPE/SIGILL. Otherwise, domain and
41 range checking will happen before calling the float routines. This has
42 no effect if HAVE_MATHERR is defined (since matherr will be called when
43 a domain error occurs.)
50 #include "syssignal.h"
52 Lisp_Object Qarith_error
;
54 #ifdef LISP_FLOAT_TYPE
59 /* These declarations are omitted on some systems, like Ultrix. */
60 extern double logb ();
63 #if defined(DOMAIN) && defined(SING) && defined(OVERFLOW)
64 /* If those are defined, then this is probably a `matherr' machine. */
75 # ifdef FLOAT_CHECK_ERRNO
76 # undef FLOAT_CHECK_ERRNO
78 # ifdef FLOAT_CHECK_DOMAIN
79 # undef FLOAT_CHECK_DOMAIN
83 #ifndef NO_FLOAT_CHECK_ERRNO
84 #define FLOAT_CHECK_ERRNO
87 #ifdef FLOAT_CHECK_ERRNO
93 /* Avoid traps on VMS from sinh and cosh.
94 All the other functions set errno instead. */
99 #define cosh(x) ((exp(x)+exp(-x))*0.5)
100 #define sinh(x) ((exp(x)-exp(-x))*0.5)
104 #define rint(x) (floor((x)+0.5))
107 static SIGTYPE
float_error ();
109 /* Nonzero while executing in floating point.
110 This tells float_error what to do. */
114 /* If an argument is out of range for a mathematical function,
115 here is the actual argument value to use in the error message. */
117 static Lisp_Object float_error_arg
, float_error_arg2
;
119 static char *float_error_fn_name
;
121 /* Evaluate the floating point expression D, recording NUM
122 as the original argument for error messages.
123 D is normally an assignment expression.
124 Handle errors which may result in signals or may set errno.
126 Note that float_error may be declared to return void, so you can't
127 just cast the zero after the colon to (SIGTYPE) to make the types
130 #ifdef FLOAT_CHECK_ERRNO
131 #define IN_FLOAT(d, name, num) \
133 float_error_arg = num; \
134 float_error_fn_name = name; \
135 in_float = 1; errno = 0; (d); in_float = 0; \
138 case EDOM: domain_error (float_error_fn_name, float_error_arg); \
139 case ERANGE: range_error (float_error_fn_name, float_error_arg); \
140 default: arith_error (float_error_fn_name, float_error_arg); \
143 #define IN_FLOAT2(d, name, num, num2) \
145 float_error_arg = num; \
146 float_error_arg2 = num2; \
147 float_error_fn_name = name; \
148 in_float = 1; errno = 0; (d); in_float = 0; \
151 case EDOM: domain_error (float_error_fn_name, float_error_arg); \
152 case ERANGE: range_error (float_error_fn_name, float_error_arg); \
153 default: arith_error (float_error_fn_name, float_error_arg); \
157 #define IN_FLOAT(d, name, num) (in_float = 1, (d), in_float = 0)
158 #define IN_FLOAT2(d, name, num, num2) (in_float = 1, (d), in_float = 0)
161 #define arith_error(op,arg) \
162 Fsignal (Qarith_error, Fcons (build_string ((op)), Fcons ((arg), Qnil)))
163 #define range_error(op,arg) \
164 Fsignal (Qrange_error, Fcons (build_string ((op)), Fcons ((arg), Qnil)))
165 #define domain_error(op,arg) \
166 Fsignal (Qdomain_error, Fcons (build_string ((op)), Fcons ((arg), Qnil)))
167 #define domain_error2(op,a1,a2) \
168 Fsignal (Qdomain_error, Fcons (build_string ((op)), Fcons ((a1), Fcons ((a2), Qnil))))
170 /* Extract a Lisp number as a `double', or signal an error. */
176 CHECK_NUMBER_OR_FLOAT (num
, 0);
178 if (XTYPE (num
) == Lisp_Float
)
179 return XFLOAT (num
)->data
;
180 return (double) XINT (num
);
183 /* Trig functions. */
185 DEFUN ("acos", Facos
, Sacos
, 1, 1, 0,
186 "Return the inverse cosine of ARG.")
188 register Lisp_Object arg
;
190 double d
= extract_float (arg
);
191 #ifdef FLOAT_CHECK_DOMAIN
192 if (d
> 1.0 || d
< -1.0)
193 domain_error ("acos", arg
);
195 IN_FLOAT (d
= acos (d
), "acos", arg
);
196 return make_float (d
);
199 DEFUN ("asin", Fasin
, Sasin
, 1, 1, 0,
200 "Return the inverse sine of ARG.")
202 register Lisp_Object arg
;
204 double d
= extract_float (arg
);
205 #ifdef FLOAT_CHECK_DOMAIN
206 if (d
> 1.0 || d
< -1.0)
207 domain_error ("asin", arg
);
209 IN_FLOAT (d
= asin (d
), "asin", arg
);
210 return make_float (d
);
213 DEFUN ("atan", Fatan
, Satan
, 1, 1, 0,
214 "Return the inverse tangent of ARG.")
216 register Lisp_Object arg
;
218 double d
= extract_float (arg
);
219 IN_FLOAT (d
= atan (d
), "atan", arg
);
220 return make_float (d
);
223 DEFUN ("cos", Fcos
, Scos
, 1, 1, 0,
224 "Return the cosine of ARG.")
226 register Lisp_Object arg
;
228 double d
= extract_float (arg
);
229 IN_FLOAT (d
= cos (d
), "cos", arg
);
230 return make_float (d
);
233 DEFUN ("sin", Fsin
, Ssin
, 1, 1, 0,
234 "Return the sine of ARG.")
236 register Lisp_Object arg
;
238 double d
= extract_float (arg
);
239 IN_FLOAT (d
= sin (d
), "sin", arg
);
240 return make_float (d
);
243 DEFUN ("tan", Ftan
, Stan
, 1, 1, 0,
244 "Return the tangent of ARG.")
246 register Lisp_Object arg
;
248 double d
= extract_float (arg
);
250 #ifdef FLOAT_CHECK_DOMAIN
252 domain_error ("tan", arg
);
254 IN_FLOAT (d
= sin (d
) / c
, "tan", arg
);
255 return make_float (d
);
258 #if 0 /* Leave these out unless we find there's a reason for them. */
260 DEFUN ("bessel-j0", Fbessel_j0
, Sbessel_j0
, 1, 1, 0,
261 "Return the bessel function j0 of ARG.")
263 register Lisp_Object arg
;
265 double d
= extract_float (arg
);
266 IN_FLOAT (d
= j0 (d
), "bessel-j0", arg
);
267 return make_float (d
);
270 DEFUN ("bessel-j1", Fbessel_j1
, Sbessel_j1
, 1, 1, 0,
271 "Return the bessel function j1 of ARG.")
273 register Lisp_Object arg
;
275 double d
= extract_float (arg
);
276 IN_FLOAT (d
= j1 (d
), "bessel-j1", arg
);
277 return make_float (d
);
280 DEFUN ("bessel-jn", Fbessel_jn
, Sbessel_jn
, 2, 2, 0,
281 "Return the order N bessel function output jn of ARG.\n\
282 The first arg (the order) is truncated to an integer.")
284 register Lisp_Object arg1
, arg2
;
286 int i1
= extract_float (arg1
);
287 double f2
= extract_float (arg2
);
289 IN_FLOAT (f2
= jn (i1
, f2
), "bessel-jn", arg1
);
290 return make_float (f2
);
293 DEFUN ("bessel-y0", Fbessel_y0
, Sbessel_y0
, 1, 1, 0,
294 "Return the bessel function y0 of ARG.")
296 register Lisp_Object arg
;
298 double d
= extract_float (arg
);
299 IN_FLOAT (d
= y0 (d
), "bessel-y0", arg
);
300 return make_float (d
);
303 DEFUN ("bessel-y1", Fbessel_y1
, Sbessel_y1
, 1, 1, 0,
304 "Return the bessel function y1 of ARG.")
306 register Lisp_Object arg
;
308 double d
= extract_float (arg
);
309 IN_FLOAT (d
= y1 (d
), "bessel-y0", arg
);
310 return make_float (d
);
313 DEFUN ("bessel-yn", Fbessel_yn
, Sbessel_yn
, 2, 2, 0,
314 "Return the order N bessel function output yn of ARG.\n\
315 The first arg (the order) is truncated to an integer.")
317 register Lisp_Object arg1
, arg2
;
319 int i1
= extract_float (arg1
);
320 double f2
= extract_float (arg2
);
322 IN_FLOAT (f2
= yn (i1
, f2
), "bessel-yn", arg1
);
323 return make_float (f2
);
328 #if 0 /* Leave these out unless we see they are worth having. */
330 DEFUN ("erf", Ferf
, Serf
, 1, 1, 0,
331 "Return the mathematical error function of ARG.")
333 register Lisp_Object arg
;
335 double d
= extract_float (arg
);
336 IN_FLOAT (d
= erf (d
), "erf", arg
);
337 return make_float (d
);
340 DEFUN ("erfc", Ferfc
, Serfc
, 1, 1, 0,
341 "Return the complementary error function of ARG.")
343 register Lisp_Object arg
;
345 double d
= extract_float (arg
);
346 IN_FLOAT (d
= erfc (d
), "erfc", arg
);
347 return make_float (d
);
350 DEFUN ("log-gamma", Flog_gamma
, Slog_gamma
, 1, 1, 0,
351 "Return the log gamma of ARG.")
353 register Lisp_Object arg
;
355 double d
= extract_float (arg
);
356 IN_FLOAT (d
= lgamma (d
), "log-gamma", arg
);
357 return make_float (d
);
360 DEFUN ("cube-root", Fcube_root
, Scube_root
, 1, 1, 0,
361 "Return the cube root of ARG.")
363 register Lisp_Object arg
;
365 double d
= extract_float (arg
);
367 IN_FLOAT (d
= cbrt (d
), "cube-root", arg
);
370 IN_FLOAT (d
= pow (d
, 1.0/3.0), "cube-root", arg
);
372 IN_FLOAT (d
= -pow (-d
, 1.0/3.0), "cube-root", arg
);
374 return make_float (d
);
379 DEFUN ("exp", Fexp
, Sexp
, 1, 1, 0,
380 "Return the exponential base e of ARG.")
382 register Lisp_Object arg
;
384 double d
= extract_float (arg
);
385 #ifdef FLOAT_CHECK_DOMAIN
386 if (d
> 709.7827) /* Assume IEEE doubles here */
387 range_error ("exp", arg
);
389 return make_float (0.0);
392 IN_FLOAT (d
= exp (d
), "exp", arg
);
393 return make_float (d
);
396 DEFUN ("expt", Fexpt
, Sexpt
, 2, 2, 0,
397 "Return the exponential X ** Y.")
399 register Lisp_Object arg1
, arg2
;
403 CHECK_NUMBER_OR_FLOAT (arg1
, 0);
404 CHECK_NUMBER_OR_FLOAT (arg2
, 0);
405 if ((XTYPE (arg1
) == Lisp_Int
) && /* common lisp spec */
406 (XTYPE (arg2
) == Lisp_Int
)) /* don't promote, if both are ints */
407 { /* this can be improved by pre-calculating */
408 int acc
, x
, y
; /* some binary powers of x then accumulating */
420 acc
= (y
& 1) ? -1 : 1;
432 y
= (unsigned)y
>> 1;
435 XSET (val
, Lisp_Int
, acc
);
438 f1
= (XTYPE (arg1
) == Lisp_Float
) ? XFLOAT (arg1
)->data
: XINT (arg1
);
439 f2
= (XTYPE (arg2
) == Lisp_Float
) ? XFLOAT (arg2
)->data
: XINT (arg2
);
440 /* Really should check for overflow, too */
441 if (f1
== 0.0 && f2
== 0.0)
443 #ifdef FLOAT_CHECK_DOMAIN
444 else if ((f1
== 0.0 && f2
< 0.0) || (f1
< 0 && f2
!= floor(f2
)))
445 domain_error2 ("expt", arg1
, arg2
);
447 IN_FLOAT (f1
= pow (f1
, f2
), "expt", arg1
);
448 return make_float (f1
);
451 DEFUN ("log", Flog
, Slog
, 1, 2, 0,
452 "Return the natural logarithm of ARG.\n\
453 If second optional argument BASE is given, return log ARG using that base.")
455 register Lisp_Object arg
, base
;
457 double d
= extract_float (arg
);
459 #ifdef FLOAT_CHECK_DOMAIN
461 domain_error2 ("log", arg
, base
);
464 IN_FLOAT (d
= log (d
), "log", arg
);
467 double b
= extract_float (base
);
469 #ifdef FLOAT_CHECK_DOMAIN
470 if (b
<= 0.0 || b
== 1.0)
471 domain_error2 ("log", arg
, base
);
474 IN_FLOAT2 (d
= log10 (d
), "log", arg
, base
);
476 IN_FLOAT2 (d
= log (d
) / log (b
), "log", arg
, base
);
478 return make_float (d
);
481 DEFUN ("log10", Flog10
, Slog10
, 1, 1, 0,
482 "Return the logarithm base 10 of ARG.")
484 register Lisp_Object arg
;
486 double d
= extract_float (arg
);
487 #ifdef FLOAT_CHECK_DOMAIN
489 domain_error ("log10", arg
);
491 IN_FLOAT (d
= log10 (d
), "log10", arg
);
492 return make_float (d
);
495 DEFUN ("sqrt", Fsqrt
, Ssqrt
, 1, 1, 0,
496 "Return the square root of ARG.")
498 register Lisp_Object arg
;
500 double d
= extract_float (arg
);
501 #ifdef FLOAT_CHECK_DOMAIN
503 domain_error ("sqrt", arg
);
505 IN_FLOAT (d
= sqrt (d
), "sqrt", arg
);
506 return make_float (d
);
509 #if 0 /* Not clearly worth adding. */
511 DEFUN ("acosh", Facosh
, Sacosh
, 1, 1, 0,
512 "Return the inverse hyperbolic cosine of ARG.")
514 register Lisp_Object arg
;
516 double d
= extract_float (arg
);
517 #ifdef FLOAT_CHECK_DOMAIN
519 domain_error ("acosh", arg
);
521 #ifdef HAVE_INVERSE_HYPERBOLIC
522 IN_FLOAT (d
= acosh (d
), "acosh", arg
);
524 IN_FLOAT (d
= log (d
+ sqrt (d
*d
- 1.0)), "acosh", arg
);
526 return make_float (d
);
529 DEFUN ("asinh", Fasinh
, Sasinh
, 1, 1, 0,
530 "Return the inverse hyperbolic sine of ARG.")
532 register Lisp_Object arg
;
534 double d
= extract_float (arg
);
535 #ifdef HAVE_INVERSE_HYPERBOLIC
536 IN_FLOAT (d
= asinh (d
), "asinh", arg
);
538 IN_FLOAT (d
= log (d
+ sqrt (d
*d
+ 1.0)), "asinh", arg
);
540 return make_float (d
);
543 DEFUN ("atanh", Fatanh
, Satanh
, 1, 1, 0,
544 "Return the inverse hyperbolic tangent of ARG.")
546 register Lisp_Object arg
;
548 double d
= extract_float (arg
);
549 #ifdef FLOAT_CHECK_DOMAIN
550 if (d
>= 1.0 || d
<= -1.0)
551 domain_error ("atanh", arg
);
553 #ifdef HAVE_INVERSE_HYPERBOLIC
554 IN_FLOAT (d
= atanh (d
), "atanh", arg
);
556 IN_FLOAT (d
= 0.5 * log ((1.0 + d
) / (1.0 - d
)), "atanh", arg
);
558 return make_float (d
);
561 DEFUN ("cosh", Fcosh
, Scosh
, 1, 1, 0,
562 "Return the hyperbolic cosine of ARG.")
564 register Lisp_Object arg
;
566 double d
= extract_float (arg
);
567 #ifdef FLOAT_CHECK_DOMAIN
568 if (d
> 710.0 || d
< -710.0)
569 range_error ("cosh", arg
);
571 IN_FLOAT (d
= cosh (d
), "cosh", arg
);
572 return make_float (d
);
575 DEFUN ("sinh", Fsinh
, Ssinh
, 1, 1, 0,
576 "Return the hyperbolic sine of ARG.")
578 register Lisp_Object arg
;
580 double d
= extract_float (arg
);
581 #ifdef FLOAT_CHECK_DOMAIN
582 if (d
> 710.0 || d
< -710.0)
583 range_error ("sinh", arg
);
585 IN_FLOAT (d
= sinh (d
), "sinh", arg
);
586 return make_float (d
);
589 DEFUN ("tanh", Ftanh
, Stanh
, 1, 1, 0,
590 "Return the hyperbolic tangent of ARG.")
592 register Lisp_Object arg
;
594 double d
= extract_float (arg
);
595 IN_FLOAT (d
= tanh (d
), "tanh", arg
);
596 return make_float (d
);
600 DEFUN ("abs", Fabs
, Sabs
, 1, 1, 0,
601 "Return the absolute value of ARG.")
603 register Lisp_Object arg
;
605 CHECK_NUMBER_OR_FLOAT (arg
, 0);
607 if (XTYPE (arg
) == Lisp_Float
)
608 IN_FLOAT (arg
= make_float (fabs (XFLOAT (arg
)->data
)), "abs", arg
);
609 else if (XINT (arg
) < 0)
610 XSETINT (arg
, - XFASTINT (arg
));
615 DEFUN ("float", Ffloat
, Sfloat
, 1, 1, 0,
616 "Return the floating point number equal to ARG.")
618 register Lisp_Object arg
;
620 CHECK_NUMBER_OR_FLOAT (arg
, 0);
622 if (XTYPE (arg
) == Lisp_Int
)
623 return make_float ((double) XINT (arg
));
624 else /* give 'em the same float back */
628 DEFUN ("logb", Flogb
, Slogb
, 1, 1, 0,
629 "Returns the integer not greater than the base 2 log of the magnitude of ARG.\n\
630 This is the same as the exponent of a float.")
636 double f
= extract_float (arg
);
642 IN_FLOAT (frexp (f
, &exp
), "logb", arg
);
643 XSET (val
, Lisp_Int
, exp
-1);
646 IN_FLOAT (value
= logb (f
), "logb", arg
);
647 XSET (val
, Lisp_Int
, value
);
653 /* the rounding functions */
655 DEFUN ("ceiling", Fceiling
, Sceiling
, 1, 1, 0,
656 "Return the smallest integer no less than ARG. (Round toward +inf.)")
658 register Lisp_Object arg
;
660 CHECK_NUMBER_OR_FLOAT (arg
, 0);
662 if (XTYPE (arg
) == Lisp_Float
)
663 IN_FLOAT (XSET (arg
, Lisp_Int
, ceil (XFLOAT (arg
)->data
)), "ceiling", arg
);
668 DEFUN ("floor", Ffloor
, Sfloor
, 1, 1, 0,
669 "Return the largest integer no greater than ARG. (Round towards -inf.)")
671 register Lisp_Object arg
;
673 CHECK_NUMBER_OR_FLOAT (arg
, 0);
675 if (XTYPE (arg
) == Lisp_Float
)
676 IN_FLOAT (XSET (arg
, Lisp_Int
, floor (XFLOAT (arg
)->data
)), "floor", arg
);
681 DEFUN ("round", Fround
, Sround
, 1, 1, 0,
682 "Return the nearest integer to ARG.")
684 register Lisp_Object arg
;
686 CHECK_NUMBER_OR_FLOAT (arg
, 0);
688 if (XTYPE (arg
) == Lisp_Float
)
689 /* Screw the prevailing rounding mode. */
690 IN_FLOAT (XSET (arg
, Lisp_Int
, rint (XFLOAT (arg
)->data
)), "round", arg
);
695 DEFUN ("truncate", Ftruncate
, Struncate
, 1, 1, 0,
696 "Truncate a floating point number to an int.\n\
697 Rounds the value toward zero.")
699 register Lisp_Object arg
;
701 CHECK_NUMBER_OR_FLOAT (arg
, 0);
703 if (XTYPE (arg
) == Lisp_Float
)
704 XSET (arg
, Lisp_Int
, (int) XFLOAT (arg
)->data
);
710 /* It's not clear these are worth adding. */
712 DEFUN ("fceiling", Ffceiling
, Sfceiling
, 1, 1, 0,
713 "Return the smallest integer no less than ARG, as a float.\n\
714 \(Round toward +inf.\)")
716 register Lisp_Object arg
;
718 double d
= extract_float (arg
);
719 IN_FLOAT (d
= ceil (d
), "fceiling", arg
);
720 return make_float (d
);
723 DEFUN ("ffloor", Fffloor
, Sffloor
, 1, 1, 0,
724 "Return the largest integer no greater than ARG, as a float.\n\
725 \(Round towards -inf.\)")
727 register Lisp_Object arg
;
729 double d
= extract_float (arg
);
730 IN_FLOAT (d
= floor (d
), "ffloor", arg
);
731 return make_float (d
);
734 DEFUN ("fround", Ffround
, Sfround
, 1, 1, 0,
735 "Return the nearest integer to ARG, as a float.")
737 register Lisp_Object arg
;
739 double d
= extract_float (arg
);
740 IN_FLOAT (d
= rint (XFLOAT (arg
)->data
), "fround", arg
);
741 return make_float (d
);
744 DEFUN ("ftruncate", Fftruncate
, Sftruncate
, 1, 1, 0,
745 "Truncate a floating point number to an integral float value.\n\
746 Rounds the value toward zero.")
748 register Lisp_Object arg
;
750 double d
= extract_float (arg
);
752 IN_FLOAT (d
= floor (d
), "ftruncate", arg
);
754 IN_FLOAT (d
= ceil (d
), arg
);
755 return make_float (d
);
759 #ifdef FLOAT_CATCH_SIGILL
765 fatal_error_signal (signo
);
770 #else /* not BSD4_1 */
771 sigsetmask (SIGEMPTYMASK
);
772 #endif /* not BSD4_1 */
774 /* Must reestablish handler each time it is called. */
775 signal (SIGILL
, float_error
);
780 Fsignal (Qarith_error
, Fcons (float_error_arg
, Qnil
));
783 /* Another idea was to replace the library function `infnan'
784 where SIGILL is signaled. */
786 #endif /* FLOAT_CATCH_SIGILL */
795 /* Not called from emacs-lisp float routines; do the default thing. */
797 if (!strcmp (x
->name
, "pow"))
801 = Fcons (build_string (x
->name
),
802 Fcons (make_float (x
->arg1
),
803 ((!strcmp (x
->name
, "log") || !strcmp (x
->name
, "pow"))
804 ? Fcons (make_float (x
->arg2
), Qnil
)
808 case DOMAIN
: Fsignal (Qdomain_error
, args
); break;
809 case SING
: Fsignal (Qsingularity_error
, args
); break;
810 case OVERFLOW
: Fsignal (Qoverflow_error
, args
); break;
811 case UNDERFLOW
: Fsignal (Qunderflow_error
, args
); break;
812 default: Fsignal (Qarith_error
, args
); break;
814 return (1); /* don't set errno or print a message */
816 #endif /* HAVE_MATHERR */
820 #ifdef FLOAT_CATCH_SIGILL
821 signal (SIGILL
, float_error
);
841 defsubr (&Sbessel_y0
);
842 defsubr (&Sbessel_y1
);
843 defsubr (&Sbessel_yn
);
844 defsubr (&Sbessel_j0
);
845 defsubr (&Sbessel_j1
);
846 defsubr (&Sbessel_jn
);
849 defsubr (&Slog_gamma
);
850 defsubr (&Scube_root
);
851 defsubr (&Sfceiling
);
854 defsubr (&Sftruncate
);
868 defsubr (&Struncate
);
871 #else /* not LISP_FLOAT_TYPE */
879 #endif /* not LISP_FLOAT_TYPE */