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 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
104 #ifdef FLOAT_CATCH_SIGILL
105 static SIGTYPE
float_error ();
108 /* Nonzero while executing in floating point.
109 This tells float_error what to do. */
113 /* If an argument is out of range for a mathematical function,
114 here is the actual argument value to use in the error message.
115 These variables are used only across the floating point library call
116 so there is no need to staticpro them. */
118 static Lisp_Object float_error_arg
, float_error_arg2
;
120 static char *float_error_fn_name
;
122 /* Evaluate the floating point expression D, recording NUM
123 as the original argument for error messages.
124 D is normally an assignment expression.
125 Handle errors which may result in signals or may set errno.
127 Note that float_error may be declared to return void, so you can't
128 just cast the zero after the colon to (SIGTYPE) to make the types
131 #ifdef FLOAT_CHECK_ERRNO
132 #define IN_FLOAT(d, name, num) \
134 float_error_arg = num; \
135 float_error_fn_name = name; \
136 in_float = 1; errno = 0; (d); in_float = 0; \
139 case EDOM: domain_error (float_error_fn_name, float_error_arg); \
140 case ERANGE: range_error (float_error_fn_name, float_error_arg); \
141 default: arith_error (float_error_fn_name, float_error_arg); \
144 #define IN_FLOAT2(d, name, num, num2) \
146 float_error_arg = num; \
147 float_error_arg2 = num2; \
148 float_error_fn_name = name; \
149 in_float = 1; errno = 0; (d); in_float = 0; \
152 case EDOM: domain_error (float_error_fn_name, float_error_arg); \
153 case ERANGE: range_error (float_error_fn_name, float_error_arg); \
154 default: arith_error (float_error_fn_name, float_error_arg); \
158 #define IN_FLOAT(d, name, num) (in_float = 1, (d), in_float = 0)
159 #define IN_FLOAT2(d, name, num, num2) (in_float = 1, (d), in_float = 0)
162 /* Convert float to Lisp_Int if it fits, else signal a range error
163 using the given arguments. */
164 #define FLOAT_TO_INT(x, i, name, num) \
167 if (FIXNUM_OVERFLOW_P (x)) \
168 range_error (name, num); \
169 XSETINT (i, (EMACS_INT)(x)); \
172 #define FLOAT_TO_INT2(x, i, name, num1, num2) \
175 if (FIXNUM_OVERFLOW_P (x)) \
176 range_error2 (name, num1, num2); \
177 XSETINT (i, (EMACS_INT)(x)); \
181 #define arith_error(op,arg) \
182 xsignal2 (Qarith_error, build_string ((op)), (arg))
183 #define range_error(op,arg) \
184 xsignal2 (Qrange_error, build_string ((op)), (arg))
185 #define range_error2(op,a1,a2) \
186 xsignal3 (Qrange_error, build_string ((op)), (a1), (a2))
187 #define domain_error(op,arg) \
188 xsignal2 (Qdomain_error, build_string ((op)), (arg))
189 #define domain_error2(op,a1,a2) \
190 xsignal3 (Qdomain_error, build_string ((op)), (a1), (a2))
192 /* Extract a Lisp number as a `double', or signal an error. */
198 CHECK_NUMBER_OR_FLOAT (num
);
201 return XFLOAT_DATA (num
);
202 return (double) XINT (num
);
205 /* Trig functions. */
207 DEFUN ("acos", Facos
, Sacos
, 1, 1, 0,
208 doc
: /* Return the inverse cosine of ARG. */)
210 register Lisp_Object arg
;
212 double d
= extract_float (arg
);
213 #ifdef FLOAT_CHECK_DOMAIN
214 if (d
> 1.0 || d
< -1.0)
215 domain_error ("acos", arg
);
217 IN_FLOAT (d
= acos (d
), "acos", arg
);
218 return make_float (d
);
221 DEFUN ("asin", Fasin
, Sasin
, 1, 1, 0,
222 doc
: /* Return the inverse sine of ARG. */)
224 register Lisp_Object arg
;
226 double d
= extract_float (arg
);
227 #ifdef FLOAT_CHECK_DOMAIN
228 if (d
> 1.0 || d
< -1.0)
229 domain_error ("asin", arg
);
231 IN_FLOAT (d
= asin (d
), "asin", arg
);
232 return make_float (d
);
235 DEFUN ("atan", Fatan
, Satan
, 1, 2, 0,
236 doc
: /* Return the inverse tangent of the arguments.
237 If only one argument Y is given, return the inverse tangent of Y.
238 If two arguments Y and X are given, return the inverse tangent of Y
239 divided by X, i.e. the angle in radians between the vector (X, Y)
242 register Lisp_Object y
, x
;
244 double d
= extract_float (y
);
247 IN_FLOAT (d
= atan (d
), "atan", y
);
250 double d2
= extract_float (x
);
252 IN_FLOAT2 (d
= atan2 (d
, d2
), "atan", y
, x
);
254 return make_float (d
);
257 DEFUN ("cos", Fcos
, Scos
, 1, 1, 0,
258 doc
: /* Return the cosine of ARG. */)
260 register Lisp_Object arg
;
262 double d
= extract_float (arg
);
263 IN_FLOAT (d
= cos (d
), "cos", arg
);
264 return make_float (d
);
267 DEFUN ("sin", Fsin
, Ssin
, 1, 1, 0,
268 doc
: /* Return the sine of ARG. */)
270 register Lisp_Object arg
;
272 double d
= extract_float (arg
);
273 IN_FLOAT (d
= sin (d
), "sin", arg
);
274 return make_float (d
);
277 DEFUN ("tan", Ftan
, Stan
, 1, 1, 0,
278 doc
: /* Return the tangent of ARG. */)
280 register Lisp_Object arg
;
282 double d
= extract_float (arg
);
284 #ifdef FLOAT_CHECK_DOMAIN
286 domain_error ("tan", arg
);
288 IN_FLOAT (d
= sin (d
) / c
, "tan", arg
);
289 return make_float (d
);
292 #if defined HAVE_ISNAN && defined HAVE_COPYSIGN
293 DEFUN ("isnan", Fisnan
, Sisnan
, 1, 1, 0,
294 doc
: /* Return non nil iff argument X is a NaN. */)
299 return isnan (XFLOAT_DATA (x
)) ? Qt
: Qnil
;
302 DEFUN ("copysign", Fcopysign
, Scopysign
, 1, 2, 0,
303 doc
: /* Copy sign of X2 to value of X1, and return the result.
304 Cause an error if X1 or X2 is not a float. */)
313 f1
= XFLOAT_DATA (x1
);
314 f2
= XFLOAT_DATA (x2
);
316 return make_float (copysign (f1
, f2
));
319 DEFUN ("frexp", Ffrexp
, Sfrexp
, 1, 1, 0,
320 doc
: /* Get significand and exponent of a floating point number.
321 Breaks the floating point number X into its binary significand SGNFCAND
322 \(a floating point value between 0.5 (included) and 1.0 (excluded))
323 and an integral exponent EXP for 2, such that:
327 The function returns the cons cell (SGNFCAND . EXP).
328 If X is zero, both parts (SGNFCAND and EXP) are zero. */)
332 double f
= XFLOATINT (x
);
335 return Fcons (make_float (0.0), make_number (0));
339 double sgnfcand
= frexp (f
, &exp
);
340 return Fcons (make_float (sgnfcand
), make_number (exp
));
344 DEFUN ("ldexp", Fldexp
, Sldexp
, 1, 2, 0,
345 doc
: /* Construct number X from significand SGNFCAND and exponent EXP.
346 Returns the floating point value resulting from multiplying SGNFCAND
347 (the significand) by 2 raised to the power of EXP (the exponent). */)
349 Lisp_Object sgnfcand
, exp
;
352 return make_float (ldexp (XFLOATINT (sgnfcand
), XINT (exp
)));
356 #if 0 /* Leave these out unless we find there's a reason for them. */
358 DEFUN ("bessel-j0", Fbessel_j0
, Sbessel_j0
, 1, 1, 0,
359 doc
: /* Return the bessel function j0 of ARG. */)
361 register Lisp_Object arg
;
363 double d
= extract_float (arg
);
364 IN_FLOAT (d
= j0 (d
), "bessel-j0", arg
);
365 return make_float (d
);
368 DEFUN ("bessel-j1", Fbessel_j1
, Sbessel_j1
, 1, 1, 0,
369 doc
: /* Return the bessel function j1 of ARG. */)
371 register Lisp_Object arg
;
373 double d
= extract_float (arg
);
374 IN_FLOAT (d
= j1 (d
), "bessel-j1", arg
);
375 return make_float (d
);
378 DEFUN ("bessel-jn", Fbessel_jn
, Sbessel_jn
, 2, 2, 0,
379 doc
: /* Return the order N bessel function output jn of ARG.
380 The first arg (the order) is truncated to an integer. */)
382 register Lisp_Object n
, arg
;
384 int i1
= extract_float (n
);
385 double f2
= extract_float (arg
);
387 IN_FLOAT (f2
= jn (i1
, f2
), "bessel-jn", n
);
388 return make_float (f2
);
391 DEFUN ("bessel-y0", Fbessel_y0
, Sbessel_y0
, 1, 1, 0,
392 doc
: /* Return the bessel function y0 of ARG. */)
394 register Lisp_Object arg
;
396 double d
= extract_float (arg
);
397 IN_FLOAT (d
= y0 (d
), "bessel-y0", arg
);
398 return make_float (d
);
401 DEFUN ("bessel-y1", Fbessel_y1
, Sbessel_y1
, 1, 1, 0,
402 doc
: /* Return the bessel function y1 of ARG. */)
404 register Lisp_Object arg
;
406 double d
= extract_float (arg
);
407 IN_FLOAT (d
= y1 (d
), "bessel-y0", arg
);
408 return make_float (d
);
411 DEFUN ("bessel-yn", Fbessel_yn
, Sbessel_yn
, 2, 2, 0,
412 doc
: /* Return the order N bessel function output yn of ARG.
413 The first arg (the order) is truncated to an integer. */)
415 register Lisp_Object n
, arg
;
417 int i1
= extract_float (n
);
418 double f2
= extract_float (arg
);
420 IN_FLOAT (f2
= yn (i1
, f2
), "bessel-yn", n
);
421 return make_float (f2
);
426 #if 0 /* Leave these out unless we see they are worth having. */
428 DEFUN ("erf", Ferf
, Serf
, 1, 1, 0,
429 doc
: /* Return the mathematical error function of ARG. */)
431 register Lisp_Object arg
;
433 double d
= extract_float (arg
);
434 IN_FLOAT (d
= erf (d
), "erf", arg
);
435 return make_float (d
);
438 DEFUN ("erfc", Ferfc
, Serfc
, 1, 1, 0,
439 doc
: /* Return the complementary error function of ARG. */)
441 register Lisp_Object arg
;
443 double d
= extract_float (arg
);
444 IN_FLOAT (d
= erfc (d
), "erfc", arg
);
445 return make_float (d
);
448 DEFUN ("log-gamma", Flog_gamma
, Slog_gamma
, 1, 1, 0,
449 doc
: /* Return the log gamma of ARG. */)
451 register Lisp_Object arg
;
453 double d
= extract_float (arg
);
454 IN_FLOAT (d
= lgamma (d
), "log-gamma", arg
);
455 return make_float (d
);
458 DEFUN ("cube-root", Fcube_root
, Scube_root
, 1, 1, 0,
459 doc
: /* Return the cube root of ARG. */)
461 register Lisp_Object arg
;
463 double d
= extract_float (arg
);
465 IN_FLOAT (d
= cbrt (d
), "cube-root", arg
);
468 IN_FLOAT (d
= pow (d
, 1.0/3.0), "cube-root", arg
);
470 IN_FLOAT (d
= -pow (-d
, 1.0/3.0), "cube-root", arg
);
472 return make_float (d
);
477 DEFUN ("exp", Fexp
, Sexp
, 1, 1, 0,
478 doc
: /* Return the exponential base e of ARG. */)
480 register Lisp_Object arg
;
482 double d
= extract_float (arg
);
483 #ifdef FLOAT_CHECK_DOMAIN
484 if (d
> 709.7827) /* Assume IEEE doubles here */
485 range_error ("exp", arg
);
487 return make_float (0.0);
490 IN_FLOAT (d
= exp (d
), "exp", arg
);
491 return make_float (d
);
494 DEFUN ("expt", Fexpt
, Sexpt
, 2, 2, 0,
495 doc
: /* Return the exponential ARG1 ** ARG2. */)
497 register Lisp_Object arg1
, arg2
;
501 CHECK_NUMBER_OR_FLOAT (arg1
);
502 CHECK_NUMBER_OR_FLOAT (arg2
);
503 if (INTEGERP (arg1
) /* common lisp spec */
504 && INTEGERP (arg2
) /* don't promote, if both are ints, and */
505 && 0 <= XINT (arg2
)) /* we are sure the result is not fractional */
506 { /* this can be improved by pre-calculating */
507 EMACS_INT acc
, x
, y
; /* some binary powers of x then accumulating */
519 acc
= (y
& 1) ? -1 : 1;
530 y
= (unsigned)y
>> 1;
536 f1
= FLOATP (arg1
) ? XFLOAT_DATA (arg1
) : XINT (arg1
);
537 f2
= FLOATP (arg2
) ? XFLOAT_DATA (arg2
) : XINT (arg2
);
538 /* Really should check for overflow, too */
539 if (f1
== 0.0 && f2
== 0.0)
541 #ifdef FLOAT_CHECK_DOMAIN
542 else if ((f1
== 0.0 && f2
< 0.0) || (f1
< 0 && f2
!= floor(f2
)))
543 domain_error2 ("expt", arg1
, arg2
);
545 IN_FLOAT2 (f3
= pow (f1
, f2
), "expt", arg1
, arg2
);
546 /* Check for overflow in the result. */
547 if (f1
!= 0.0 && f3
== 0.0)
548 range_error ("expt", arg1
);
549 return make_float (f3
);
552 DEFUN ("log", Flog
, Slog
, 1, 2, 0,
553 doc
: /* Return the natural logarithm of ARG.
554 If the optional argument BASE is given, return log ARG using that base. */)
556 register Lisp_Object arg
, base
;
558 double d
= extract_float (arg
);
560 #ifdef FLOAT_CHECK_DOMAIN
562 domain_error2 ("log", arg
, base
);
565 IN_FLOAT (d
= log (d
), "log", arg
);
568 double b
= extract_float (base
);
570 #ifdef FLOAT_CHECK_DOMAIN
571 if (b
<= 0.0 || b
== 1.0)
572 domain_error2 ("log", arg
, base
);
575 IN_FLOAT2 (d
= log10 (d
), "log", arg
, base
);
577 IN_FLOAT2 (d
= log (d
) / log (b
), "log", arg
, base
);
579 return make_float (d
);
582 DEFUN ("log10", Flog10
, Slog10
, 1, 1, 0,
583 doc
: /* Return the logarithm base 10 of ARG. */)
585 register Lisp_Object arg
;
587 double d
= extract_float (arg
);
588 #ifdef FLOAT_CHECK_DOMAIN
590 domain_error ("log10", arg
);
592 IN_FLOAT (d
= log10 (d
), "log10", arg
);
593 return make_float (d
);
596 DEFUN ("sqrt", Fsqrt
, Ssqrt
, 1, 1, 0,
597 doc
: /* Return the square root of ARG. */)
599 register Lisp_Object arg
;
601 double d
= extract_float (arg
);
602 #ifdef FLOAT_CHECK_DOMAIN
604 domain_error ("sqrt", arg
);
606 IN_FLOAT (d
= sqrt (d
), "sqrt", arg
);
607 return make_float (d
);
610 #if 0 /* Not clearly worth adding. */
612 DEFUN ("acosh", Facosh
, Sacosh
, 1, 1, 0,
613 doc
: /* Return the inverse hyperbolic cosine of ARG. */)
615 register Lisp_Object arg
;
617 double d
= extract_float (arg
);
618 #ifdef FLOAT_CHECK_DOMAIN
620 domain_error ("acosh", arg
);
622 #ifdef HAVE_INVERSE_HYPERBOLIC
623 IN_FLOAT (d
= acosh (d
), "acosh", arg
);
625 IN_FLOAT (d
= log (d
+ sqrt (d
*d
- 1.0)), "acosh", arg
);
627 return make_float (d
);
630 DEFUN ("asinh", Fasinh
, Sasinh
, 1, 1, 0,
631 doc
: /* Return the inverse hyperbolic sine of ARG. */)
633 register Lisp_Object arg
;
635 double d
= extract_float (arg
);
636 #ifdef HAVE_INVERSE_HYPERBOLIC
637 IN_FLOAT (d
= asinh (d
), "asinh", arg
);
639 IN_FLOAT (d
= log (d
+ sqrt (d
*d
+ 1.0)), "asinh", arg
);
641 return make_float (d
);
644 DEFUN ("atanh", Fatanh
, Satanh
, 1, 1, 0,
645 doc
: /* Return the inverse hyperbolic tangent of ARG. */)
647 register Lisp_Object arg
;
649 double d
= extract_float (arg
);
650 #ifdef FLOAT_CHECK_DOMAIN
651 if (d
>= 1.0 || d
<= -1.0)
652 domain_error ("atanh", arg
);
654 #ifdef HAVE_INVERSE_HYPERBOLIC
655 IN_FLOAT (d
= atanh (d
), "atanh", arg
);
657 IN_FLOAT (d
= 0.5 * log ((1.0 + d
) / (1.0 - d
)), "atanh", arg
);
659 return make_float (d
);
662 DEFUN ("cosh", Fcosh
, Scosh
, 1, 1, 0,
663 doc
: /* Return the hyperbolic cosine of ARG. */)
665 register Lisp_Object arg
;
667 double d
= extract_float (arg
);
668 #ifdef FLOAT_CHECK_DOMAIN
669 if (d
> 710.0 || d
< -710.0)
670 range_error ("cosh", arg
);
672 IN_FLOAT (d
= cosh (d
), "cosh", arg
);
673 return make_float (d
);
676 DEFUN ("sinh", Fsinh
, Ssinh
, 1, 1, 0,
677 doc
: /* Return the hyperbolic sine of ARG. */)
679 register Lisp_Object arg
;
681 double d
= extract_float (arg
);
682 #ifdef FLOAT_CHECK_DOMAIN
683 if (d
> 710.0 || d
< -710.0)
684 range_error ("sinh", arg
);
686 IN_FLOAT (d
= sinh (d
), "sinh", arg
);
687 return make_float (d
);
690 DEFUN ("tanh", Ftanh
, Stanh
, 1, 1, 0,
691 doc
: /* Return the hyperbolic tangent of ARG. */)
693 register Lisp_Object arg
;
695 double d
= extract_float (arg
);
696 IN_FLOAT (d
= tanh (d
), "tanh", arg
);
697 return make_float (d
);
701 DEFUN ("abs", Fabs
, Sabs
, 1, 1, 0,
702 doc
: /* Return the absolute value of ARG. */)
704 register Lisp_Object arg
;
706 CHECK_NUMBER_OR_FLOAT (arg
);
709 IN_FLOAT (arg
= make_float (fabs (XFLOAT_DATA (arg
))), "abs", arg
);
710 else if (XINT (arg
) < 0)
711 XSETINT (arg
, - XINT (arg
));
716 DEFUN ("float", Ffloat
, Sfloat
, 1, 1, 0,
717 doc
: /* Return the floating point number equal to ARG. */)
719 register Lisp_Object arg
;
721 CHECK_NUMBER_OR_FLOAT (arg
);
724 return make_float ((double) XINT (arg
));
725 else /* give 'em the same float back */
729 DEFUN ("logb", Flogb
, Slogb
, 1, 1, 0,
730 doc
: /* Returns largest integer <= the base 2 log of the magnitude of ARG.
731 This is the same as the exponent of a float. */)
737 double f
= extract_float (arg
);
740 value
= MOST_NEGATIVE_FIXNUM
;
744 IN_FLOAT (value
= logb (f
), "logb", arg
);
748 IN_FLOAT (frexp (f
, &ivalue
), "logb", arg
);
758 for (i
= 1, d
= 0.5; d
* d
>= f
; i
+= i
)
765 for (i
= 1, d
= 2.0; d
* d
<= f
; i
+= i
)
773 XSETINT (val
, value
);
778 /* the rounding functions */
781 rounding_driver (arg
, divisor
, double_round
, int_round2
, name
)
782 register Lisp_Object arg
, divisor
;
783 double (*double_round
) ();
784 EMACS_INT (*int_round2
) ();
787 CHECK_NUMBER_OR_FLOAT (arg
);
789 if (! NILP (divisor
))
793 CHECK_NUMBER_OR_FLOAT (divisor
);
795 if (FLOATP (arg
) || FLOATP (divisor
))
799 f1
= FLOATP (arg
) ? XFLOAT_DATA (arg
) : XINT (arg
);
800 f2
= (FLOATP (divisor
) ? XFLOAT_DATA (divisor
) : XINT (divisor
));
801 if (! IEEE_FLOATING_POINT
&& f2
== 0)
802 xsignal0 (Qarith_error
);
804 IN_FLOAT2 (f1
= (*double_round
) (f1
/ f2
), name
, arg
, divisor
);
805 FLOAT_TO_INT2 (f1
, arg
, name
, arg
, divisor
);
813 xsignal0 (Qarith_error
);
815 XSETINT (arg
, (*int_round2
) (i1
, i2
));
823 IN_FLOAT (d
= (*double_round
) (XFLOAT_DATA (arg
)), name
, arg
);
824 FLOAT_TO_INT (d
, arg
, name
, arg
);
830 /* With C's /, the result is implementation-defined if either operand
831 is negative, so take care with negative operands in the following
832 integer functions. */
839 ? (i1
< 0 ? ((-1 - i1
) / -i2
) + 1 : - (i1
/ -i2
))
840 : (i1
<= 0 ? - (-i1
/ i2
) : ((i1
- 1) / i2
) + 1));
848 ? (i1
<= 0 ? -i1
/ -i2
: -1 - ((i1
- 1) / -i2
))
849 : (i1
< 0 ? -1 - ((-1 - i1
) / i2
) : i1
/ i2
));
857 ? (i1
< 0 ? -i1
/ -i2
: - (i1
/ -i2
))
858 : (i1
< 0 ? - (-i1
/ i2
) : i1
/ i2
));
865 /* The C language's division operator gives us one remainder R, but
866 we want the remainder R1 on the other side of 0 if R1 is closer
867 to 0 than R is; because we want to round to even, we also want R1
868 if R and R1 are the same distance from 0 and if C's quotient is
870 EMACS_INT q
= i1
/ i2
;
871 EMACS_INT r
= i1
% i2
;
872 EMACS_INT abs_r
= r
< 0 ? -r
: r
;
873 EMACS_INT abs_r1
= (i2
< 0 ? -i2
: i2
) - abs_r
;
874 return q
+ (abs_r
+ (q
& 1) <= abs_r1
? 0 : (i2
^ r
) < 0 ? -1 : 1);
877 /* The code uses emacs_rint, so that it works to undefine HAVE_RINT
878 if `rint' exists but does not work right. */
880 #define emacs_rint rint
886 return floor (d
+ 0.5);
897 DEFUN ("ceiling", Fceiling
, Sceiling
, 1, 2, 0,
898 doc
: /* Return the smallest integer no less than ARG.
899 This rounds the value towards +inf.
900 With optional DIVISOR, return the smallest integer no less than ARG/DIVISOR. */)
902 Lisp_Object arg
, divisor
;
904 return rounding_driver (arg
, divisor
, ceil
, ceiling2
, "ceiling");
907 DEFUN ("floor", Ffloor
, Sfloor
, 1, 2, 0,
908 doc
: /* Return the largest integer no greater than ARG.
909 This rounds the value towards -inf.
910 With optional DIVISOR, return the largest integer no greater than ARG/DIVISOR. */)
912 Lisp_Object arg
, divisor
;
914 return rounding_driver (arg
, divisor
, floor
, floor2
, "floor");
917 DEFUN ("round", Fround
, Sround
, 1, 2, 0,
918 doc
: /* Return the nearest integer to ARG.
919 With optional DIVISOR, return the nearest integer to ARG/DIVISOR.
921 Rounding a value equidistant between two integers may choose the
922 integer closer to zero, or it may prefer an even integer, depending on
923 your machine. For example, \(round 2.5\) can return 3 on some
924 systems, but 2 on others. */)
926 Lisp_Object arg
, divisor
;
928 return rounding_driver (arg
, divisor
, emacs_rint
, round2
, "round");
931 DEFUN ("truncate", Ftruncate
, Struncate
, 1, 2, 0,
932 doc
: /* Truncate a floating point number to an int.
933 Rounds ARG toward zero.
934 With optional DIVISOR, truncate ARG/DIVISOR. */)
936 Lisp_Object arg
, divisor
;
938 return rounding_driver (arg
, divisor
, double_identity
, truncate2
,
945 register Lisp_Object x
, y
;
949 f1
= FLOATP (x
) ? XFLOAT_DATA (x
) : XINT (x
);
950 f2
= FLOATP (y
) ? XFLOAT_DATA (y
) : XINT (y
);
952 if (! IEEE_FLOATING_POINT
&& f2
== 0)
953 xsignal0 (Qarith_error
);
955 /* If the "remainder" comes out with the wrong sign, fix it. */
956 IN_FLOAT2 ((f1
= fmod (f1
, f2
),
957 f1
= (f2
< 0 ? f1
> 0 : f1
< 0) ? f1
+ f2
: f1
),
959 return make_float (f1
);
962 /* It's not clear these are worth adding. */
964 DEFUN ("fceiling", Ffceiling
, Sfceiling
, 1, 1, 0,
965 doc
: /* Return the smallest integer no less than ARG, as a float.
966 \(Round toward +inf.\) */)
968 register Lisp_Object arg
;
970 double d
= extract_float (arg
);
971 IN_FLOAT (d
= ceil (d
), "fceiling", arg
);
972 return make_float (d
);
975 DEFUN ("ffloor", Fffloor
, Sffloor
, 1, 1, 0,
976 doc
: /* Return the largest integer no greater than ARG, as a float.
977 \(Round towards -inf.\) */)
979 register Lisp_Object arg
;
981 double d
= extract_float (arg
);
982 IN_FLOAT (d
= floor (d
), "ffloor", arg
);
983 return make_float (d
);
986 DEFUN ("fround", Ffround
, Sfround
, 1, 1, 0,
987 doc
: /* Return the nearest integer to ARG, as a float. */)
989 register Lisp_Object arg
;
991 double d
= extract_float (arg
);
992 IN_FLOAT (d
= emacs_rint (d
), "fround", arg
);
993 return make_float (d
);
996 DEFUN ("ftruncate", Fftruncate
, Sftruncate
, 1, 1, 0,
997 doc
: /* Truncate a floating point number to an integral float value.
998 Rounds the value toward zero. */)
1000 register Lisp_Object arg
;
1002 double d
= extract_float (arg
);
1004 IN_FLOAT (d
= floor (d
), "ftruncate", arg
);
1006 IN_FLOAT (d
= ceil (d
), "ftruncate", arg
);
1007 return make_float (d
);
1010 #ifdef FLOAT_CATCH_SIGILL
1016 fatal_error_signal (signo
);
1019 sigsetmask (SIGEMPTYMASK
);
1021 /* Must reestablish handler each time it is called. */
1022 signal (SIGILL
, float_error
);
1023 #endif /* BSD_SYSTEM */
1025 SIGNAL_THREAD_CHECK (signo
);
1028 xsignal1 (Qarith_error
, float_error_arg
);
1031 /* Another idea was to replace the library function `infnan'
1032 where SIGILL is signaled. */
1034 #endif /* FLOAT_CATCH_SIGILL */
1039 struct exception
*x
;
1043 /* Not called from emacs-lisp float routines; do the default thing. */
1045 if (!strcmp (x
->name
, "pow"))
1049 = Fcons (build_string (x
->name
),
1050 Fcons (make_float (x
->arg1
),
1051 ((!strcmp (x
->name
, "log") || !strcmp (x
->name
, "pow"))
1052 ? Fcons (make_float (x
->arg2
), Qnil
)
1056 case DOMAIN
: xsignal (Qdomain_error
, args
); break;
1057 case SING
: xsignal (Qsingularity_error
, args
); break;
1058 case OVERFLOW
: xsignal (Qoverflow_error
, args
); break;
1059 case UNDERFLOW
: xsignal (Qunderflow_error
, args
); break;
1060 default: xsignal (Qarith_error
, args
); break;
1062 return (1); /* don't set errno or print a message */
1064 #endif /* HAVE_MATHERR */
1069 #ifdef FLOAT_CATCH_SIGILL
1070 signal (SIGILL
, float_error
);
1084 #if defined HAVE_ISNAN && defined HAVE_COPYSIGN
1086 defsubr (&Scopysign
);
1097 defsubr (&Sbessel_y0
);
1098 defsubr (&Sbessel_y1
);
1099 defsubr (&Sbessel_yn
);
1100 defsubr (&Sbessel_j0
);
1101 defsubr (&Sbessel_j1
);
1102 defsubr (&Sbessel_jn
);
1105 defsubr (&Slog_gamma
);
1106 defsubr (&Scube_root
);
1108 defsubr (&Sfceiling
);
1111 defsubr (&Sftruncate
);
1121 defsubr (&Sceiling
);
1124 defsubr (&Struncate
);
1127 /* arch-tag: be05bf9d-049e-4e31-91b9-e6153d483ae7
1128 (do not change this comment) */