1 /* Primitive operations on floating point for GNU Emacs Lisp interpreter.
2 Copyright (C) 1988, 1993, 1994, 1999, 2002, 2003, 2004,
3 2005 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
23 /* ANSI C requires only these float functions:
24 acos, asin, atan, atan2, ceil, cos, cosh, exp, fabs, floor, fmod,
25 frexp, ldexp, log, log10, modf, pow, sin, sinh, sqrt, tan, tanh.
27 Define HAVE_INVERSE_HYPERBOLIC if you have acosh, asinh, and atanh.
28 Define HAVE_CBRT if you have cbrt.
29 Define HAVE_RINT if you have a working rint.
30 If you don't define these, then the appropriate routines will be simulated.
32 Define HAVE_MATHERR if on a system supporting the SysV matherr callback.
33 (This should happen automatically.)
35 Define FLOAT_CHECK_ERRNO if the float library routines set errno.
36 This has no effect if HAVE_MATHERR is defined.
38 Define FLOAT_CATCH_SIGILL if the float library routines signal SIGILL.
39 (What systems actually do this? Please let us know.)
41 Define FLOAT_CHECK_DOMAIN if the float library doesn't handle errors by
42 either setting errno, or signaling SIGFPE/SIGILL. Otherwise, domain and
43 range checking will happen before calling the float routines. This has
44 no effect if HAVE_MATHERR is defined (since matherr will be called when
45 a domain error occurs.)
51 #include "syssignal.h"
57 /* If IEEE_FLOATING_POINT isn't defined, default it from FLT_*. */
58 #ifndef IEEE_FLOATING_POINT
59 #if (FLT_RADIX == 2 && FLT_MANT_DIG == 24 \
60 && FLT_MIN_EXP == -125 && FLT_MAX_EXP == 128)
61 #define IEEE_FLOATING_POINT 1
63 #define IEEE_FLOATING_POINT 0
67 /* Work around a problem that happens because math.h on hpux 7
68 defines two static variables--which, in Emacs, are not really static,
69 because `static' is defined as nothing. The problem is that they are
70 defined both here and in lread.c.
71 These macros prevent the name conflict. */
72 #if defined (HPUX) && !defined (HPUX8)
73 #define _MAXLDBL floatfns_maxldbl
74 #define _NMAXLDBL floatfns_nmaxldbl
79 /* This declaration is omitted on some systems, like Ultrix. */
80 #if !defined (HPUX) && defined (HAVE_LOGB) && !defined (logb)
81 extern double logb ();
82 #endif /* not HPUX and HAVE_LOGB and no logb macro */
84 #if defined(DOMAIN) && defined(SING) && defined(OVERFLOW)
85 /* If those are defined, then this is probably a `matherr' machine. */
96 # ifdef FLOAT_CHECK_ERRNO
97 # undef FLOAT_CHECK_ERRNO
99 # ifdef FLOAT_CHECK_DOMAIN
100 # undef FLOAT_CHECK_DOMAIN
104 #ifndef NO_FLOAT_CHECK_ERRNO
105 #define FLOAT_CHECK_ERRNO
108 #ifdef FLOAT_CHECK_ERRNO
116 /* Avoid traps on VMS from sinh and cosh.
117 All the other functions set errno instead. */
122 #define cosh(x) ((exp(x)+exp(-x))*0.5)
123 #define sinh(x) ((exp(x)-exp(-x))*0.5)
126 #ifdef FLOAT_CATCH_SIGILL
127 static SIGTYPE
float_error ();
130 /* Nonzero while executing in floating point.
131 This tells float_error what to do. */
135 /* If an argument is out of range for a mathematical function,
136 here is the actual argument value to use in the error message.
137 These variables are used only across the floating point library call
138 so there is no need to staticpro them. */
140 static Lisp_Object float_error_arg
, float_error_arg2
;
142 static char *float_error_fn_name
;
144 /* Evaluate the floating point expression D, recording NUM
145 as the original argument for error messages.
146 D is normally an assignment expression.
147 Handle errors which may result in signals or may set errno.
149 Note that float_error may be declared to return void, so you can't
150 just cast the zero after the colon to (SIGTYPE) to make the types
153 #ifdef FLOAT_CHECK_ERRNO
154 #define IN_FLOAT(d, name, num) \
156 float_error_arg = num; \
157 float_error_fn_name = name; \
158 in_float = 1; errno = 0; (d); in_float = 0; \
161 case EDOM: domain_error (float_error_fn_name, float_error_arg); \
162 case ERANGE: range_error (float_error_fn_name, float_error_arg); \
163 default: arith_error (float_error_fn_name, float_error_arg); \
166 #define IN_FLOAT2(d, name, num, num2) \
168 float_error_arg = num; \
169 float_error_arg2 = num2; \
170 float_error_fn_name = name; \
171 in_float = 1; errno = 0; (d); in_float = 0; \
174 case EDOM: domain_error (float_error_fn_name, float_error_arg); \
175 case ERANGE: range_error (float_error_fn_name, float_error_arg); \
176 default: arith_error (float_error_fn_name, float_error_arg); \
180 #define IN_FLOAT(d, name, num) (in_float = 1, (d), in_float = 0)
181 #define IN_FLOAT2(d, name, num, num2) (in_float = 1, (d), in_float = 0)
184 /* Convert float to Lisp_Int if it fits, else signal a range error
185 using the given arguments. */
186 #define FLOAT_TO_INT(x, i, name, num) \
189 if (FIXNUM_OVERFLOW_P (x)) \
190 range_error (name, num); \
191 XSETINT (i, (EMACS_INT)(x)); \
194 #define FLOAT_TO_INT2(x, i, name, num1, num2) \
197 if (FIXNUM_OVERFLOW_P (x)) \
198 range_error2 (name, num1, num2); \
199 XSETINT (i, (EMACS_INT)(x)); \
203 #define arith_error(op,arg) \
204 Fsignal (Qarith_error, Fcons (build_string ((op)), Fcons ((arg), Qnil)))
205 #define range_error(op,arg) \
206 Fsignal (Qrange_error, Fcons (build_string ((op)), Fcons ((arg), Qnil)))
207 #define range_error2(op,a1,a2) \
208 Fsignal (Qrange_error, Fcons (build_string ((op)), \
209 Fcons ((a1), Fcons ((a2), Qnil))))
210 #define domain_error(op,arg) \
211 Fsignal (Qdomain_error, Fcons (build_string ((op)), Fcons ((arg), Qnil)))
212 #define domain_error2(op,a1,a2) \
213 Fsignal (Qdomain_error, Fcons (build_string ((op)), \
214 Fcons ((a1), Fcons ((a2), Qnil))))
216 /* Extract a Lisp number as a `double', or signal an error. */
222 CHECK_NUMBER_OR_FLOAT (num
);
225 return XFLOAT_DATA (num
);
226 return (double) XINT (num
);
229 /* Trig functions. */
231 DEFUN ("acos", Facos
, Sacos
, 1, 1, 0,
232 doc
: /* Return the inverse cosine of ARG. */)
234 register Lisp_Object arg
;
236 double d
= extract_float (arg
);
237 #ifdef FLOAT_CHECK_DOMAIN
238 if (d
> 1.0 || d
< -1.0)
239 domain_error ("acos", arg
);
241 IN_FLOAT (d
= acos (d
), "acos", arg
);
242 return make_float (d
);
245 DEFUN ("asin", Fasin
, Sasin
, 1, 1, 0,
246 doc
: /* Return the inverse sine of ARG. */)
248 register Lisp_Object arg
;
250 double d
= extract_float (arg
);
251 #ifdef FLOAT_CHECK_DOMAIN
252 if (d
> 1.0 || d
< -1.0)
253 domain_error ("asin", arg
);
255 IN_FLOAT (d
= asin (d
), "asin", arg
);
256 return make_float (d
);
259 DEFUN ("atan", Fatan
, Satan
, 1, 2, 0,
260 doc
: /* Return the inverse tangent of the arguments.
261 If only one argument Y is given, return the inverse tangent of Y.
262 If two arguments Y and X are given, return the inverse tangent of Y
263 divided by X, i.e. the angle in radians between the vector (X, Y)
266 register Lisp_Object y
, x
;
268 double d
= extract_float (y
);
271 IN_FLOAT (d
= atan (d
), "atan", y
);
274 double d2
= extract_float (x
);
276 IN_FLOAT2 (d
= atan2 (d
, d2
), "atan", y
, x
);
278 return make_float (d
);
281 DEFUN ("cos", Fcos
, Scos
, 1, 1, 0,
282 doc
: /* Return the cosine of ARG. */)
284 register Lisp_Object arg
;
286 double d
= extract_float (arg
);
287 IN_FLOAT (d
= cos (d
), "cos", arg
);
288 return make_float (d
);
291 DEFUN ("sin", Fsin
, Ssin
, 1, 1, 0,
292 doc
: /* Return the sine of ARG. */)
294 register Lisp_Object arg
;
296 double d
= extract_float (arg
);
297 IN_FLOAT (d
= sin (d
), "sin", arg
);
298 return make_float (d
);
301 DEFUN ("tan", Ftan
, Stan
, 1, 1, 0,
302 doc
: /* Return the tangent of ARG. */)
304 register Lisp_Object arg
;
306 double d
= extract_float (arg
);
308 #ifdef FLOAT_CHECK_DOMAIN
310 domain_error ("tan", arg
);
312 IN_FLOAT (d
= sin (d
) / c
, "tan", arg
);
313 return make_float (d
);
316 #if 0 /* Leave these out unless we find there's a reason for them. */
318 DEFUN ("bessel-j0", Fbessel_j0
, Sbessel_j0
, 1, 1, 0,
319 doc
: /* Return the bessel function j0 of ARG. */)
321 register Lisp_Object arg
;
323 double d
= extract_float (arg
);
324 IN_FLOAT (d
= j0 (d
), "bessel-j0", arg
);
325 return make_float (d
);
328 DEFUN ("bessel-j1", Fbessel_j1
, Sbessel_j1
, 1, 1, 0,
329 doc
: /* Return the bessel function j1 of ARG. */)
331 register Lisp_Object arg
;
333 double d
= extract_float (arg
);
334 IN_FLOAT (d
= j1 (d
), "bessel-j1", arg
);
335 return make_float (d
);
338 DEFUN ("bessel-jn", Fbessel_jn
, Sbessel_jn
, 2, 2, 0,
339 doc
: /* Return the order N bessel function output jn of ARG.
340 The first arg (the order) is truncated to an integer. */)
342 register Lisp_Object n
, arg
;
344 int i1
= extract_float (n
);
345 double f2
= extract_float (arg
);
347 IN_FLOAT (f2
= jn (i1
, f2
), "bessel-jn", n
);
348 return make_float (f2
);
351 DEFUN ("bessel-y0", Fbessel_y0
, Sbessel_y0
, 1, 1, 0,
352 doc
: /* Return the bessel function y0 of ARG. */)
354 register Lisp_Object arg
;
356 double d
= extract_float (arg
);
357 IN_FLOAT (d
= y0 (d
), "bessel-y0", arg
);
358 return make_float (d
);
361 DEFUN ("bessel-y1", Fbessel_y1
, Sbessel_y1
, 1, 1, 0,
362 doc
: /* Return the bessel function y1 of ARG. */)
364 register Lisp_Object arg
;
366 double d
= extract_float (arg
);
367 IN_FLOAT (d
= y1 (d
), "bessel-y0", arg
);
368 return make_float (d
);
371 DEFUN ("bessel-yn", Fbessel_yn
, Sbessel_yn
, 2, 2, 0,
372 doc
: /* Return the order N bessel function output yn of ARG.
373 The first arg (the order) is truncated to an integer. */)
375 register Lisp_Object n
, arg
;
377 int i1
= extract_float (n
);
378 double f2
= extract_float (arg
);
380 IN_FLOAT (f2
= yn (i1
, f2
), "bessel-yn", n
);
381 return make_float (f2
);
386 #if 0 /* Leave these out unless we see they are worth having. */
388 DEFUN ("erf", Ferf
, Serf
, 1, 1, 0,
389 doc
: /* Return the mathematical error function of ARG. */)
391 register Lisp_Object arg
;
393 double d
= extract_float (arg
);
394 IN_FLOAT (d
= erf (d
), "erf", arg
);
395 return make_float (d
);
398 DEFUN ("erfc", Ferfc
, Serfc
, 1, 1, 0,
399 doc
: /* Return the complementary error function of ARG. */)
401 register Lisp_Object arg
;
403 double d
= extract_float (arg
);
404 IN_FLOAT (d
= erfc (d
), "erfc", arg
);
405 return make_float (d
);
408 DEFUN ("log-gamma", Flog_gamma
, Slog_gamma
, 1, 1, 0,
409 doc
: /* Return the log gamma of ARG. */)
411 register Lisp_Object arg
;
413 double d
= extract_float (arg
);
414 IN_FLOAT (d
= lgamma (d
), "log-gamma", arg
);
415 return make_float (d
);
418 DEFUN ("cube-root", Fcube_root
, Scube_root
, 1, 1, 0,
419 doc
: /* Return the cube root of ARG. */)
421 register Lisp_Object arg
;
423 double d
= extract_float (arg
);
425 IN_FLOAT (d
= cbrt (d
), "cube-root", arg
);
428 IN_FLOAT (d
= pow (d
, 1.0/3.0), "cube-root", arg
);
430 IN_FLOAT (d
= -pow (-d
, 1.0/3.0), "cube-root", arg
);
432 return make_float (d
);
437 DEFUN ("exp", Fexp
, Sexp
, 1, 1, 0,
438 doc
: /* Return the exponential base e of ARG. */)
440 register Lisp_Object arg
;
442 double d
= extract_float (arg
);
443 #ifdef FLOAT_CHECK_DOMAIN
444 if (d
> 709.7827) /* Assume IEEE doubles here */
445 range_error ("exp", arg
);
447 return make_float (0.0);
450 IN_FLOAT (d
= exp (d
), "exp", arg
);
451 return make_float (d
);
454 DEFUN ("expt", Fexpt
, Sexpt
, 2, 2, 0,
455 doc
: /* Return the exponential ARG1 ** ARG2. */)
457 register Lisp_Object arg1
, arg2
;
461 CHECK_NUMBER_OR_FLOAT (arg1
);
462 CHECK_NUMBER_OR_FLOAT (arg2
);
463 if (INTEGERP (arg1
) /* common lisp spec */
464 && INTEGERP (arg2
) /* don't promote, if both are ints, and */
465 && 0 <= XINT (arg2
)) /* we are sure the result is not fractional */
466 { /* this can be improved by pre-calculating */
467 EMACS_INT acc
, x
, y
; /* some binary powers of x then accumulating */
479 acc
= (y
& 1) ? -1 : 1;
490 y
= (unsigned)y
>> 1;
496 f1
= FLOATP (arg1
) ? XFLOAT_DATA (arg1
) : XINT (arg1
);
497 f2
= FLOATP (arg2
) ? XFLOAT_DATA (arg2
) : XINT (arg2
);
498 /* Really should check for overflow, too */
499 if (f1
== 0.0 && f2
== 0.0)
501 #ifdef FLOAT_CHECK_DOMAIN
502 else if ((f1
== 0.0 && f2
< 0.0) || (f1
< 0 && f2
!= floor(f2
)))
503 domain_error2 ("expt", arg1
, arg2
);
505 IN_FLOAT2 (f1
= pow (f1
, f2
), "expt", arg1
, arg2
);
506 return make_float (f1
);
509 DEFUN ("log", Flog
, Slog
, 1, 2, 0,
510 doc
: /* Return the natural logarithm of ARG.
511 If second optional argument BASE is given, return log ARG using that base. */)
513 register Lisp_Object arg
, base
;
515 double d
= extract_float (arg
);
517 #ifdef FLOAT_CHECK_DOMAIN
519 domain_error2 ("log", arg
, base
);
522 IN_FLOAT (d
= log (d
), "log", arg
);
525 double b
= extract_float (base
);
527 #ifdef FLOAT_CHECK_DOMAIN
528 if (b
<= 0.0 || b
== 1.0)
529 domain_error2 ("log", arg
, base
);
532 IN_FLOAT2 (d
= log10 (d
), "log", arg
, base
);
534 IN_FLOAT2 (d
= log (d
) / log (b
), "log", arg
, base
);
536 return make_float (d
);
539 DEFUN ("log10", Flog10
, Slog10
, 1, 1, 0,
540 doc
: /* Return the logarithm base 10 of ARG. */)
542 register Lisp_Object arg
;
544 double d
= extract_float (arg
);
545 #ifdef FLOAT_CHECK_DOMAIN
547 domain_error ("log10", arg
);
549 IN_FLOAT (d
= log10 (d
), "log10", arg
);
550 return make_float (d
);
553 DEFUN ("sqrt", Fsqrt
, Ssqrt
, 1, 1, 0,
554 doc
: /* Return the square root of ARG. */)
556 register Lisp_Object arg
;
558 double d
= extract_float (arg
);
559 #ifdef FLOAT_CHECK_DOMAIN
561 domain_error ("sqrt", arg
);
563 IN_FLOAT (d
= sqrt (d
), "sqrt", arg
);
564 return make_float (d
);
567 #if 0 /* Not clearly worth adding. */
569 DEFUN ("acosh", Facosh
, Sacosh
, 1, 1, 0,
570 doc
: /* Return the inverse hyperbolic cosine of ARG. */)
572 register Lisp_Object arg
;
574 double d
= extract_float (arg
);
575 #ifdef FLOAT_CHECK_DOMAIN
577 domain_error ("acosh", arg
);
579 #ifdef HAVE_INVERSE_HYPERBOLIC
580 IN_FLOAT (d
= acosh (d
), "acosh", arg
);
582 IN_FLOAT (d
= log (d
+ sqrt (d
*d
- 1.0)), "acosh", arg
);
584 return make_float (d
);
587 DEFUN ("asinh", Fasinh
, Sasinh
, 1, 1, 0,
588 doc
: /* Return the inverse hyperbolic sine of ARG. */)
590 register Lisp_Object arg
;
592 double d
= extract_float (arg
);
593 #ifdef HAVE_INVERSE_HYPERBOLIC
594 IN_FLOAT (d
= asinh (d
), "asinh", arg
);
596 IN_FLOAT (d
= log (d
+ sqrt (d
*d
+ 1.0)), "asinh", arg
);
598 return make_float (d
);
601 DEFUN ("atanh", Fatanh
, Satanh
, 1, 1, 0,
602 doc
: /* Return the inverse hyperbolic tangent of ARG. */)
604 register Lisp_Object arg
;
606 double d
= extract_float (arg
);
607 #ifdef FLOAT_CHECK_DOMAIN
608 if (d
>= 1.0 || d
<= -1.0)
609 domain_error ("atanh", arg
);
611 #ifdef HAVE_INVERSE_HYPERBOLIC
612 IN_FLOAT (d
= atanh (d
), "atanh", arg
);
614 IN_FLOAT (d
= 0.5 * log ((1.0 + d
) / (1.0 - d
)), "atanh", arg
);
616 return make_float (d
);
619 DEFUN ("cosh", Fcosh
, Scosh
, 1, 1, 0,
620 doc
: /* Return the hyperbolic cosine of ARG. */)
622 register Lisp_Object arg
;
624 double d
= extract_float (arg
);
625 #ifdef FLOAT_CHECK_DOMAIN
626 if (d
> 710.0 || d
< -710.0)
627 range_error ("cosh", arg
);
629 IN_FLOAT (d
= cosh (d
), "cosh", arg
);
630 return make_float (d
);
633 DEFUN ("sinh", Fsinh
, Ssinh
, 1, 1, 0,
634 doc
: /* Return the hyperbolic sine of ARG. */)
636 register Lisp_Object arg
;
638 double d
= extract_float (arg
);
639 #ifdef FLOAT_CHECK_DOMAIN
640 if (d
> 710.0 || d
< -710.0)
641 range_error ("sinh", arg
);
643 IN_FLOAT (d
= sinh (d
), "sinh", arg
);
644 return make_float (d
);
647 DEFUN ("tanh", Ftanh
, Stanh
, 1, 1, 0,
648 doc
: /* Return the hyperbolic tangent of ARG. */)
650 register Lisp_Object arg
;
652 double d
= extract_float (arg
);
653 IN_FLOAT (d
= tanh (d
), "tanh", arg
);
654 return make_float (d
);
658 DEFUN ("abs", Fabs
, Sabs
, 1, 1, 0,
659 doc
: /* Return the absolute value of ARG. */)
661 register Lisp_Object arg
;
663 CHECK_NUMBER_OR_FLOAT (arg
);
666 IN_FLOAT (arg
= make_float (fabs (XFLOAT_DATA (arg
))), "abs", arg
);
667 else if (XINT (arg
) < 0)
668 XSETINT (arg
, - XINT (arg
));
673 DEFUN ("float", Ffloat
, Sfloat
, 1, 1, 0,
674 doc
: /* Return the floating point number equal to ARG. */)
676 register Lisp_Object arg
;
678 CHECK_NUMBER_OR_FLOAT (arg
);
681 return make_float ((double) XINT (arg
));
682 else /* give 'em the same float back */
686 DEFUN ("logb", Flogb
, Slogb
, 1, 1, 0,
687 doc
: /* Returns largest integer <= the base 2 log of the magnitude of ARG.
688 This is the same as the exponent of a float. */)
694 double f
= extract_float (arg
);
697 value
= MOST_NEGATIVE_FIXNUM
;
701 IN_FLOAT (value
= logb (f
), "logb", arg
);
705 IN_FLOAT (frexp (f
, &ivalue
), "logb", arg
);
715 for (i
= 1, d
= 0.5; d
* d
>= f
; i
+= i
)
722 for (i
= 1, d
= 2.0; d
* d
<= f
; i
+= i
)
730 XSETINT (val
, value
);
735 /* the rounding functions */
738 rounding_driver (arg
, divisor
, double_round
, int_round2
, name
)
739 register Lisp_Object arg
, divisor
;
740 double (*double_round
) ();
741 EMACS_INT (*int_round2
) ();
744 CHECK_NUMBER_OR_FLOAT (arg
);
746 if (! NILP (divisor
))
750 CHECK_NUMBER_OR_FLOAT (divisor
);
752 if (FLOATP (arg
) || FLOATP (divisor
))
756 f1
= FLOATP (arg
) ? XFLOAT_DATA (arg
) : XINT (arg
);
757 f2
= (FLOATP (divisor
) ? XFLOAT_DATA (divisor
) : XINT (divisor
));
758 if (! IEEE_FLOATING_POINT
&& f2
== 0)
759 Fsignal (Qarith_error
, Qnil
);
761 IN_FLOAT2 (f1
= (*double_round
) (f1
/ f2
), name
, arg
, divisor
);
762 FLOAT_TO_INT2 (f1
, arg
, name
, arg
, divisor
);
770 Fsignal (Qarith_error
, Qnil
);
772 XSETINT (arg
, (*int_round2
) (i1
, i2
));
780 IN_FLOAT (d
= (*double_round
) (XFLOAT_DATA (arg
)), name
, arg
);
781 FLOAT_TO_INT (d
, arg
, name
, arg
);
787 /* With C's /, the result is implementation-defined if either operand
788 is negative, so take care with negative operands in the following
789 integer functions. */
796 ? (i1
< 0 ? ((-1 - i1
) / -i2
) + 1 : - (i1
/ -i2
))
797 : (i1
<= 0 ? - (-i1
/ i2
) : ((i1
- 1) / i2
) + 1));
805 ? (i1
<= 0 ? -i1
/ -i2
: -1 - ((i1
- 1) / -i2
))
806 : (i1
< 0 ? -1 - ((-1 - i1
) / i2
) : i1
/ i2
));
814 ? (i1
< 0 ? -i1
/ -i2
: - (i1
/ -i2
))
815 : (i1
< 0 ? - (-i1
/ i2
) : i1
/ i2
));
822 /* The C language's division operator gives us one remainder R, but
823 we want the remainder R1 on the other side of 0 if R1 is closer
824 to 0 than R is; because we want to round to even, we also want R1
825 if R and R1 are the same distance from 0 and if C's quotient is
827 EMACS_INT q
= i1
/ i2
;
828 EMACS_INT r
= i1
% i2
;
829 EMACS_INT abs_r
= r
< 0 ? -r
: r
;
830 EMACS_INT abs_r1
= (i2
< 0 ? -i2
: i2
) - abs_r
;
831 return q
+ (abs_r
+ (q
& 1) <= abs_r1
? 0 : (i2
^ r
) < 0 ? -1 : 1);
834 /* The code uses emacs_rint, so that it works to undefine HAVE_RINT
835 if `rint' exists but does not work right. */
837 #define emacs_rint rint
843 return floor (d
+ 0.5);
854 DEFUN ("ceiling", Fceiling
, Sceiling
, 1, 2, 0,
855 doc
: /* Return the smallest integer no less than ARG.
856 This rounds the value towards +inf.
857 With optional DIVISOR, return the smallest integer no less than ARG/DIVISOR. */)
859 Lisp_Object arg
, divisor
;
861 return rounding_driver (arg
, divisor
, ceil
, ceiling2
, "ceiling");
864 DEFUN ("floor", Ffloor
, Sfloor
, 1, 2, 0,
865 doc
: /* Return the largest integer no greater than ARG.
866 This rounds the value towards -inf.
867 With optional DIVISOR, return the largest integer no greater than ARG/DIVISOR. */)
869 Lisp_Object arg
, divisor
;
871 return rounding_driver (arg
, divisor
, floor
, floor2
, "floor");
874 DEFUN ("round", Fround
, Sround
, 1, 2, 0,
875 doc
: /* Return the nearest integer to ARG.
876 With optional DIVISOR, return the nearest integer to ARG/DIVISOR.
878 Rounding a value equidistant between two integers may choose the
879 integer closer to zero, or it may prefer an even integer, depending on
880 your machine. For example, \(round 2.5\) can return 3 on some
881 systems, but 2 on others. */)
883 Lisp_Object arg
, divisor
;
885 return rounding_driver (arg
, divisor
, emacs_rint
, round2
, "round");
888 DEFUN ("truncate", Ftruncate
, Struncate
, 1, 2, 0,
889 doc
: /* Truncate a floating point number to an int.
890 Rounds ARG toward zero.
891 With optional DIVISOR, truncate ARG/DIVISOR. */)
893 Lisp_Object arg
, divisor
;
895 return rounding_driver (arg
, divisor
, double_identity
, truncate2
,
902 register Lisp_Object x
, y
;
906 f1
= FLOATP (x
) ? XFLOAT_DATA (x
) : XINT (x
);
907 f2
= FLOATP (y
) ? XFLOAT_DATA (y
) : XINT (y
);
909 if (! IEEE_FLOATING_POINT
&& f2
== 0)
910 Fsignal (Qarith_error
, Qnil
);
912 /* If the "remainder" comes out with the wrong sign, fix it. */
913 IN_FLOAT2 ((f1
= fmod (f1
, f2
),
914 f1
= (f2
< 0 ? f1
> 0 : f1
< 0) ? f1
+ f2
: f1
),
916 return make_float (f1
);
919 /* It's not clear these are worth adding. */
921 DEFUN ("fceiling", Ffceiling
, Sfceiling
, 1, 1, 0,
922 doc
: /* Return the smallest integer no less than ARG, as a float.
923 \(Round toward +inf.\) */)
925 register Lisp_Object arg
;
927 double d
= extract_float (arg
);
928 IN_FLOAT (d
= ceil (d
), "fceiling", arg
);
929 return make_float (d
);
932 DEFUN ("ffloor", Fffloor
, Sffloor
, 1, 1, 0,
933 doc
: /* Return the largest integer no greater than ARG, as a float.
934 \(Round towards -inf.\) */)
936 register Lisp_Object arg
;
938 double d
= extract_float (arg
);
939 IN_FLOAT (d
= floor (d
), "ffloor", arg
);
940 return make_float (d
);
943 DEFUN ("fround", Ffround
, Sfround
, 1, 1, 0,
944 doc
: /* Return the nearest integer to ARG, as a float. */)
946 register Lisp_Object arg
;
948 double d
= extract_float (arg
);
949 IN_FLOAT (d
= emacs_rint (d
), "fround", arg
);
950 return make_float (d
);
953 DEFUN ("ftruncate", Fftruncate
, Sftruncate
, 1, 1, 0,
954 doc
: /* Truncate a floating point number to an integral float value.
955 Rounds the value toward zero. */)
957 register Lisp_Object arg
;
959 double d
= extract_float (arg
);
961 IN_FLOAT (d
= floor (d
), "ftruncate", arg
);
963 IN_FLOAT (d
= ceil (d
), "ftruncate", arg
);
964 return make_float (d
);
967 #ifdef FLOAT_CATCH_SIGILL
973 fatal_error_signal (signo
);
978 #else /* not BSD4_1 */
979 sigsetmask (SIGEMPTYMASK
);
980 #endif /* not BSD4_1 */
982 /* Must reestablish handler each time it is called. */
983 signal (SIGILL
, float_error
);
984 #endif /* BSD_SYSTEM */
986 SIGNAL_THREAD_CHECK (signo
);
989 Fsignal (Qarith_error
, Fcons (float_error_arg
, Qnil
));
992 /* Another idea was to replace the library function `infnan'
993 where SIGILL is signaled. */
995 #endif /* FLOAT_CATCH_SIGILL */
1000 struct exception
*x
;
1004 /* Not called from emacs-lisp float routines; do the default thing. */
1006 if (!strcmp (x
->name
, "pow"))
1010 = Fcons (build_string (x
->name
),
1011 Fcons (make_float (x
->arg1
),
1012 ((!strcmp (x
->name
, "log") || !strcmp (x
->name
, "pow"))
1013 ? Fcons (make_float (x
->arg2
), Qnil
)
1017 case DOMAIN
: Fsignal (Qdomain_error
, args
); break;
1018 case SING
: Fsignal (Qsingularity_error
, args
); break;
1019 case OVERFLOW
: Fsignal (Qoverflow_error
, args
); break;
1020 case UNDERFLOW
: Fsignal (Qunderflow_error
, args
); break;
1021 default: Fsignal (Qarith_error
, args
); break;
1023 return (1); /* don't set errno or print a message */
1025 #endif /* HAVE_MATHERR */
1030 #ifdef FLOAT_CATCH_SIGILL
1031 signal (SIGILL
, float_error
);
1052 defsubr (&Sbessel_y0
);
1053 defsubr (&Sbessel_y1
);
1054 defsubr (&Sbessel_yn
);
1055 defsubr (&Sbessel_j0
);
1056 defsubr (&Sbessel_j1
);
1057 defsubr (&Sbessel_jn
);
1060 defsubr (&Slog_gamma
);
1061 defsubr (&Scube_root
);
1063 defsubr (&Sfceiling
);
1066 defsubr (&Sftruncate
);
1076 defsubr (&Sceiling
);
1079 defsubr (&Struncate
);
1082 /* arch-tag: be05bf9d-049e-4e31-91b9-e6153d483ae7
1083 (do not change this comment) */