1 /* Primitive operations on floating point for GNU Emacs Lisp interpreter.
2 Copyright (C) 1988, 1993, 1994, 1999, 2001, 2002, 2003, 2004,
3 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
5 Author: Wolfgang Rupprecht
6 (according to ack.texi)
8 This file is part of GNU Emacs.
10 GNU Emacs is free software: you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation, either version 3 of the License, or
13 (at your option) any later version.
15 GNU Emacs is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
24 /* ANSI C requires only these float functions:
25 acos, asin, atan, atan2, ceil, cos, cosh, exp, fabs, floor, fmod,
26 frexp, ldexp, log, log10, modf, pow, sin, sinh, sqrt, tan, tanh.
28 Define HAVE_INVERSE_HYPERBOLIC if you have acosh, asinh, and atanh.
29 Define HAVE_CBRT if you have cbrt.
30 Define HAVE_RINT if you have a working rint.
31 If you don't define these, then the appropriate routines will be simulated.
33 Define HAVE_MATHERR if on a system supporting the SysV matherr callback.
34 (This should happen automatically.)
36 Define FLOAT_CHECK_ERRNO if the float library routines set errno.
37 This has no effect if HAVE_MATHERR is defined.
39 Define FLOAT_CATCH_SIGILL if the float library routines signal SIGILL.
40 (What systems actually do this? Please let us know.)
42 Define FLOAT_CHECK_DOMAIN if the float library doesn't handle errors by
43 either setting errno, or signaling SIGFPE/SIGILL. Otherwise, domain and
44 range checking will happen before calling the float routines. This has
45 no effect if HAVE_MATHERR is defined (since matherr will be called when
46 a domain error occurs.)
53 #include "syssignal.h"
59 /* If IEEE_FLOATING_POINT isn't defined, default it from FLT_*. */
60 #ifndef IEEE_FLOATING_POINT
61 #if (FLT_RADIX == 2 && FLT_MANT_DIG == 24 \
62 && FLT_MIN_EXP == -125 && FLT_MAX_EXP == 128)
63 #define IEEE_FLOATING_POINT 1
65 #define IEEE_FLOATING_POINT 0
71 /* This declaration is omitted on some systems, like Ultrix. */
72 #if !defined (HPUX) && defined (HAVE_LOGB) && !defined (logb)
73 extern double logb ();
74 #endif /* not HPUX and HAVE_LOGB and no logb macro */
76 #if defined(DOMAIN) && defined(SING) && defined(OVERFLOW)
77 /* If those are defined, then this is probably a `matherr' machine. */
88 # ifdef FLOAT_CHECK_ERRNO
89 # undef FLOAT_CHECK_ERRNO
91 # ifdef FLOAT_CHECK_DOMAIN
92 # undef FLOAT_CHECK_DOMAIN
96 #ifndef NO_FLOAT_CHECK_ERRNO
97 #define FLOAT_CHECK_ERRNO
100 #ifdef FLOAT_CHECK_ERRNO
108 #ifdef FLOAT_CATCH_SIGILL
109 static SIGTYPE
float_error ();
112 /* Nonzero while executing in floating point.
113 This tells float_error what to do. */
117 /* If an argument is out of range for a mathematical function,
118 here is the actual argument value to use in the error message.
119 These variables are used only across the floating point library call
120 so there is no need to staticpro them. */
122 static Lisp_Object float_error_arg
, float_error_arg2
;
124 static char *float_error_fn_name
;
126 /* Evaluate the floating point expression D, recording NUM
127 as the original argument for error messages.
128 D is normally an assignment expression.
129 Handle errors which may result in signals or may set errno.
131 Note that float_error may be declared to return void, so you can't
132 just cast the zero after the colon to (SIGTYPE) to make the types
135 #ifdef FLOAT_CHECK_ERRNO
136 #define IN_FLOAT(d, name, num) \
138 float_error_arg = num; \
139 float_error_fn_name = name; \
140 in_float = 1; errno = 0; (d); in_float = 0; \
143 case EDOM: domain_error (float_error_fn_name, float_error_arg); \
144 case ERANGE: range_error (float_error_fn_name, float_error_arg); \
145 default: arith_error (float_error_fn_name, float_error_arg); \
148 #define IN_FLOAT2(d, name, num, num2) \
150 float_error_arg = num; \
151 float_error_arg2 = num2; \
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); \
162 #define IN_FLOAT(d, name, num) (in_float = 1, (d), in_float = 0)
163 #define IN_FLOAT2(d, name, num, num2) (in_float = 1, (d), in_float = 0)
166 /* Convert float to Lisp_Int if it fits, else signal a range error
167 using the given arguments. */
168 #define FLOAT_TO_INT(x, i, name, num) \
171 if (FIXNUM_OVERFLOW_P (x)) \
172 range_error (name, num); \
173 XSETINT (i, (EMACS_INT)(x)); \
176 #define FLOAT_TO_INT2(x, i, name, num1, num2) \
179 if (FIXNUM_OVERFLOW_P (x)) \
180 range_error2 (name, num1, num2); \
181 XSETINT (i, (EMACS_INT)(x)); \
185 #define arith_error(op,arg) \
186 xsignal2 (Qarith_error, build_string ((op)), (arg))
187 #define range_error(op,arg) \
188 xsignal2 (Qrange_error, build_string ((op)), (arg))
189 #define range_error2(op,a1,a2) \
190 xsignal3 (Qrange_error, build_string ((op)), (a1), (a2))
191 #define domain_error(op,arg) \
192 xsignal2 (Qdomain_error, build_string ((op)), (arg))
193 #define domain_error2(op,a1,a2) \
194 xsignal3 (Qdomain_error, build_string ((op)), (a1), (a2))
196 /* Extract a Lisp number as a `double', or signal an error. */
202 CHECK_NUMBER_OR_FLOAT (num
);
205 return XFLOAT_DATA (num
);
206 return (double) XINT (num
);
209 /* Trig functions. */
211 DEFUN ("acos", Facos
, Sacos
, 1, 1, 0,
212 doc
: /* Return the inverse cosine of ARG. */)
214 register Lisp_Object arg
;
216 double d
= extract_float (arg
);
217 #ifdef FLOAT_CHECK_DOMAIN
218 if (d
> 1.0 || d
< -1.0)
219 domain_error ("acos", arg
);
221 IN_FLOAT (d
= acos (d
), "acos", arg
);
222 return make_float (d
);
225 DEFUN ("asin", Fasin
, Sasin
, 1, 1, 0,
226 doc
: /* Return the inverse sine of ARG. */)
228 register Lisp_Object arg
;
230 double d
= extract_float (arg
);
231 #ifdef FLOAT_CHECK_DOMAIN
232 if (d
> 1.0 || d
< -1.0)
233 domain_error ("asin", arg
);
235 IN_FLOAT (d
= asin (d
), "asin", arg
);
236 return make_float (d
);
239 DEFUN ("atan", Fatan
, Satan
, 1, 2, 0,
240 doc
: /* Return the inverse tangent of the arguments.
241 If only one argument Y is given, return the inverse tangent of Y.
242 If two arguments Y and X are given, return the inverse tangent of Y
243 divided by X, i.e. the angle in radians between the vector (X, Y)
246 register Lisp_Object y
, x
;
248 double d
= extract_float (y
);
251 IN_FLOAT (d
= atan (d
), "atan", y
);
254 double d2
= extract_float (x
);
256 IN_FLOAT2 (d
= atan2 (d
, d2
), "atan", y
, x
);
258 return make_float (d
);
261 DEFUN ("cos", Fcos
, Scos
, 1, 1, 0,
262 doc
: /* Return the cosine of ARG. */)
264 register Lisp_Object arg
;
266 double d
= extract_float (arg
);
267 IN_FLOAT (d
= cos (d
), "cos", arg
);
268 return make_float (d
);
271 DEFUN ("sin", Fsin
, Ssin
, 1, 1, 0,
272 doc
: /* Return the sine of ARG. */)
274 register Lisp_Object arg
;
276 double d
= extract_float (arg
);
277 IN_FLOAT (d
= sin (d
), "sin", arg
);
278 return make_float (d
);
281 DEFUN ("tan", Ftan
, Stan
, 1, 1, 0,
282 doc
: /* Return the tangent of ARG. */)
284 register Lisp_Object arg
;
286 double d
= extract_float (arg
);
288 #ifdef FLOAT_CHECK_DOMAIN
290 domain_error ("tan", arg
);
292 IN_FLOAT (d
= sin (d
) / c
, "tan", arg
);
293 return make_float (d
);
296 #if 0 /* Leave these out unless we find there's a reason for them. */
298 DEFUN ("bessel-j0", Fbessel_j0
, Sbessel_j0
, 1, 1, 0,
299 doc
: /* Return the bessel function j0 of ARG. */)
301 register Lisp_Object arg
;
303 double d
= extract_float (arg
);
304 IN_FLOAT (d
= j0 (d
), "bessel-j0", arg
);
305 return make_float (d
);
308 DEFUN ("bessel-j1", Fbessel_j1
, Sbessel_j1
, 1, 1, 0,
309 doc
: /* Return the bessel function j1 of ARG. */)
311 register Lisp_Object arg
;
313 double d
= extract_float (arg
);
314 IN_FLOAT (d
= j1 (d
), "bessel-j1", arg
);
315 return make_float (d
);
318 DEFUN ("bessel-jn", Fbessel_jn
, Sbessel_jn
, 2, 2, 0,
319 doc
: /* Return the order N bessel function output jn of ARG.
320 The first arg (the order) is truncated to an integer. */)
322 register Lisp_Object n
, arg
;
324 int i1
= extract_float (n
);
325 double f2
= extract_float (arg
);
327 IN_FLOAT (f2
= jn (i1
, f2
), "bessel-jn", n
);
328 return make_float (f2
);
331 DEFUN ("bessel-y0", Fbessel_y0
, Sbessel_y0
, 1, 1, 0,
332 doc
: /* Return the bessel function y0 of ARG. */)
334 register Lisp_Object arg
;
336 double d
= extract_float (arg
);
337 IN_FLOAT (d
= y0 (d
), "bessel-y0", arg
);
338 return make_float (d
);
341 DEFUN ("bessel-y1", Fbessel_y1
, Sbessel_y1
, 1, 1, 0,
342 doc
: /* Return the bessel function y1 of ARG. */)
344 register Lisp_Object arg
;
346 double d
= extract_float (arg
);
347 IN_FLOAT (d
= y1 (d
), "bessel-y0", arg
);
348 return make_float (d
);
351 DEFUN ("bessel-yn", Fbessel_yn
, Sbessel_yn
, 2, 2, 0,
352 doc
: /* Return the order N bessel function output yn of ARG.
353 The first arg (the order) is truncated to an integer. */)
355 register Lisp_Object n
, arg
;
357 int i1
= extract_float (n
);
358 double f2
= extract_float (arg
);
360 IN_FLOAT (f2
= yn (i1
, f2
), "bessel-yn", n
);
361 return make_float (f2
);
366 #if 0 /* Leave these out unless we see they are worth having. */
368 DEFUN ("erf", Ferf
, Serf
, 1, 1, 0,
369 doc
: /* Return the mathematical error function of ARG. */)
371 register Lisp_Object arg
;
373 double d
= extract_float (arg
);
374 IN_FLOAT (d
= erf (d
), "erf", arg
);
375 return make_float (d
);
378 DEFUN ("erfc", Ferfc
, Serfc
, 1, 1, 0,
379 doc
: /* Return the complementary error function of ARG. */)
381 register Lisp_Object arg
;
383 double d
= extract_float (arg
);
384 IN_FLOAT (d
= erfc (d
), "erfc", arg
);
385 return make_float (d
);
388 DEFUN ("log-gamma", Flog_gamma
, Slog_gamma
, 1, 1, 0,
389 doc
: /* Return the log gamma of ARG. */)
391 register Lisp_Object arg
;
393 double d
= extract_float (arg
);
394 IN_FLOAT (d
= lgamma (d
), "log-gamma", arg
);
395 return make_float (d
);
398 DEFUN ("cube-root", Fcube_root
, Scube_root
, 1, 1, 0,
399 doc
: /* Return the cube root of ARG. */)
401 register Lisp_Object arg
;
403 double d
= extract_float (arg
);
405 IN_FLOAT (d
= cbrt (d
), "cube-root", arg
);
408 IN_FLOAT (d
= pow (d
, 1.0/3.0), "cube-root", arg
);
410 IN_FLOAT (d
= -pow (-d
, 1.0/3.0), "cube-root", arg
);
412 return make_float (d
);
417 DEFUN ("exp", Fexp
, Sexp
, 1, 1, 0,
418 doc
: /* Return the exponential base e of ARG. */)
420 register Lisp_Object arg
;
422 double d
= extract_float (arg
);
423 #ifdef FLOAT_CHECK_DOMAIN
424 if (d
> 709.7827) /* Assume IEEE doubles here */
425 range_error ("exp", arg
);
427 return make_float (0.0);
430 IN_FLOAT (d
= exp (d
), "exp", arg
);
431 return make_float (d
);
434 DEFUN ("expt", Fexpt
, Sexpt
, 2, 2, 0,
435 doc
: /* Return the exponential ARG1 ** ARG2. */)
437 register Lisp_Object arg1
, arg2
;
441 CHECK_NUMBER_OR_FLOAT (arg1
);
442 CHECK_NUMBER_OR_FLOAT (arg2
);
443 if (INTEGERP (arg1
) /* common lisp spec */
444 && INTEGERP (arg2
) /* don't promote, if both are ints, and */
445 && 0 <= XINT (arg2
)) /* we are sure the result is not fractional */
446 { /* this can be improved by pre-calculating */
447 EMACS_INT acc
, x
, y
; /* some binary powers of x then accumulating */
459 acc
= (y
& 1) ? -1 : 1;
470 y
= (unsigned)y
>> 1;
476 f1
= FLOATP (arg1
) ? XFLOAT_DATA (arg1
) : XINT (arg1
);
477 f2
= FLOATP (arg2
) ? XFLOAT_DATA (arg2
) : XINT (arg2
);
478 /* Really should check for overflow, too */
479 if (f1
== 0.0 && f2
== 0.0)
481 #ifdef FLOAT_CHECK_DOMAIN
482 else if ((f1
== 0.0 && f2
< 0.0) || (f1
< 0 && f2
!= floor(f2
)))
483 domain_error2 ("expt", arg1
, arg2
);
485 IN_FLOAT2 (f3
= pow (f1
, f2
), "expt", arg1
, arg2
);
486 /* Check for overflow in the result. */
487 if (f1
!= 0.0 && f3
== 0.0)
488 range_error ("expt", arg1
);
489 return make_float (f3
);
492 DEFUN ("log", Flog
, Slog
, 1, 2, 0,
493 doc
: /* Return the natural logarithm of ARG.
494 If the optional argument BASE is given, return log ARG using that base. */)
496 register Lisp_Object arg
, base
;
498 double d
= extract_float (arg
);
500 #ifdef FLOAT_CHECK_DOMAIN
502 domain_error2 ("log", arg
, base
);
505 IN_FLOAT (d
= log (d
), "log", arg
);
508 double b
= extract_float (base
);
510 #ifdef FLOAT_CHECK_DOMAIN
511 if (b
<= 0.0 || b
== 1.0)
512 domain_error2 ("log", arg
, base
);
515 IN_FLOAT2 (d
= log10 (d
), "log", arg
, base
);
517 IN_FLOAT2 (d
= log (d
) / log (b
), "log", arg
, base
);
519 return make_float (d
);
522 DEFUN ("log10", Flog10
, Slog10
, 1, 1, 0,
523 doc
: /* Return the logarithm base 10 of ARG. */)
525 register Lisp_Object arg
;
527 double d
= extract_float (arg
);
528 #ifdef FLOAT_CHECK_DOMAIN
530 domain_error ("log10", arg
);
532 IN_FLOAT (d
= log10 (d
), "log10", arg
);
533 return make_float (d
);
536 DEFUN ("sqrt", Fsqrt
, Ssqrt
, 1, 1, 0,
537 doc
: /* Return the square root of ARG. */)
539 register Lisp_Object arg
;
541 double d
= extract_float (arg
);
542 #ifdef FLOAT_CHECK_DOMAIN
544 domain_error ("sqrt", arg
);
546 IN_FLOAT (d
= sqrt (d
), "sqrt", arg
);
547 return make_float (d
);
550 #if 0 /* Not clearly worth adding. */
552 DEFUN ("acosh", Facosh
, Sacosh
, 1, 1, 0,
553 doc
: /* Return the inverse hyperbolic cosine of ARG. */)
555 register Lisp_Object arg
;
557 double d
= extract_float (arg
);
558 #ifdef FLOAT_CHECK_DOMAIN
560 domain_error ("acosh", arg
);
562 #ifdef HAVE_INVERSE_HYPERBOLIC
563 IN_FLOAT (d
= acosh (d
), "acosh", arg
);
565 IN_FLOAT (d
= log (d
+ sqrt (d
*d
- 1.0)), "acosh", arg
);
567 return make_float (d
);
570 DEFUN ("asinh", Fasinh
, Sasinh
, 1, 1, 0,
571 doc
: /* Return the inverse hyperbolic sine of ARG. */)
573 register Lisp_Object arg
;
575 double d
= extract_float (arg
);
576 #ifdef HAVE_INVERSE_HYPERBOLIC
577 IN_FLOAT (d
= asinh (d
), "asinh", arg
);
579 IN_FLOAT (d
= log (d
+ sqrt (d
*d
+ 1.0)), "asinh", arg
);
581 return make_float (d
);
584 DEFUN ("atanh", Fatanh
, Satanh
, 1, 1, 0,
585 doc
: /* Return the inverse hyperbolic tangent of ARG. */)
587 register Lisp_Object arg
;
589 double d
= extract_float (arg
);
590 #ifdef FLOAT_CHECK_DOMAIN
591 if (d
>= 1.0 || d
<= -1.0)
592 domain_error ("atanh", arg
);
594 #ifdef HAVE_INVERSE_HYPERBOLIC
595 IN_FLOAT (d
= atanh (d
), "atanh", arg
);
597 IN_FLOAT (d
= 0.5 * log ((1.0 + d
) / (1.0 - d
)), "atanh", arg
);
599 return make_float (d
);
602 DEFUN ("cosh", Fcosh
, Scosh
, 1, 1, 0,
603 doc
: /* Return the hyperbolic cosine of ARG. */)
605 register Lisp_Object arg
;
607 double d
= extract_float (arg
);
608 #ifdef FLOAT_CHECK_DOMAIN
609 if (d
> 710.0 || d
< -710.0)
610 range_error ("cosh", arg
);
612 IN_FLOAT (d
= cosh (d
), "cosh", arg
);
613 return make_float (d
);
616 DEFUN ("sinh", Fsinh
, Ssinh
, 1, 1, 0,
617 doc
: /* Return the hyperbolic sine of ARG. */)
619 register Lisp_Object arg
;
621 double d
= extract_float (arg
);
622 #ifdef FLOAT_CHECK_DOMAIN
623 if (d
> 710.0 || d
< -710.0)
624 range_error ("sinh", arg
);
626 IN_FLOAT (d
= sinh (d
), "sinh", arg
);
627 return make_float (d
);
630 DEFUN ("tanh", Ftanh
, Stanh
, 1, 1, 0,
631 doc
: /* Return the hyperbolic tangent of ARG. */)
633 register Lisp_Object arg
;
635 double d
= extract_float (arg
);
636 IN_FLOAT (d
= tanh (d
), "tanh", arg
);
637 return make_float (d
);
641 DEFUN ("abs", Fabs
, Sabs
, 1, 1, 0,
642 doc
: /* Return the absolute value of ARG. */)
644 register Lisp_Object arg
;
646 CHECK_NUMBER_OR_FLOAT (arg
);
649 IN_FLOAT (arg
= make_float (fabs (XFLOAT_DATA (arg
))), "abs", arg
);
650 else if (XINT (arg
) < 0)
651 XSETINT (arg
, - XINT (arg
));
656 DEFUN ("float", Ffloat
, Sfloat
, 1, 1, 0,
657 doc
: /* Return the floating point number equal to ARG. */)
659 register Lisp_Object arg
;
661 CHECK_NUMBER_OR_FLOAT (arg
);
664 return make_float ((double) XINT (arg
));
665 else /* give 'em the same float back */
669 DEFUN ("logb", Flogb
, Slogb
, 1, 1, 0,
670 doc
: /* Returns largest integer <= the base 2 log of the magnitude of ARG.
671 This is the same as the exponent of a float. */)
677 double f
= extract_float (arg
);
680 value
= MOST_NEGATIVE_FIXNUM
;
684 IN_FLOAT (value
= logb (f
), "logb", arg
);
688 IN_FLOAT (frexp (f
, &ivalue
), "logb", arg
);
698 for (i
= 1, d
= 0.5; d
* d
>= f
; i
+= i
)
705 for (i
= 1, d
= 2.0; d
* d
<= f
; i
+= i
)
713 XSETINT (val
, value
);
718 /* the rounding functions */
721 rounding_driver (arg
, divisor
, double_round
, int_round2
, name
)
722 register Lisp_Object arg
, divisor
;
723 double (*double_round
) ();
724 EMACS_INT (*int_round2
) ();
727 CHECK_NUMBER_OR_FLOAT (arg
);
729 if (! NILP (divisor
))
733 CHECK_NUMBER_OR_FLOAT (divisor
);
735 if (FLOATP (arg
) || FLOATP (divisor
))
739 f1
= FLOATP (arg
) ? XFLOAT_DATA (arg
) : XINT (arg
);
740 f2
= (FLOATP (divisor
) ? XFLOAT_DATA (divisor
) : XINT (divisor
));
741 if (! IEEE_FLOATING_POINT
&& f2
== 0)
742 xsignal0 (Qarith_error
);
744 IN_FLOAT2 (f1
= (*double_round
) (f1
/ f2
), name
, arg
, divisor
);
745 FLOAT_TO_INT2 (f1
, arg
, name
, arg
, divisor
);
753 xsignal0 (Qarith_error
);
755 XSETINT (arg
, (*int_round2
) (i1
, i2
));
763 IN_FLOAT (d
= (*double_round
) (XFLOAT_DATA (arg
)), name
, arg
);
764 FLOAT_TO_INT (d
, arg
, name
, arg
);
770 /* With C's /, the result is implementation-defined if either operand
771 is negative, so take care with negative operands in the following
772 integer functions. */
779 ? (i1
< 0 ? ((-1 - i1
) / -i2
) + 1 : - (i1
/ -i2
))
780 : (i1
<= 0 ? - (-i1
/ i2
) : ((i1
- 1) / i2
) + 1));
788 ? (i1
<= 0 ? -i1
/ -i2
: -1 - ((i1
- 1) / -i2
))
789 : (i1
< 0 ? -1 - ((-1 - i1
) / i2
) : i1
/ i2
));
797 ? (i1
< 0 ? -i1
/ -i2
: - (i1
/ -i2
))
798 : (i1
< 0 ? - (-i1
/ i2
) : i1
/ i2
));
805 /* The C language's division operator gives us one remainder R, but
806 we want the remainder R1 on the other side of 0 if R1 is closer
807 to 0 than R is; because we want to round to even, we also want R1
808 if R and R1 are the same distance from 0 and if C's quotient is
810 EMACS_INT q
= i1
/ i2
;
811 EMACS_INT r
= i1
% i2
;
812 EMACS_INT abs_r
= r
< 0 ? -r
: r
;
813 EMACS_INT abs_r1
= (i2
< 0 ? -i2
: i2
) - abs_r
;
814 return q
+ (abs_r
+ (q
& 1) <= abs_r1
? 0 : (i2
^ r
) < 0 ? -1 : 1);
817 /* The code uses emacs_rint, so that it works to undefine HAVE_RINT
818 if `rint' exists but does not work right. */
820 #define emacs_rint rint
826 return floor (d
+ 0.5);
837 DEFUN ("ceiling", Fceiling
, Sceiling
, 1, 2, 0,
838 doc
: /* Return the smallest integer no less than ARG.
839 This rounds the value towards +inf.
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 doc
: /* Return the largest integer no greater than ARG.
849 This rounds the value towards -inf.
850 With optional DIVISOR, return the largest integer no greater than ARG/DIVISOR. */)
852 Lisp_Object arg
, divisor
;
854 return rounding_driver (arg
, divisor
, floor
, floor2
, "floor");
857 DEFUN ("round", Fround
, Sround
, 1, 2, 0,
858 doc
: /* Return the nearest integer to ARG.
859 With optional DIVISOR, return the nearest integer to ARG/DIVISOR.
861 Rounding a value equidistant between two integers may choose the
862 integer closer to zero, or it may prefer an even integer, depending on
863 your machine. For example, \(round 2.5\) can return 3 on some
864 systems, but 2 on others. */)
866 Lisp_Object arg
, divisor
;
868 return rounding_driver (arg
, divisor
, emacs_rint
, round2
, "round");
871 DEFUN ("truncate", Ftruncate
, Struncate
, 1, 2, 0,
872 doc
: /* Truncate a floating point number to an int.
873 Rounds ARG toward zero.
874 With optional DIVISOR, truncate ARG/DIVISOR. */)
876 Lisp_Object arg
, divisor
;
878 return rounding_driver (arg
, divisor
, double_identity
, truncate2
,
885 register Lisp_Object x
, y
;
889 f1
= FLOATP (x
) ? XFLOAT_DATA (x
) : XINT (x
);
890 f2
= FLOATP (y
) ? XFLOAT_DATA (y
) : XINT (y
);
892 if (! IEEE_FLOATING_POINT
&& f2
== 0)
893 xsignal0 (Qarith_error
);
895 /* If the "remainder" comes out with the wrong sign, fix it. */
896 IN_FLOAT2 ((f1
= fmod (f1
, f2
),
897 f1
= (f2
< 0 ? f1
> 0 : f1
< 0) ? f1
+ f2
: f1
),
899 return make_float (f1
);
902 /* It's not clear these are worth adding. */
904 DEFUN ("fceiling", Ffceiling
, Sfceiling
, 1, 1, 0,
905 doc
: /* Return the smallest integer no less than ARG, as a float.
906 \(Round toward +inf.\) */)
908 register Lisp_Object arg
;
910 double d
= extract_float (arg
);
911 IN_FLOAT (d
= ceil (d
), "fceiling", arg
);
912 return make_float (d
);
915 DEFUN ("ffloor", Fffloor
, Sffloor
, 1, 1, 0,
916 doc
: /* Return the largest integer no greater than ARG, as a float.
917 \(Round towards -inf.\) */)
919 register Lisp_Object arg
;
921 double d
= extract_float (arg
);
922 IN_FLOAT (d
= floor (d
), "ffloor", arg
);
923 return make_float (d
);
926 DEFUN ("fround", Ffround
, Sfround
, 1, 1, 0,
927 doc
: /* Return the nearest integer to ARG, as a float. */)
929 register Lisp_Object arg
;
931 double d
= extract_float (arg
);
932 IN_FLOAT (d
= emacs_rint (d
), "fround", arg
);
933 return make_float (d
);
936 DEFUN ("ftruncate", Fftruncate
, Sftruncate
, 1, 1, 0,
937 doc
: /* Truncate a floating point number to an integral float value.
938 Rounds the value toward zero. */)
940 register Lisp_Object arg
;
942 double d
= extract_float (arg
);
944 IN_FLOAT (d
= floor (d
), "ftruncate", arg
);
946 IN_FLOAT (d
= ceil (d
), "ftruncate", arg
);
947 return make_float (d
);
950 #ifdef FLOAT_CATCH_SIGILL
956 fatal_error_signal (signo
);
959 sigsetmask (SIGEMPTYMASK
);
961 /* Must reestablish handler each time it is called. */
962 signal (SIGILL
, float_error
);
963 #endif /* BSD_SYSTEM */
965 SIGNAL_THREAD_CHECK (signo
);
968 xsignal1 (Qarith_error
, float_error_arg
);
971 /* Another idea was to replace the library function `infnan'
972 where SIGILL is signaled. */
974 #endif /* FLOAT_CATCH_SIGILL */
983 /* Not called from emacs-lisp float routines; do the default thing. */
985 if (!strcmp (x
->name
, "pow"))
989 = Fcons (build_string (x
->name
),
990 Fcons (make_float (x
->arg1
),
991 ((!strcmp (x
->name
, "log") || !strcmp (x
->name
, "pow"))
992 ? Fcons (make_float (x
->arg2
), Qnil
)
996 case DOMAIN
: xsignal (Qdomain_error
, args
); break;
997 case SING
: xsignal (Qsingularity_error
, args
); break;
998 case OVERFLOW
: xsignal (Qoverflow_error
, args
); break;
999 case UNDERFLOW
: xsignal (Qunderflow_error
, args
); break;
1000 default: xsignal (Qarith_error
, args
); break;
1002 return (1); /* don't set errno or print a message */
1004 #endif /* HAVE_MATHERR */
1009 #ifdef FLOAT_CATCH_SIGILL
1010 signal (SIGILL
, float_error
);
1031 defsubr (&Sbessel_y0
);
1032 defsubr (&Sbessel_y1
);
1033 defsubr (&Sbessel_yn
);
1034 defsubr (&Sbessel_j0
);
1035 defsubr (&Sbessel_j1
);
1036 defsubr (&Sbessel_jn
);
1039 defsubr (&Slog_gamma
);
1040 defsubr (&Scube_root
);
1042 defsubr (&Sfceiling
);
1045 defsubr (&Sftruncate
);
1055 defsubr (&Sceiling
);
1058 defsubr (&Struncate
);
1061 /* arch-tag: be05bf9d-049e-4e31-91b9-e6153d483ae7
1062 (do not change this comment) */