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 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.)
52 #include "syssignal.h"
58 /* If IEEE_FLOATING_POINT isn't defined, default it from FLT_*. */
59 #ifndef IEEE_FLOATING_POINT
60 #if (FLT_RADIX == 2 && FLT_MANT_DIG == 24 \
61 && FLT_MIN_EXP == -125 && FLT_MAX_EXP == 128)
62 #define IEEE_FLOATING_POINT 1
64 #define IEEE_FLOATING_POINT 0
70 /* This declaration is omitted on some systems, like Ultrix. */
71 #if !defined (HPUX) && defined (HAVE_LOGB) && !defined (logb)
72 extern double logb ();
73 #endif /* not HPUX and HAVE_LOGB and no logb macro */
75 #if defined(DOMAIN) && defined(SING) && defined(OVERFLOW)
76 /* If those are defined, then this is probably a `matherr' machine. */
87 # ifdef FLOAT_CHECK_ERRNO
88 # undef FLOAT_CHECK_ERRNO
90 # ifdef FLOAT_CHECK_DOMAIN
91 # undef FLOAT_CHECK_DOMAIN
95 #ifndef NO_FLOAT_CHECK_ERRNO
96 #define FLOAT_CHECK_ERRNO
99 #ifdef FLOAT_CHECK_ERRNO
107 #ifdef FLOAT_CATCH_SIGILL
108 static SIGTYPE
float_error ();
111 /* Nonzero while executing in floating point.
112 This tells float_error what to do. */
116 /* If an argument is out of range for a mathematical function,
117 here is the actual argument value to use in the error message.
118 These variables are used only across the floating point library call
119 so there is no need to staticpro them. */
121 static Lisp_Object float_error_arg
, float_error_arg2
;
123 static char *float_error_fn_name
;
125 /* Evaluate the floating point expression D, recording NUM
126 as the original argument for error messages.
127 D is normally an assignment expression.
128 Handle errors which may result in signals or may set errno.
130 Note that float_error may be declared to return void, so you can't
131 just cast the zero after the colon to (SIGTYPE) to make the types
134 #ifdef FLOAT_CHECK_ERRNO
135 #define IN_FLOAT(d, name, num) \
137 float_error_arg = num; \
138 float_error_fn_name = name; \
139 in_float = 1; errno = 0; (d); in_float = 0; \
142 case EDOM: domain_error (float_error_fn_name, float_error_arg); \
143 case ERANGE: range_error (float_error_fn_name, float_error_arg); \
144 default: arith_error (float_error_fn_name, float_error_arg); \
147 #define IN_FLOAT2(d, name, num, num2) \
149 float_error_arg = num; \
150 float_error_arg2 = num2; \
151 float_error_fn_name = name; \
152 in_float = 1; errno = 0; (d); in_float = 0; \
155 case EDOM: domain_error (float_error_fn_name, float_error_arg); \
156 case ERANGE: range_error (float_error_fn_name, float_error_arg); \
157 default: arith_error (float_error_fn_name, float_error_arg); \
161 #define IN_FLOAT(d, name, num) (in_float = 1, (d), in_float = 0)
162 #define IN_FLOAT2(d, name, num, num2) (in_float = 1, (d), in_float = 0)
165 /* Convert float to Lisp_Int if it fits, else signal a range error
166 using the given arguments. */
167 #define FLOAT_TO_INT(x, i, name, num) \
170 if (FIXNUM_OVERFLOW_P (x)) \
171 range_error (name, num); \
172 XSETINT (i, (EMACS_INT)(x)); \
175 #define FLOAT_TO_INT2(x, i, name, num1, num2) \
178 if (FIXNUM_OVERFLOW_P (x)) \
179 range_error2 (name, num1, num2); \
180 XSETINT (i, (EMACS_INT)(x)); \
184 #define arith_error(op,arg) \
185 xsignal2 (Qarith_error, build_string ((op)), (arg))
186 #define range_error(op,arg) \
187 xsignal2 (Qrange_error, build_string ((op)), (arg))
188 #define range_error2(op,a1,a2) \
189 xsignal3 (Qrange_error, build_string ((op)), (a1), (a2))
190 #define domain_error(op,arg) \
191 xsignal2 (Qdomain_error, build_string ((op)), (arg))
192 #define domain_error2(op,a1,a2) \
193 xsignal3 (Qdomain_error, build_string ((op)), (a1), (a2))
195 /* Extract a Lisp number as a `double', or signal an error. */
201 CHECK_NUMBER_OR_FLOAT (num
);
204 return XFLOAT_DATA (num
);
205 return (double) XINT (num
);
208 /* Trig functions. */
210 DEFUN ("acos", Facos
, Sacos
, 1, 1, 0,
211 doc
: /* Return the inverse cosine of ARG. */)
213 register Lisp_Object arg
;
215 double d
= extract_float (arg
);
216 #ifdef FLOAT_CHECK_DOMAIN
217 if (d
> 1.0 || d
< -1.0)
218 domain_error ("acos", arg
);
220 IN_FLOAT (d
= acos (d
), "acos", arg
);
221 return make_float (d
);
224 DEFUN ("asin", Fasin
, Sasin
, 1, 1, 0,
225 doc
: /* Return the inverse sine of ARG. */)
227 register Lisp_Object arg
;
229 double d
= extract_float (arg
);
230 #ifdef FLOAT_CHECK_DOMAIN
231 if (d
> 1.0 || d
< -1.0)
232 domain_error ("asin", arg
);
234 IN_FLOAT (d
= asin (d
), "asin", arg
);
235 return make_float (d
);
238 DEFUN ("atan", Fatan
, Satan
, 1, 2, 0,
239 doc
: /* Return the inverse tangent of the arguments.
240 If only one argument Y is given, return the inverse tangent of Y.
241 If two arguments Y and X are given, return the inverse tangent of Y
242 divided by X, i.e. the angle in radians between the vector (X, Y)
245 register Lisp_Object y
, x
;
247 double d
= extract_float (y
);
250 IN_FLOAT (d
= atan (d
), "atan", y
);
253 double d2
= extract_float (x
);
255 IN_FLOAT2 (d
= atan2 (d
, d2
), "atan", y
, x
);
257 return make_float (d
);
260 DEFUN ("cos", Fcos
, Scos
, 1, 1, 0,
261 doc
: /* Return the cosine of ARG. */)
263 register Lisp_Object arg
;
265 double d
= extract_float (arg
);
266 IN_FLOAT (d
= cos (d
), "cos", arg
);
267 return make_float (d
);
270 DEFUN ("sin", Fsin
, Ssin
, 1, 1, 0,
271 doc
: /* Return the sine of ARG. */)
273 register Lisp_Object arg
;
275 double d
= extract_float (arg
);
276 IN_FLOAT (d
= sin (d
), "sin", arg
);
277 return make_float (d
);
280 DEFUN ("tan", Ftan
, Stan
, 1, 1, 0,
281 doc
: /* Return the tangent of ARG. */)
283 register Lisp_Object arg
;
285 double d
= extract_float (arg
);
287 #ifdef FLOAT_CHECK_DOMAIN
289 domain_error ("tan", arg
);
291 IN_FLOAT (d
= sin (d
) / c
, "tan", arg
);
292 return make_float (d
);
295 #if 0 /* Leave these out unless we find there's a reason for them. */
297 DEFUN ("bessel-j0", Fbessel_j0
, Sbessel_j0
, 1, 1, 0,
298 doc
: /* Return the bessel function j0 of ARG. */)
300 register Lisp_Object arg
;
302 double d
= extract_float (arg
);
303 IN_FLOAT (d
= j0 (d
), "bessel-j0", arg
);
304 return make_float (d
);
307 DEFUN ("bessel-j1", Fbessel_j1
, Sbessel_j1
, 1, 1, 0,
308 doc
: /* Return the bessel function j1 of ARG. */)
310 register Lisp_Object arg
;
312 double d
= extract_float (arg
);
313 IN_FLOAT (d
= j1 (d
), "bessel-j1", arg
);
314 return make_float (d
);
317 DEFUN ("bessel-jn", Fbessel_jn
, Sbessel_jn
, 2, 2, 0,
318 doc
: /* Return the order N bessel function output jn of ARG.
319 The first arg (the order) is truncated to an integer. */)
321 register Lisp_Object n
, arg
;
323 int i1
= extract_float (n
);
324 double f2
= extract_float (arg
);
326 IN_FLOAT (f2
= jn (i1
, f2
), "bessel-jn", n
);
327 return make_float (f2
);
330 DEFUN ("bessel-y0", Fbessel_y0
, Sbessel_y0
, 1, 1, 0,
331 doc
: /* Return the bessel function y0 of ARG. */)
333 register Lisp_Object arg
;
335 double d
= extract_float (arg
);
336 IN_FLOAT (d
= y0 (d
), "bessel-y0", arg
);
337 return make_float (d
);
340 DEFUN ("bessel-y1", Fbessel_y1
, Sbessel_y1
, 1, 1, 0,
341 doc
: /* Return the bessel function y1 of ARG. */)
343 register Lisp_Object arg
;
345 double d
= extract_float (arg
);
346 IN_FLOAT (d
= y1 (d
), "bessel-y0", arg
);
347 return make_float (d
);
350 DEFUN ("bessel-yn", Fbessel_yn
, Sbessel_yn
, 2, 2, 0,
351 doc
: /* Return the order N bessel function output yn of ARG.
352 The first arg (the order) is truncated to an integer. */)
354 register Lisp_Object n
, arg
;
356 int i1
= extract_float (n
);
357 double f2
= extract_float (arg
);
359 IN_FLOAT (f2
= yn (i1
, f2
), "bessel-yn", n
);
360 return make_float (f2
);
365 #if 0 /* Leave these out unless we see they are worth having. */
367 DEFUN ("erf", Ferf
, Serf
, 1, 1, 0,
368 doc
: /* Return the mathematical error function of ARG. */)
370 register Lisp_Object arg
;
372 double d
= extract_float (arg
);
373 IN_FLOAT (d
= erf (d
), "erf", arg
);
374 return make_float (d
);
377 DEFUN ("erfc", Ferfc
, Serfc
, 1, 1, 0,
378 doc
: /* Return the complementary error function of ARG. */)
380 register Lisp_Object arg
;
382 double d
= extract_float (arg
);
383 IN_FLOAT (d
= erfc (d
), "erfc", arg
);
384 return make_float (d
);
387 DEFUN ("log-gamma", Flog_gamma
, Slog_gamma
, 1, 1, 0,
388 doc
: /* Return the log gamma of ARG. */)
390 register Lisp_Object arg
;
392 double d
= extract_float (arg
);
393 IN_FLOAT (d
= lgamma (d
), "log-gamma", arg
);
394 return make_float (d
);
397 DEFUN ("cube-root", Fcube_root
, Scube_root
, 1, 1, 0,
398 doc
: /* Return the cube root of ARG. */)
400 register Lisp_Object arg
;
402 double d
= extract_float (arg
);
404 IN_FLOAT (d
= cbrt (d
), "cube-root", arg
);
407 IN_FLOAT (d
= pow (d
, 1.0/3.0), "cube-root", arg
);
409 IN_FLOAT (d
= -pow (-d
, 1.0/3.0), "cube-root", arg
);
411 return make_float (d
);
416 DEFUN ("exp", Fexp
, Sexp
, 1, 1, 0,
417 doc
: /* Return the exponential base e of ARG. */)
419 register Lisp_Object arg
;
421 double d
= extract_float (arg
);
422 #ifdef FLOAT_CHECK_DOMAIN
423 if (d
> 709.7827) /* Assume IEEE doubles here */
424 range_error ("exp", arg
);
426 return make_float (0.0);
429 IN_FLOAT (d
= exp (d
), "exp", arg
);
430 return make_float (d
);
433 DEFUN ("expt", Fexpt
, Sexpt
, 2, 2, 0,
434 doc
: /* Return the exponential ARG1 ** ARG2. */)
436 register Lisp_Object arg1
, arg2
;
440 CHECK_NUMBER_OR_FLOAT (arg1
);
441 CHECK_NUMBER_OR_FLOAT (arg2
);
442 if (INTEGERP (arg1
) /* common lisp spec */
443 && INTEGERP (arg2
) /* don't promote, if both are ints, and */
444 && 0 <= XINT (arg2
)) /* we are sure the result is not fractional */
445 { /* this can be improved by pre-calculating */
446 EMACS_INT acc
, x
, y
; /* some binary powers of x then accumulating */
458 acc
= (y
& 1) ? -1 : 1;
469 y
= (unsigned)y
>> 1;
475 f1
= FLOATP (arg1
) ? XFLOAT_DATA (arg1
) : XINT (arg1
);
476 f2
= FLOATP (arg2
) ? XFLOAT_DATA (arg2
) : XINT (arg2
);
477 /* Really should check for overflow, too */
478 if (f1
== 0.0 && f2
== 0.0)
480 #ifdef FLOAT_CHECK_DOMAIN
481 else if ((f1
== 0.0 && f2
< 0.0) || (f1
< 0 && f2
!= floor(f2
)))
482 domain_error2 ("expt", arg1
, arg2
);
484 IN_FLOAT2 (f3
= pow (f1
, f2
), "expt", arg1
, arg2
);
485 /* Check for overflow in the result. */
486 if (f1
!= 0.0 && f3
== 0.0)
487 range_error ("expt", arg1
);
488 return make_float (f3
);
491 DEFUN ("log", Flog
, Slog
, 1, 2, 0,
492 doc
: /* Return the natural logarithm of ARG.
493 If the optional argument BASE is given, return log ARG using that base. */)
495 register Lisp_Object arg
, base
;
497 double d
= extract_float (arg
);
499 #ifdef FLOAT_CHECK_DOMAIN
501 domain_error2 ("log", arg
, base
);
504 IN_FLOAT (d
= log (d
), "log", arg
);
507 double b
= extract_float (base
);
509 #ifdef FLOAT_CHECK_DOMAIN
510 if (b
<= 0.0 || b
== 1.0)
511 domain_error2 ("log", arg
, base
);
514 IN_FLOAT2 (d
= log10 (d
), "log", arg
, base
);
516 IN_FLOAT2 (d
= log (d
) / log (b
), "log", arg
, base
);
518 return make_float (d
);
521 DEFUN ("log10", Flog10
, Slog10
, 1, 1, 0,
522 doc
: /* Return the logarithm base 10 of ARG. */)
524 register Lisp_Object arg
;
526 double d
= extract_float (arg
);
527 #ifdef FLOAT_CHECK_DOMAIN
529 domain_error ("log10", arg
);
531 IN_FLOAT (d
= log10 (d
), "log10", arg
);
532 return make_float (d
);
535 DEFUN ("sqrt", Fsqrt
, Ssqrt
, 1, 1, 0,
536 doc
: /* Return the square root of ARG. */)
538 register Lisp_Object arg
;
540 double d
= extract_float (arg
);
541 #ifdef FLOAT_CHECK_DOMAIN
543 domain_error ("sqrt", arg
);
545 IN_FLOAT (d
= sqrt (d
), "sqrt", arg
);
546 return make_float (d
);
549 #if 0 /* Not clearly worth adding. */
551 DEFUN ("acosh", Facosh
, Sacosh
, 1, 1, 0,
552 doc
: /* Return the inverse hyperbolic cosine of ARG. */)
554 register Lisp_Object arg
;
556 double d
= extract_float (arg
);
557 #ifdef FLOAT_CHECK_DOMAIN
559 domain_error ("acosh", arg
);
561 #ifdef HAVE_INVERSE_HYPERBOLIC
562 IN_FLOAT (d
= acosh (d
), "acosh", arg
);
564 IN_FLOAT (d
= log (d
+ sqrt (d
*d
- 1.0)), "acosh", arg
);
566 return make_float (d
);
569 DEFUN ("asinh", Fasinh
, Sasinh
, 1, 1, 0,
570 doc
: /* Return the inverse hyperbolic sine of ARG. */)
572 register Lisp_Object arg
;
574 double d
= extract_float (arg
);
575 #ifdef HAVE_INVERSE_HYPERBOLIC
576 IN_FLOAT (d
= asinh (d
), "asinh", arg
);
578 IN_FLOAT (d
= log (d
+ sqrt (d
*d
+ 1.0)), "asinh", arg
);
580 return make_float (d
);
583 DEFUN ("atanh", Fatanh
, Satanh
, 1, 1, 0,
584 doc
: /* Return the inverse hyperbolic tangent of ARG. */)
586 register Lisp_Object arg
;
588 double d
= extract_float (arg
);
589 #ifdef FLOAT_CHECK_DOMAIN
590 if (d
>= 1.0 || d
<= -1.0)
591 domain_error ("atanh", arg
);
593 #ifdef HAVE_INVERSE_HYPERBOLIC
594 IN_FLOAT (d
= atanh (d
), "atanh", arg
);
596 IN_FLOAT (d
= 0.5 * log ((1.0 + d
) / (1.0 - d
)), "atanh", arg
);
598 return make_float (d
);
601 DEFUN ("cosh", Fcosh
, Scosh
, 1, 1, 0,
602 doc
: /* Return the hyperbolic cosine of ARG. */)
604 register Lisp_Object arg
;
606 double d
= extract_float (arg
);
607 #ifdef FLOAT_CHECK_DOMAIN
608 if (d
> 710.0 || d
< -710.0)
609 range_error ("cosh", arg
);
611 IN_FLOAT (d
= cosh (d
), "cosh", arg
);
612 return make_float (d
);
615 DEFUN ("sinh", Fsinh
, Ssinh
, 1, 1, 0,
616 doc
: /* Return the hyperbolic sine of ARG. */)
618 register Lisp_Object arg
;
620 double d
= extract_float (arg
);
621 #ifdef FLOAT_CHECK_DOMAIN
622 if (d
> 710.0 || d
< -710.0)
623 range_error ("sinh", arg
);
625 IN_FLOAT (d
= sinh (d
), "sinh", arg
);
626 return make_float (d
);
629 DEFUN ("tanh", Ftanh
, Stanh
, 1, 1, 0,
630 doc
: /* Return the hyperbolic tangent of ARG. */)
632 register Lisp_Object arg
;
634 double d
= extract_float (arg
);
635 IN_FLOAT (d
= tanh (d
), "tanh", arg
);
636 return make_float (d
);
640 DEFUN ("abs", Fabs
, Sabs
, 1, 1, 0,
641 doc
: /* Return the absolute value of ARG. */)
643 register Lisp_Object arg
;
645 CHECK_NUMBER_OR_FLOAT (arg
);
648 IN_FLOAT (arg
= make_float (fabs (XFLOAT_DATA (arg
))), "abs", arg
);
649 else if (XINT (arg
) < 0)
650 XSETINT (arg
, - XINT (arg
));
655 DEFUN ("float", Ffloat
, Sfloat
, 1, 1, 0,
656 doc
: /* Return the floating point number equal to ARG. */)
658 register Lisp_Object arg
;
660 CHECK_NUMBER_OR_FLOAT (arg
);
663 return make_float ((double) XINT (arg
));
664 else /* give 'em the same float back */
668 DEFUN ("logb", Flogb
, Slogb
, 1, 1, 0,
669 doc
: /* Returns largest integer <= the base 2 log of the magnitude of ARG.
670 This is the same as the exponent of a float. */)
676 double f
= extract_float (arg
);
679 value
= MOST_NEGATIVE_FIXNUM
;
683 IN_FLOAT (value
= logb (f
), "logb", arg
);
687 IN_FLOAT (frexp (f
, &ivalue
), "logb", arg
);
697 for (i
= 1, d
= 0.5; d
* d
>= f
; i
+= i
)
704 for (i
= 1, d
= 2.0; d
* d
<= f
; i
+= i
)
712 XSETINT (val
, value
);
717 /* the rounding functions */
720 rounding_driver (arg
, divisor
, double_round
, int_round2
, name
)
721 register Lisp_Object arg
, divisor
;
722 double (*double_round
) ();
723 EMACS_INT (*int_round2
) ();
726 CHECK_NUMBER_OR_FLOAT (arg
);
728 if (! NILP (divisor
))
732 CHECK_NUMBER_OR_FLOAT (divisor
);
734 if (FLOATP (arg
) || FLOATP (divisor
))
738 f1
= FLOATP (arg
) ? XFLOAT_DATA (arg
) : XINT (arg
);
739 f2
= (FLOATP (divisor
) ? XFLOAT_DATA (divisor
) : XINT (divisor
));
740 if (! IEEE_FLOATING_POINT
&& f2
== 0)
741 xsignal0 (Qarith_error
);
743 IN_FLOAT2 (f1
= (*double_round
) (f1
/ f2
), name
, arg
, divisor
);
744 FLOAT_TO_INT2 (f1
, arg
, name
, arg
, divisor
);
752 xsignal0 (Qarith_error
);
754 XSETINT (arg
, (*int_round2
) (i1
, i2
));
762 IN_FLOAT (d
= (*double_round
) (XFLOAT_DATA (arg
)), name
, arg
);
763 FLOAT_TO_INT (d
, arg
, name
, arg
);
769 /* With C's /, the result is implementation-defined if either operand
770 is negative, so take care with negative operands in the following
771 integer functions. */
778 ? (i1
< 0 ? ((-1 - i1
) / -i2
) + 1 : - (i1
/ -i2
))
779 : (i1
<= 0 ? - (-i1
/ i2
) : ((i1
- 1) / i2
) + 1));
787 ? (i1
<= 0 ? -i1
/ -i2
: -1 - ((i1
- 1) / -i2
))
788 : (i1
< 0 ? -1 - ((-1 - i1
) / i2
) : i1
/ i2
));
796 ? (i1
< 0 ? -i1
/ -i2
: - (i1
/ -i2
))
797 : (i1
< 0 ? - (-i1
/ i2
) : i1
/ i2
));
804 /* The C language's division operator gives us one remainder R, but
805 we want the remainder R1 on the other side of 0 if R1 is closer
806 to 0 than R is; because we want to round to even, we also want R1
807 if R and R1 are the same distance from 0 and if C's quotient is
809 EMACS_INT q
= i1
/ i2
;
810 EMACS_INT r
= i1
% i2
;
811 EMACS_INT abs_r
= r
< 0 ? -r
: r
;
812 EMACS_INT abs_r1
= (i2
< 0 ? -i2
: i2
) - abs_r
;
813 return q
+ (abs_r
+ (q
& 1) <= abs_r1
? 0 : (i2
^ r
) < 0 ? -1 : 1);
816 /* The code uses emacs_rint, so that it works to undefine HAVE_RINT
817 if `rint' exists but does not work right. */
819 #define emacs_rint rint
825 return floor (d
+ 0.5);
836 DEFUN ("ceiling", Fceiling
, Sceiling
, 1, 2, 0,
837 doc
: /* Return the smallest integer no less than ARG.
838 This rounds the value towards +inf.
839 With optional DIVISOR, return the smallest integer no less than ARG/DIVISOR. */)
841 Lisp_Object arg
, divisor
;
843 return rounding_driver (arg
, divisor
, ceil
, ceiling2
, "ceiling");
846 DEFUN ("floor", Ffloor
, Sfloor
, 1, 2, 0,
847 doc
: /* Return the largest integer no greater than ARG.
848 This rounds the value towards -inf.
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 doc
: /* Return the nearest integer to ARG.
858 With optional DIVISOR, return the nearest integer to ARG/DIVISOR.
860 Rounding a value equidistant between two integers may choose the
861 integer closer to zero, or it may prefer an even integer, depending on
862 your machine. For example, \(round 2.5\) can return 3 on some
863 systems, but 2 on others. */)
865 Lisp_Object arg
, divisor
;
867 return rounding_driver (arg
, divisor
, emacs_rint
, round2
, "round");
870 DEFUN ("truncate", Ftruncate
, Struncate
, 1, 2, 0,
871 doc
: /* Truncate a floating point number to an int.
872 Rounds ARG toward zero.
873 With optional DIVISOR, truncate ARG/DIVISOR. */)
875 Lisp_Object arg
, divisor
;
877 return rounding_driver (arg
, divisor
, double_identity
, truncate2
,
884 register Lisp_Object x
, y
;
888 f1
= FLOATP (x
) ? XFLOAT_DATA (x
) : XINT (x
);
889 f2
= FLOATP (y
) ? XFLOAT_DATA (y
) : XINT (y
);
891 if (! IEEE_FLOATING_POINT
&& f2
== 0)
892 xsignal0 (Qarith_error
);
894 /* If the "remainder" comes out with the wrong sign, fix it. */
895 IN_FLOAT2 ((f1
= fmod (f1
, f2
),
896 f1
= (f2
< 0 ? f1
> 0 : f1
< 0) ? f1
+ f2
: f1
),
898 return make_float (f1
);
901 /* It's not clear these are worth adding. */
903 DEFUN ("fceiling", Ffceiling
, Sfceiling
, 1, 1, 0,
904 doc
: /* Return the smallest integer no less than ARG, as a float.
905 \(Round toward +inf.\) */)
907 register Lisp_Object arg
;
909 double d
= extract_float (arg
);
910 IN_FLOAT (d
= ceil (d
), "fceiling", arg
);
911 return make_float (d
);
914 DEFUN ("ffloor", Fffloor
, Sffloor
, 1, 1, 0,
915 doc
: /* Return the largest integer no greater than ARG, as a float.
916 \(Round towards -inf.\) */)
918 register Lisp_Object arg
;
920 double d
= extract_float (arg
);
921 IN_FLOAT (d
= floor (d
), "ffloor", arg
);
922 return make_float (d
);
925 DEFUN ("fround", Ffround
, Sfround
, 1, 1, 0,
926 doc
: /* Return the nearest integer to ARG, as a float. */)
928 register Lisp_Object arg
;
930 double d
= extract_float (arg
);
931 IN_FLOAT (d
= emacs_rint (d
), "fround", arg
);
932 return make_float (d
);
935 DEFUN ("ftruncate", Fftruncate
, Sftruncate
, 1, 1, 0,
936 doc
: /* Truncate a floating point number to an integral float value.
937 Rounds the value toward zero. */)
939 register Lisp_Object arg
;
941 double d
= extract_float (arg
);
943 IN_FLOAT (d
= floor (d
), "ftruncate", arg
);
945 IN_FLOAT (d
= ceil (d
), "ftruncate", arg
);
946 return make_float (d
);
949 #ifdef FLOAT_CATCH_SIGILL
955 fatal_error_signal (signo
);
958 sigsetmask (SIGEMPTYMASK
);
960 /* Must reestablish handler each time it is called. */
961 signal (SIGILL
, float_error
);
962 #endif /* BSD_SYSTEM */
964 SIGNAL_THREAD_CHECK (signo
);
967 xsignal1 (Qarith_error
, float_error_arg
);
970 /* Another idea was to replace the library function `infnan'
971 where SIGILL is signaled. */
973 #endif /* FLOAT_CATCH_SIGILL */
982 /* Not called from emacs-lisp float routines; do the default thing. */
984 if (!strcmp (x
->name
, "pow"))
988 = Fcons (build_string (x
->name
),
989 Fcons (make_float (x
->arg1
),
990 ((!strcmp (x
->name
, "log") || !strcmp (x
->name
, "pow"))
991 ? Fcons (make_float (x
->arg2
), Qnil
)
995 case DOMAIN
: xsignal (Qdomain_error
, args
); break;
996 case SING
: xsignal (Qsingularity_error
, args
); break;
997 case OVERFLOW
: xsignal (Qoverflow_error
, args
); break;
998 case UNDERFLOW
: xsignal (Qunderflow_error
, args
); break;
999 default: xsignal (Qarith_error
, args
); break;
1001 return (1); /* don't set errno or print a message */
1003 #endif /* HAVE_MATHERR */
1008 #ifdef FLOAT_CATCH_SIGILL
1009 signal (SIGILL
, float_error
);
1030 defsubr (&Sbessel_y0
);
1031 defsubr (&Sbessel_y1
);
1032 defsubr (&Sbessel_yn
);
1033 defsubr (&Sbessel_j0
);
1034 defsubr (&Sbessel_j1
);
1035 defsubr (&Sbessel_jn
);
1038 defsubr (&Slog_gamma
);
1039 defsubr (&Scube_root
);
1041 defsubr (&Sfceiling
);
1044 defsubr (&Sftruncate
);
1054 defsubr (&Sceiling
);
1057 defsubr (&Struncate
);
1060 /* arch-tag: be05bf9d-049e-4e31-91b9-e6153d483ae7
1061 (do not change this comment) */