1 /* Primitive operations on floating point for GNU Emacs Lisp interpreter.
2 Copyright (C) 1988, 1993, 1994, 1999 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, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
22 /* ANSI C requires only these float functions:
23 acos, asin, atan, atan2, ceil, cos, cosh, exp, fabs, floor, fmod,
24 frexp, ldexp, log, log10, modf, pow, sin, sinh, sqrt, tan, tanh.
26 Define HAVE_INVERSE_HYPERBOLIC if you have acosh, asinh, and atanh.
27 Define HAVE_CBRT if you have cbrt.
28 Define HAVE_RINT if you have a working rint.
29 If you don't define these, then the appropriate routines will be simulated.
31 Define HAVE_MATHERR if on a system supporting the SysV matherr callback.
32 (This should happen automatically.)
34 Define FLOAT_CHECK_ERRNO if the float library routines set errno.
35 This has no effect if HAVE_MATHERR is defined.
37 Define FLOAT_CATCH_SIGILL if the float library routines signal SIGILL.
38 (What systems actually do this? Please let us know.)
40 Define FLOAT_CHECK_DOMAIN if the float library doesn't handle errors by
41 either setting errno, or signaling SIGFPE/SIGILL. Otherwise, domain and
42 range checking will happen before calling the float routines. This has
43 no effect if HAVE_MATHERR is defined (since matherr will be called when
44 a domain error occurs.)
50 #include "syssignal.h"
56 /* If IEEE_FLOATING_POINT isn't defined, default it from FLT_*. */
57 #ifndef IEEE_FLOATING_POINT
58 #if (FLT_RADIX == 2 && FLT_MANT_DIG == 24 \
59 && FLT_MIN_EXP == -125 && FLT_MAX_EXP == 128)
60 #define IEEE_FLOATING_POINT 1
62 #define IEEE_FLOATING_POINT 0
66 /* Work around a problem that happens because math.h on hpux 7
67 defines two static variables--which, in Emacs, are not really static,
68 because `static' is defined as nothing. The problem is that they are
69 defined both here and in lread.c.
70 These macros prevent the name conflict. */
71 #if defined (HPUX) && !defined (HPUX8)
72 #define _MAXLDBL floatfns_maxldbl
73 #define _NMAXLDBL floatfns_nmaxldbl
78 /* This declaration is omitted on some systems, like Ultrix. */
79 #if !defined (HPUX) && defined (HAVE_LOGB) && !defined (logb)
80 extern double logb ();
81 #endif /* not HPUX and HAVE_LOGB and no logb macro */
83 #if defined(DOMAIN) && defined(SING) && defined(OVERFLOW)
84 /* If those are defined, then this is probably a `matherr' machine. */
95 # ifdef FLOAT_CHECK_ERRNO
96 # undef FLOAT_CHECK_ERRNO
98 # ifdef FLOAT_CHECK_DOMAIN
99 # undef FLOAT_CHECK_DOMAIN
103 #ifndef NO_FLOAT_CHECK_ERRNO
104 #define FLOAT_CHECK_ERRNO
107 #ifdef FLOAT_CHECK_ERRNO
113 /* Avoid traps on VMS from sinh and cosh.
114 All the other functions set errno instead. */
119 #define cosh(x) ((exp(x)+exp(-x))*0.5)
120 #define sinh(x) ((exp(x)-exp(-x))*0.5)
123 static SIGTYPE
float_error ();
125 /* Nonzero while executing in floating point.
126 This tells float_error what to do. */
130 /* If an argument is out of range for a mathematical function,
131 here is the actual argument value to use in the error message.
132 These variables are used only across the floating point library call
133 so there is no need to staticpro them. */
135 static Lisp_Object float_error_arg
, float_error_arg2
;
137 static char *float_error_fn_name
;
139 /* Evaluate the floating point expression D, recording NUM
140 as the original argument for error messages.
141 D is normally an assignment expression.
142 Handle errors which may result in signals or may set errno.
144 Note that float_error may be declared to return void, so you can't
145 just cast the zero after the colon to (SIGTYPE) to make the types
148 #ifdef FLOAT_CHECK_ERRNO
149 #define IN_FLOAT(d, name, num) \
151 float_error_arg = num; \
152 float_error_fn_name = name; \
153 in_float = 1; errno = 0; (d); in_float = 0; \
156 case EDOM: domain_error (float_error_fn_name, float_error_arg); \
157 case ERANGE: range_error (float_error_fn_name, float_error_arg); \
158 default: arith_error (float_error_fn_name, float_error_arg); \
161 #define IN_FLOAT2(d, name, num, num2) \
163 float_error_arg = num; \
164 float_error_arg2 = num2; \
165 float_error_fn_name = name; \
166 in_float = 1; errno = 0; (d); in_float = 0; \
169 case EDOM: domain_error (float_error_fn_name, float_error_arg); \
170 case ERANGE: range_error (float_error_fn_name, float_error_arg); \
171 default: arith_error (float_error_fn_name, float_error_arg); \
175 #define IN_FLOAT(d, name, num) (in_float = 1, (d), in_float = 0)
176 #define IN_FLOAT2(d, name, num, num2) (in_float = 1, (d), in_float = 0)
179 /* Convert float to Lisp_Int if it fits, else signal a range error
180 using the given arguments. */
181 #define FLOAT_TO_INT(x, i, name, num) \
184 if ((x) >= (((EMACS_INT) 1) << (VALBITS-1)) || \
185 (x) <= - (((EMACS_INT) 1) << (VALBITS-1)) - 1) \
186 range_error (name, num); \
187 XSETINT (i, (EMACS_INT)(x)); \
190 #define FLOAT_TO_INT2(x, i, name, num1, num2) \
193 if ((x) >= (((EMACS_INT) 1) << (VALBITS-1)) || \
194 (x) <= - (((EMACS_INT) 1) << (VALBITS-1)) - 1) \
195 range_error2 (name, num1, num2); \
196 XSETINT (i, (EMACS_INT)(x)); \
200 #define arith_error(op,arg) \
201 Fsignal (Qarith_error, Fcons (build_string ((op)), Fcons ((arg), Qnil)))
202 #define range_error(op,arg) \
203 Fsignal (Qrange_error, Fcons (build_string ((op)), Fcons ((arg), Qnil)))
204 #define range_error2(op,a1,a2) \
205 Fsignal (Qrange_error, Fcons (build_string ((op)), \
206 Fcons ((a1), Fcons ((a2), Qnil))))
207 #define domain_error(op,arg) \
208 Fsignal (Qdomain_error, Fcons (build_string ((op)), Fcons ((arg), Qnil)))
209 #define domain_error2(op,a1,a2) \
210 Fsignal (Qdomain_error, Fcons (build_string ((op)), \
211 Fcons ((a1), Fcons ((a2), Qnil))))
213 /* Extract a Lisp number as a `double', or signal an error. */
219 CHECK_NUMBER_OR_FLOAT (num
, 0);
222 return XFLOAT_DATA (num
);
223 return (double) XINT (num
);
226 /* Trig functions. */
228 DEFUN ("acos", Facos
, Sacos
, 1, 1, 0,
229 "Return the inverse cosine of ARG.")
231 register Lisp_Object arg
;
233 double d
= extract_float (arg
);
234 #ifdef FLOAT_CHECK_DOMAIN
235 if (d
> 1.0 || d
< -1.0)
236 domain_error ("acos", arg
);
238 IN_FLOAT (d
= acos (d
), "acos", arg
);
239 return make_float (d
);
242 DEFUN ("asin", Fasin
, Sasin
, 1, 1, 0,
243 "Return the inverse sine of ARG.")
245 register Lisp_Object arg
;
247 double d
= extract_float (arg
);
248 #ifdef FLOAT_CHECK_DOMAIN
249 if (d
> 1.0 || d
< -1.0)
250 domain_error ("asin", arg
);
252 IN_FLOAT (d
= asin (d
), "asin", arg
);
253 return make_float (d
);
256 DEFUN ("atan", Fatan
, Satan
, 1, 1, 0,
257 "Return the inverse tangent of ARG.")
259 register Lisp_Object arg
;
261 double d
= extract_float (arg
);
262 IN_FLOAT (d
= atan (d
), "atan", arg
);
263 return make_float (d
);
266 DEFUN ("cos", Fcos
, Scos
, 1, 1, 0,
267 "Return the cosine of ARG.")
269 register Lisp_Object arg
;
271 double d
= extract_float (arg
);
272 IN_FLOAT (d
= cos (d
), "cos", arg
);
273 return make_float (d
);
276 DEFUN ("sin", Fsin
, Ssin
, 1, 1, 0,
277 "Return the sine of ARG.")
279 register Lisp_Object arg
;
281 double d
= extract_float (arg
);
282 IN_FLOAT (d
= sin (d
), "sin", arg
);
283 return make_float (d
);
286 DEFUN ("tan", Ftan
, Stan
, 1, 1, 0,
287 "Return the tangent of ARG.")
289 register Lisp_Object arg
;
291 double d
= extract_float (arg
);
293 #ifdef FLOAT_CHECK_DOMAIN
295 domain_error ("tan", arg
);
297 IN_FLOAT (d
= sin (d
) / c
, "tan", arg
);
298 return make_float (d
);
301 #if 0 /* Leave these out unless we find there's a reason for them. */
303 DEFUN ("bessel-j0", Fbessel_j0
, Sbessel_j0
, 1, 1, 0,
304 "Return the bessel function j0 of ARG.")
306 register Lisp_Object arg
;
308 double d
= extract_float (arg
);
309 IN_FLOAT (d
= j0 (d
), "bessel-j0", arg
);
310 return make_float (d
);
313 DEFUN ("bessel-j1", Fbessel_j1
, Sbessel_j1
, 1, 1, 0,
314 "Return the bessel function j1 of ARG.")
316 register Lisp_Object arg
;
318 double d
= extract_float (arg
);
319 IN_FLOAT (d
= j1 (d
), "bessel-j1", arg
);
320 return make_float (d
);
323 DEFUN ("bessel-jn", Fbessel_jn
, Sbessel_jn
, 2, 2, 0,
324 "Return the order N bessel function output jn of ARG.\n\
325 The first arg (the order) is truncated to an integer.")
327 register Lisp_Object n
, arg
;
329 int i1
= extract_float (n
);
330 double f2
= extract_float (arg
);
332 IN_FLOAT (f2
= jn (i1
, f2
), "bessel-jn", n
);
333 return make_float (f2
);
336 DEFUN ("bessel-y0", Fbessel_y0
, Sbessel_y0
, 1, 1, 0,
337 "Return the bessel function y0 of ARG.")
339 register Lisp_Object arg
;
341 double d
= extract_float (arg
);
342 IN_FLOAT (d
= y0 (d
), "bessel-y0", arg
);
343 return make_float (d
);
346 DEFUN ("bessel-y1", Fbessel_y1
, Sbessel_y1
, 1, 1, 0,
347 "Return the bessel function y1 of ARG.")
349 register Lisp_Object arg
;
351 double d
= extract_float (arg
);
352 IN_FLOAT (d
= y1 (d
), "bessel-y0", arg
);
353 return make_float (d
);
356 DEFUN ("bessel-yn", Fbessel_yn
, Sbessel_yn
, 2, 2, 0,
357 "Return the order N bessel function output yn of ARG.\n\
358 The first arg (the order) is truncated to an integer.")
360 register Lisp_Object n
, arg
;
362 int i1
= extract_float (n
);
363 double f2
= extract_float (arg
);
365 IN_FLOAT (f2
= yn (i1
, f2
), "bessel-yn", n
);
366 return make_float (f2
);
371 #if 0 /* Leave these out unless we see they are worth having. */
373 DEFUN ("erf", Ferf
, Serf
, 1, 1, 0,
374 "Return the mathematical error function of ARG.")
376 register Lisp_Object arg
;
378 double d
= extract_float (arg
);
379 IN_FLOAT (d
= erf (d
), "erf", arg
);
380 return make_float (d
);
383 DEFUN ("erfc", Ferfc
, Serfc
, 1, 1, 0,
384 "Return the complementary error function of ARG.")
386 register Lisp_Object arg
;
388 double d
= extract_float (arg
);
389 IN_FLOAT (d
= erfc (d
), "erfc", arg
);
390 return make_float (d
);
393 DEFUN ("log-gamma", Flog_gamma
, Slog_gamma
, 1, 1, 0,
394 "Return the log gamma of ARG.")
396 register Lisp_Object arg
;
398 double d
= extract_float (arg
);
399 IN_FLOAT (d
= lgamma (d
), "log-gamma", arg
);
400 return make_float (d
);
403 DEFUN ("cube-root", Fcube_root
, Scube_root
, 1, 1, 0,
404 "Return the cube root of ARG.")
406 register Lisp_Object arg
;
408 double d
= extract_float (arg
);
410 IN_FLOAT (d
= cbrt (d
), "cube-root", arg
);
413 IN_FLOAT (d
= pow (d
, 1.0/3.0), "cube-root", arg
);
415 IN_FLOAT (d
= -pow (-d
, 1.0/3.0), "cube-root", arg
);
417 return make_float (d
);
422 DEFUN ("exp", Fexp
, Sexp
, 1, 1, 0,
423 "Return the exponential base e of ARG.")
425 register Lisp_Object arg
;
427 double d
= extract_float (arg
);
428 #ifdef FLOAT_CHECK_DOMAIN
429 if (d
> 709.7827) /* Assume IEEE doubles here */
430 range_error ("exp", arg
);
432 return make_float (0.0);
435 IN_FLOAT (d
= exp (d
), "exp", arg
);
436 return make_float (d
);
439 DEFUN ("expt", Fexpt
, Sexpt
, 2, 2, 0,
440 "Return the exponential ARG1 ** ARG2.")
442 register Lisp_Object arg1
, arg2
;
446 CHECK_NUMBER_OR_FLOAT (arg1
, 0);
447 CHECK_NUMBER_OR_FLOAT (arg2
, 0);
448 if (INTEGERP (arg1
) /* common lisp spec */
449 && INTEGERP (arg2
)) /* don't promote, if both are ints */
450 { /* this can be improved by pre-calculating */
451 EMACS_INT acc
, x
, y
; /* some binary powers of x then accumulating */
463 acc
= (y
& 1) ? -1 : 1;
474 y
= (unsigned)y
>> 1;
480 f1
= FLOATP (arg1
) ? XFLOAT_DATA (arg1
) : XINT (arg1
);
481 f2
= FLOATP (arg2
) ? XFLOAT_DATA (arg2
) : XINT (arg2
);
482 /* Really should check for overflow, too */
483 if (f1
== 0.0 && f2
== 0.0)
485 #ifdef FLOAT_CHECK_DOMAIN
486 else if ((f1
== 0.0 && f2
< 0.0) || (f1
< 0 && f2
!= floor(f2
)))
487 domain_error2 ("expt", arg1
, arg2
);
489 IN_FLOAT2 (f1
= pow (f1
, f2
), "expt", arg1
, arg2
);
490 return make_float (f1
);
493 DEFUN ("log", Flog
, Slog
, 1, 2, 0,
494 "Return the natural logarithm of ARG.\n\
495 If second optional argument BASE is given, return log ARG using that base.")
497 register Lisp_Object arg
, base
;
499 double d
= extract_float (arg
);
501 #ifdef FLOAT_CHECK_DOMAIN
503 domain_error2 ("log", arg
, base
);
506 IN_FLOAT (d
= log (d
), "log", arg
);
509 double b
= extract_float (base
);
511 #ifdef FLOAT_CHECK_DOMAIN
512 if (b
<= 0.0 || b
== 1.0)
513 domain_error2 ("log", arg
, base
);
516 IN_FLOAT2 (d
= log10 (d
), "log", arg
, base
);
518 IN_FLOAT2 (d
= log (d
) / log (b
), "log", arg
, base
);
520 return make_float (d
);
523 DEFUN ("log10", Flog10
, Slog10
, 1, 1, 0,
524 "Return the logarithm base 10 of ARG.")
526 register Lisp_Object arg
;
528 double d
= extract_float (arg
);
529 #ifdef FLOAT_CHECK_DOMAIN
531 domain_error ("log10", arg
);
533 IN_FLOAT (d
= log10 (d
), "log10", arg
);
534 return make_float (d
);
537 DEFUN ("sqrt", Fsqrt
, Ssqrt
, 1, 1, 0,
538 "Return the square root of ARG.")
540 register Lisp_Object arg
;
542 double d
= extract_float (arg
);
543 #ifdef FLOAT_CHECK_DOMAIN
545 domain_error ("sqrt", arg
);
547 IN_FLOAT (d
= sqrt (d
), "sqrt", arg
);
548 return make_float (d
);
551 #if 0 /* Not clearly worth adding. */
553 DEFUN ("acosh", Facosh
, Sacosh
, 1, 1, 0,
554 "Return the inverse hyperbolic cosine of ARG.")
556 register Lisp_Object arg
;
558 double d
= extract_float (arg
);
559 #ifdef FLOAT_CHECK_DOMAIN
561 domain_error ("acosh", arg
);
563 #ifdef HAVE_INVERSE_HYPERBOLIC
564 IN_FLOAT (d
= acosh (d
), "acosh", arg
);
566 IN_FLOAT (d
= log (d
+ sqrt (d
*d
- 1.0)), "acosh", arg
);
568 return make_float (d
);
571 DEFUN ("asinh", Fasinh
, Sasinh
, 1, 1, 0,
572 "Return the inverse hyperbolic sine of ARG.")
574 register Lisp_Object arg
;
576 double d
= extract_float (arg
);
577 #ifdef HAVE_INVERSE_HYPERBOLIC
578 IN_FLOAT (d
= asinh (d
), "asinh", arg
);
580 IN_FLOAT (d
= log (d
+ sqrt (d
*d
+ 1.0)), "asinh", arg
);
582 return make_float (d
);
585 DEFUN ("atanh", Fatanh
, Satanh
, 1, 1, 0,
586 "Return the inverse hyperbolic tangent of ARG.")
588 register Lisp_Object arg
;
590 double d
= extract_float (arg
);
591 #ifdef FLOAT_CHECK_DOMAIN
592 if (d
>= 1.0 || d
<= -1.0)
593 domain_error ("atanh", arg
);
595 #ifdef HAVE_INVERSE_HYPERBOLIC
596 IN_FLOAT (d
= atanh (d
), "atanh", arg
);
598 IN_FLOAT (d
= 0.5 * log ((1.0 + d
) / (1.0 - d
)), "atanh", arg
);
600 return make_float (d
);
603 DEFUN ("cosh", Fcosh
, Scosh
, 1, 1, 0,
604 "Return the hyperbolic cosine of ARG.")
606 register Lisp_Object arg
;
608 double d
= extract_float (arg
);
609 #ifdef FLOAT_CHECK_DOMAIN
610 if (d
> 710.0 || d
< -710.0)
611 range_error ("cosh", arg
);
613 IN_FLOAT (d
= cosh (d
), "cosh", arg
);
614 return make_float (d
);
617 DEFUN ("sinh", Fsinh
, Ssinh
, 1, 1, 0,
618 "Return the hyperbolic sine of ARG.")
620 register Lisp_Object arg
;
622 double d
= extract_float (arg
);
623 #ifdef FLOAT_CHECK_DOMAIN
624 if (d
> 710.0 || d
< -710.0)
625 range_error ("sinh", arg
);
627 IN_FLOAT (d
= sinh (d
), "sinh", arg
);
628 return make_float (d
);
631 DEFUN ("tanh", Ftanh
, Stanh
, 1, 1, 0,
632 "Return the hyperbolic tangent of ARG.")
634 register Lisp_Object arg
;
636 double d
= extract_float (arg
);
637 IN_FLOAT (d
= tanh (d
), "tanh", arg
);
638 return make_float (d
);
642 DEFUN ("abs", Fabs
, Sabs
, 1, 1, 0,
643 "Return the absolute value of ARG.")
645 register Lisp_Object arg
;
647 CHECK_NUMBER_OR_FLOAT (arg
, 0);
650 IN_FLOAT (arg
= make_float (fabs (XFLOAT_DATA (arg
))), "abs", arg
);
651 else if (XINT (arg
) < 0)
652 XSETINT (arg
, - XINT (arg
));
657 DEFUN ("float", Ffloat
, Sfloat
, 1, 1, 0,
658 "Return the floating point number equal to ARG.")
660 register Lisp_Object arg
;
662 CHECK_NUMBER_OR_FLOAT (arg
, 0);
665 return make_float ((double) XINT (arg
));
666 else /* give 'em the same float back */
670 DEFUN ("logb", Flogb
, Slogb
, 1, 1, 0,
671 "Returns largest integer <= the base 2 log of the magnitude of ARG.\n\
672 This is the same as the exponent of a float.")
678 double f
= extract_float (arg
);
681 value
= -(VALMASK
>> 1);
685 IN_FLOAT (value
= logb (f
), "logb", arg
);
689 IN_FLOAT (frexp (f
, &ivalue
), "logb", arg
);
699 for (i
= 1, d
= 0.5; d
* d
>= f
; i
+= i
)
706 for (i
= 1, d
= 2.0; d
* d
<= f
; i
+= i
)
714 XSETINT (val
, value
);
719 /* the rounding functions */
722 rounding_driver (arg
, divisor
, double_round
, int_round2
, name
)
723 register Lisp_Object arg
, divisor
;
724 double (*double_round
) ();
725 EMACS_INT (*int_round2
) ();
728 CHECK_NUMBER_OR_FLOAT (arg
, 0);
730 if (! NILP (divisor
))
734 CHECK_NUMBER_OR_FLOAT (divisor
, 1);
736 if (FLOATP (arg
) || FLOATP (divisor
))
740 f1
= FLOATP (arg
) ? XFLOAT_DATA (arg
) : XINT (arg
);
741 f2
= (FLOATP (divisor
) ? XFLOAT_DATA (divisor
) : XINT (divisor
));
742 if (! IEEE_FLOATING_POINT
&& f2
== 0)
743 Fsignal (Qarith_error
, Qnil
);
745 IN_FLOAT2 (f1
= (*double_round
) (f1
/ f2
), name
, arg
, divisor
);
746 FLOAT_TO_INT2 (f1
, arg
, name
, arg
, divisor
);
754 Fsignal (Qarith_error
, Qnil
);
756 XSETINT (arg
, (*int_round2
) (i1
, i2
));
764 IN_FLOAT (d
= (*double_round
) (XFLOAT_DATA (arg
)), name
, arg
);
765 FLOAT_TO_INT (d
, arg
, name
, arg
);
771 /* With C's /, the result is implementation-defined if either operand
772 is negative, so take care with negative operands in the following
773 integer functions. */
780 ? (i1
< 0 ? ((-1 - i1
) / -i2
) + 1 : - (i1
/ -i2
))
781 : (i1
<= 0 ? - (-i1
/ i2
) : ((i1
- 1) / i2
) + 1));
789 ? (i1
<= 0 ? -i1
/ -i2
: -1 - ((i1
- 1) / -i2
))
790 : (i1
< 0 ? -1 - ((-1 - i1
) / i2
) : i1
/ i2
));
798 ? (i1
< 0 ? -i1
/ -i2
: - (i1
/ -i2
))
799 : (i1
< 0 ? - (-i1
/ i2
) : i1
/ i2
));
806 /* The C language's division operator gives us one remainder R, but
807 we want the remainder R1 on the other side of 0 if R1 is closer
808 to 0 than R is; because we want to round to even, we also want R1
809 if R and R1 are the same distance from 0 and if C's quotient is
811 EMACS_INT q
= i1
/ i2
;
812 EMACS_INT r
= i1
% i2
;
813 EMACS_INT abs_r
= r
< 0 ? -r
: r
;
814 EMACS_INT abs_r1
= (i2
< 0 ? -i2
: i2
) - abs_r
;
815 return q
+ (abs_r
+ (q
& 1) <= abs_r1
? 0 : (i2
^ r
) < 0 ? -1 : 1);
818 /* The code uses emacs_rint, so that it works to undefine HAVE_RINT
819 if `rint' exists but does not work right. */
821 #define emacs_rint rint
827 return floor (d
+ 0.5);
838 DEFUN ("ceiling", Fceiling
, Sceiling
, 1, 2, 0,
839 "Return the smallest integer no less than ARG. (Round toward +inf.)\n\
840 With optional DIVISOR, return the smallest integer no less than ARG/DIVISOR.")
842 Lisp_Object arg
, divisor
;
844 return rounding_driver (arg
, divisor
, ceil
, ceiling2
, "ceiling");
847 DEFUN ("floor", Ffloor
, Sfloor
, 1, 2, 0,
848 "Return the largest integer no greater than ARG. (Round towards -inf.)\n\
849 With optional DIVISOR, return the largest integer no greater than ARG/DIVISOR.")
851 Lisp_Object arg
, divisor
;
853 return rounding_driver (arg
, divisor
, floor
, floor2
, "floor");
856 DEFUN ("round", Fround
, Sround
, 1, 2, 0,
857 "Return the nearest integer to ARG.\n\
858 With optional DIVISOR, return the nearest integer to ARG/DIVISOR.")
860 Lisp_Object arg
, divisor
;
862 return rounding_driver (arg
, divisor
, emacs_rint
, round2
, "round");
865 DEFUN ("truncate", Ftruncate
, Struncate
, 1, 2, 0,
866 "Truncate a floating point number to an int.\n\
867 Rounds ARG toward zero.\n\
868 With optional DIVISOR, truncate ARG/DIVISOR.")
870 Lisp_Object arg
, divisor
;
872 return rounding_driver (arg
, divisor
, double_identity
, truncate2
,
879 register Lisp_Object x
, y
;
883 f1
= FLOATP (x
) ? XFLOAT_DATA (x
) : XINT (x
);
884 f2
= FLOATP (y
) ? XFLOAT_DATA (y
) : XINT (y
);
886 if (! IEEE_FLOATING_POINT
&& f2
== 0)
887 Fsignal (Qarith_error
, Qnil
);
889 /* If the "remainder" comes out with the wrong sign, fix it. */
890 IN_FLOAT2 ((f1
= fmod (f1
, f2
),
891 f1
= (f2
< 0 ? f1
> 0 : f1
< 0) ? f1
+ f2
: f1
),
893 return make_float (f1
);
896 /* It's not clear these are worth adding. */
898 DEFUN ("fceiling", Ffceiling
, Sfceiling
, 1, 1, 0,
899 "Return the smallest integer no less than ARG, as a float.\n\
900 \(Round toward +inf.\)")
902 register Lisp_Object arg
;
904 double d
= extract_float (arg
);
905 IN_FLOAT (d
= ceil (d
), "fceiling", arg
);
906 return make_float (d
);
909 DEFUN ("ffloor", Fffloor
, Sffloor
, 1, 1, 0,
910 "Return the largest integer no greater than ARG, as a float.\n\
911 \(Round towards -inf.\)")
913 register Lisp_Object arg
;
915 double d
= extract_float (arg
);
916 IN_FLOAT (d
= floor (d
), "ffloor", arg
);
917 return make_float (d
);
920 DEFUN ("fround", Ffround
, Sfround
, 1, 1, 0,
921 "Return the nearest integer to ARG, as a float.")
923 register Lisp_Object arg
;
925 double d
= extract_float (arg
);
926 IN_FLOAT (d
= emacs_rint (d
), "fround", arg
);
927 return make_float (d
);
930 DEFUN ("ftruncate", Fftruncate
, Sftruncate
, 1, 1, 0,
931 "Truncate a floating point number to an integral float value.\n\
932 Rounds the value toward zero.")
934 register Lisp_Object arg
;
936 double d
= extract_float (arg
);
938 IN_FLOAT (d
= floor (d
), "ftruncate", arg
);
940 IN_FLOAT (d
= ceil (d
), "ftruncate", arg
);
941 return make_float (d
);
944 #ifdef FLOAT_CATCH_SIGILL
950 fatal_error_signal (signo
);
955 #else /* not BSD4_1 */
956 sigsetmask (SIGEMPTYMASK
);
957 #endif /* not BSD4_1 */
959 /* Must reestablish handler each time it is called. */
960 signal (SIGILL
, float_error
);
961 #endif /* BSD_SYSTEM */
965 Fsignal (Qarith_error
, Fcons (float_error_arg
, Qnil
));
968 /* Another idea was to replace the library function `infnan'
969 where SIGILL is signaled. */
971 #endif /* FLOAT_CATCH_SIGILL */
980 /* Not called from emacs-lisp float routines; do the default thing. */
982 if (!strcmp (x
->name
, "pow"))
986 = Fcons (build_string (x
->name
),
987 Fcons (make_float (x
->arg1
),
988 ((!strcmp (x
->name
, "log") || !strcmp (x
->name
, "pow"))
989 ? Fcons (make_float (x
->arg2
), Qnil
)
993 case DOMAIN
: Fsignal (Qdomain_error
, args
); break;
994 case SING
: Fsignal (Qsingularity_error
, args
); break;
995 case OVERFLOW
: Fsignal (Qoverflow_error
, args
); break;
996 case UNDERFLOW
: Fsignal (Qunderflow_error
, args
); break;
997 default: Fsignal (Qarith_error
, args
); break;
999 return (1); /* don't set errno or print a message */
1001 #endif /* HAVE_MATHERR */
1006 #ifdef FLOAT_CATCH_SIGILL
1007 signal (SIGILL
, float_error
);
1028 defsubr (&Sbessel_y0
);
1029 defsubr (&Sbessel_y1
);
1030 defsubr (&Sbessel_yn
);
1031 defsubr (&Sbessel_j0
);
1032 defsubr (&Sbessel_j1
);
1033 defsubr (&Sbessel_jn
);
1036 defsubr (&Slog_gamma
);
1037 defsubr (&Scube_root
);
1039 defsubr (&Sfceiling
);
1042 defsubr (&Sftruncate
);
1052 defsubr (&Sceiling
);
1055 defsubr (&Struncate
);