* floatfns.c (Ftan): Use tan (x), not (sin (x) / cos (x)).
[bpt/emacs.git] / src / floatfns.c
1 /* Primitive operations on floating point for GNU Emacs Lisp interpreter.
2
3 Copyright (C) 1988, 1993-1994, 1999, 2001-2012
4 Free Software Foundation, Inc.
5
6 Author: Wolfgang Rupprecht
7 (according to ack.texi)
8
9 This file is part of GNU Emacs.
10
11 GNU Emacs is free software: you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
15
16 GNU Emacs is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
23
24
25 /* ANSI C requires only these float functions:
26 acos, asin, atan, atan2, ceil, cos, cosh, exp, fabs, floor, fmod,
27 frexp, ldexp, log, log10, modf, pow, sin, sinh, sqrt, tan, tanh.
28
29 Define HAVE_INVERSE_HYPERBOLIC if you have acosh, asinh, and atanh.
30 Define HAVE_CBRT if you have cbrt.
31 Define HAVE_RINT if you have a working rint.
32 If you don't define these, then the appropriate routines will be simulated.
33
34 Define HAVE_MATHERR if on a system supporting the SysV matherr callback.
35 (This should happen automatically.)
36
37 Define FLOAT_CHECK_ERRNO if the float library routines set errno.
38 This has no effect if HAVE_MATHERR is defined.
39
40 Define FLOAT_CHECK_DOMAIN if the float library doesn't handle errors by
41 either setting errno, or signaling SIGFPE. Otherwise, domain and
42 range checking will happen before calling the float routines. This has
43 no effect if HAVE_MATHERR is defined (since matherr will be called when
44 a domain error occurs.)
45 */
46
47 #include <config.h>
48 #include <setjmp.h>
49 #include "lisp.h"
50 #include "syssignal.h"
51
52 #include <float.h>
53 /* If IEEE_FLOATING_POINT isn't defined, default it from FLT_*. */
54 #ifndef IEEE_FLOATING_POINT
55 #if (FLT_RADIX == 2 && FLT_MANT_DIG == 24 \
56 && FLT_MIN_EXP == -125 && FLT_MAX_EXP == 128)
57 #define IEEE_FLOATING_POINT 1
58 #else
59 #define IEEE_FLOATING_POINT 0
60 #endif
61 #endif
62
63 #include <math.h>
64
65 /* This declaration is omitted on some systems, like Ultrix. */
66 #if !defined (HPUX) && defined (HAVE_LOGB) && !defined (logb)
67 extern double logb (double);
68 #endif /* not HPUX and HAVE_LOGB and no logb macro */
69
70 #if defined (DOMAIN) && defined (SING) && defined (OVERFLOW)
71 /* If those are defined, then this is probably a `matherr' machine. */
72 # ifndef HAVE_MATHERR
73 # define HAVE_MATHERR
74 # endif
75 #endif
76
77 #ifdef NO_MATHERR
78 #undef HAVE_MATHERR
79 #endif
80
81 #ifdef HAVE_MATHERR
82 # ifdef FLOAT_CHECK_ERRNO
83 # undef FLOAT_CHECK_ERRNO
84 # endif
85 # ifdef FLOAT_CHECK_DOMAIN
86 # undef FLOAT_CHECK_DOMAIN
87 # endif
88 #endif
89
90 #ifndef NO_FLOAT_CHECK_ERRNO
91 #define FLOAT_CHECK_ERRNO
92 #endif
93
94 #ifdef FLOAT_CHECK_ERRNO
95 # include <errno.h>
96 #endif
97
98 /* True while executing in floating point.
99 This tells float_error what to do. */
100
101 static bool in_float;
102
103 /* If an argument is out of range for a mathematical function,
104 here is the actual argument value to use in the error message.
105 These variables are used only across the floating point library call
106 so there is no need to staticpro them. */
107
108 static Lisp_Object float_error_arg, float_error_arg2;
109
110 static const char *float_error_fn_name;
111
112 /* Evaluate the floating point expression D, recording NUM
113 as the original argument for error messages.
114 D is normally an assignment expression.
115 Handle errors which may result in signals or may set errno.
116
117 Note that float_error may be declared to return void, so you can't
118 just cast the zero after the colon to (void) to make the types
119 check properly. */
120
121 #ifdef FLOAT_CHECK_ERRNO
122 #define IN_FLOAT(d, name, num) \
123 do { \
124 float_error_arg = num; \
125 float_error_fn_name = name; \
126 in_float = 1; errno = 0; (d); in_float = 0; \
127 switch (errno) { \
128 case 0: break; \
129 case EDOM: domain_error (float_error_fn_name, float_error_arg); \
130 case ERANGE: range_error (float_error_fn_name, float_error_arg); \
131 default: arith_error (float_error_fn_name, float_error_arg); \
132 } \
133 } while (0)
134 #define IN_FLOAT2(d, name, num, num2) \
135 do { \
136 float_error_arg = num; \
137 float_error_arg2 = num2; \
138 float_error_fn_name = name; \
139 in_float = 1; errno = 0; (d); in_float = 0; \
140 switch (errno) { \
141 case 0: break; \
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); \
145 } \
146 } while (0)
147 #else
148 #define IN_FLOAT(d, name, num) (in_float = 1, (d), in_float = 0)
149 #define IN_FLOAT2(d, name, num, num2) (in_float = 1, (d), in_float = 0)
150 #endif
151
152 /* Convert float to Lisp_Int if it fits, else signal a range error
153 using the given arguments. */
154 #define FLOAT_TO_INT(x, i, name, num) \
155 do \
156 { \
157 if (FIXNUM_OVERFLOW_P (x)) \
158 range_error (name, num); \
159 XSETINT (i, (EMACS_INT)(x)); \
160 } \
161 while (0)
162 #define FLOAT_TO_INT2(x, i, name, num1, num2) \
163 do \
164 { \
165 if (FIXNUM_OVERFLOW_P (x)) \
166 range_error2 (name, num1, num2); \
167 XSETINT (i, (EMACS_INT)(x)); \
168 } \
169 while (0)
170
171 #define arith_error(op,arg) \
172 xsignal2 (Qarith_error, build_string ((op)), (arg))
173 #define range_error(op,arg) \
174 xsignal2 (Qrange_error, build_string ((op)), (arg))
175 #define range_error2(op,a1,a2) \
176 xsignal3 (Qrange_error, build_string ((op)), (a1), (a2))
177 #define domain_error(op,arg) \
178 xsignal2 (Qdomain_error, build_string ((op)), (arg))
179 #ifdef FLOAT_CHECK_DOMAIN
180 #define domain_error2(op,a1,a2) \
181 xsignal3 (Qdomain_error, build_string ((op)), (a1), (a2))
182 #endif
183
184 /* Extract a Lisp number as a `double', or signal an error. */
185
186 double
187 extract_float (Lisp_Object num)
188 {
189 CHECK_NUMBER_OR_FLOAT (num);
190
191 if (FLOATP (num))
192 return XFLOAT_DATA (num);
193 return (double) XINT (num);
194 }
195 \f
196 /* Trig functions. */
197
198 DEFUN ("acos", Facos, Sacos, 1, 1, 0,
199 doc: /* Return the inverse cosine of ARG. */)
200 (register Lisp_Object arg)
201 {
202 double d = extract_float (arg);
203 #ifdef FLOAT_CHECK_DOMAIN
204 if (d > 1.0 || d < -1.0)
205 domain_error ("acos", arg);
206 #endif
207 IN_FLOAT (d = acos (d), "acos", arg);
208 return make_float (d);
209 }
210
211 DEFUN ("asin", Fasin, Sasin, 1, 1, 0,
212 doc: /* Return the inverse sine of ARG. */)
213 (register Lisp_Object arg)
214 {
215 double d = extract_float (arg);
216 #ifdef FLOAT_CHECK_DOMAIN
217 if (d > 1.0 || d < -1.0)
218 domain_error ("asin", arg);
219 #endif
220 IN_FLOAT (d = asin (d), "asin", arg);
221 return make_float (d);
222 }
223
224 DEFUN ("atan", Fatan, Satan, 1, 2, 0,
225 doc: /* Return the inverse tangent of the arguments.
226 If only one argument Y is given, return the inverse tangent of Y.
227 If two arguments Y and X are given, return the inverse tangent of Y
228 divided by X, i.e. the angle in radians between the vector (X, Y)
229 and the x-axis. */)
230 (register Lisp_Object y, Lisp_Object x)
231 {
232 double d = extract_float (y);
233
234 if (NILP (x))
235 IN_FLOAT (d = atan (d), "atan", y);
236 else
237 {
238 double d2 = extract_float (x);
239
240 IN_FLOAT2 (d = atan2 (d, d2), "atan", y, x);
241 }
242 return make_float (d);
243 }
244
245 DEFUN ("cos", Fcos, Scos, 1, 1, 0,
246 doc: /* Return the cosine of ARG. */)
247 (register Lisp_Object arg)
248 {
249 double d = extract_float (arg);
250 IN_FLOAT (d = cos (d), "cos", arg);
251 return make_float (d);
252 }
253
254 DEFUN ("sin", Fsin, Ssin, 1, 1, 0,
255 doc: /* Return the sine of ARG. */)
256 (register Lisp_Object arg)
257 {
258 double d = extract_float (arg);
259 IN_FLOAT (d = sin (d), "sin", arg);
260 return make_float (d);
261 }
262
263 DEFUN ("tan", Ftan, Stan, 1, 1, 0,
264 doc: /* Return the tangent of ARG. */)
265 (register Lisp_Object arg)
266 {
267 double d = extract_float (arg);
268 #ifdef FLOAT_CHECK_DOMAIN
269 double c = cos (d);
270 if (c == 0.0)
271 domain_error ("tan", arg);
272 #endif
273 IN_FLOAT (d = tan (d), "tan", arg);
274 return make_float (d);
275 }
276
277 #undef isnan
278 #define isnan(x) ((x) != (x))
279
280 DEFUN ("isnan", Fisnan, Sisnan, 1, 1, 0,
281 doc: /* Return non nil iff argument X is a NaN. */)
282 (Lisp_Object x)
283 {
284 CHECK_FLOAT (x);
285 return isnan (XFLOAT_DATA (x)) ? Qt : Qnil;
286 }
287
288 #ifdef HAVE_COPYSIGN
289 DEFUN ("copysign", Fcopysign, Scopysign, 2, 2, 0,
290 doc: /* Copy sign of X2 to value of X1, and return the result.
291 Cause an error if X1 or X2 is not a float. */)
292 (Lisp_Object x1, Lisp_Object x2)
293 {
294 double f1, f2;
295
296 CHECK_FLOAT (x1);
297 CHECK_FLOAT (x2);
298
299 f1 = XFLOAT_DATA (x1);
300 f2 = XFLOAT_DATA (x2);
301
302 return make_float (copysign (f1, f2));
303 }
304
305 DEFUN ("frexp", Ffrexp, Sfrexp, 1, 1, 0,
306 doc: /* Get significand and exponent of a floating point number.
307 Breaks the floating point number X into its binary significand SGNFCAND
308 \(a floating point value between 0.5 (included) and 1.0 (excluded))
309 and an integral exponent EXP for 2, such that:
310
311 X = SGNFCAND * 2^EXP
312
313 The function returns the cons cell (SGNFCAND . EXP).
314 If X is zero, both parts (SGNFCAND and EXP) are zero. */)
315 (Lisp_Object x)
316 {
317 double f = XFLOATINT (x);
318
319 if (f == 0.0)
320 return Fcons (make_float (0.0), make_number (0));
321 else
322 {
323 int exponent;
324 double sgnfcand = frexp (f, &exponent);
325 return Fcons (make_float (sgnfcand), make_number (exponent));
326 }
327 }
328
329 DEFUN ("ldexp", Fldexp, Sldexp, 1, 2, 0,
330 doc: /* Construct number X from significand SGNFCAND and exponent EXP.
331 Returns the floating point value resulting from multiplying SGNFCAND
332 (the significand) by 2 raised to the power of EXP (the exponent). */)
333 (Lisp_Object sgnfcand, Lisp_Object exponent)
334 {
335 CHECK_NUMBER (exponent);
336 return make_float (ldexp (XFLOATINT (sgnfcand), XINT (exponent)));
337 }
338 #endif
339 \f
340 #if 0 /* Leave these out unless we find there's a reason for them. */
341
342 DEFUN ("bessel-j0", Fbessel_j0, Sbessel_j0, 1, 1, 0,
343 doc: /* Return the bessel function j0 of ARG. */)
344 (register Lisp_Object arg)
345 {
346 double d = extract_float (arg);
347 IN_FLOAT (d = j0 (d), "bessel-j0", arg);
348 return make_float (d);
349 }
350
351 DEFUN ("bessel-j1", Fbessel_j1, Sbessel_j1, 1, 1, 0,
352 doc: /* Return the bessel function j1 of ARG. */)
353 (register Lisp_Object arg)
354 {
355 double d = extract_float (arg);
356 IN_FLOAT (d = j1 (d), "bessel-j1", arg);
357 return make_float (d);
358 }
359
360 DEFUN ("bessel-jn", Fbessel_jn, Sbessel_jn, 2, 2, 0,
361 doc: /* Return the order N bessel function output jn of ARG.
362 The first arg (the order) is truncated to an integer. */)
363 (register Lisp_Object n, Lisp_Object arg)
364 {
365 int i1 = extract_float (n);
366 double f2 = extract_float (arg);
367
368 IN_FLOAT (f2 = jn (i1, f2), "bessel-jn", n);
369 return make_float (f2);
370 }
371
372 DEFUN ("bessel-y0", Fbessel_y0, Sbessel_y0, 1, 1, 0,
373 doc: /* Return the bessel function y0 of ARG. */)
374 (register Lisp_Object arg)
375 {
376 double d = extract_float (arg);
377 IN_FLOAT (d = y0 (d), "bessel-y0", arg);
378 return make_float (d);
379 }
380
381 DEFUN ("bessel-y1", Fbessel_y1, Sbessel_y1, 1, 1, 0,
382 doc: /* Return the bessel function y1 of ARG. */)
383 (register Lisp_Object arg)
384 {
385 double d = extract_float (arg);
386 IN_FLOAT (d = y1 (d), "bessel-y0", arg);
387 return make_float (d);
388 }
389
390 DEFUN ("bessel-yn", Fbessel_yn, Sbessel_yn, 2, 2, 0,
391 doc: /* Return the order N bessel function output yn of ARG.
392 The first arg (the order) is truncated to an integer. */)
393 (register Lisp_Object n, Lisp_Object arg)
394 {
395 int i1 = extract_float (n);
396 double f2 = extract_float (arg);
397
398 IN_FLOAT (f2 = yn (i1, f2), "bessel-yn", n);
399 return make_float (f2);
400 }
401
402 #endif
403 \f
404 #if 0 /* Leave these out unless we see they are worth having. */
405
406 DEFUN ("erf", Ferf, Serf, 1, 1, 0,
407 doc: /* Return the mathematical error function of ARG. */)
408 (register Lisp_Object arg)
409 {
410 double d = extract_float (arg);
411 IN_FLOAT (d = erf (d), "erf", arg);
412 return make_float (d);
413 }
414
415 DEFUN ("erfc", Ferfc, Serfc, 1, 1, 0,
416 doc: /* Return the complementary error function of ARG. */)
417 (register Lisp_Object arg)
418 {
419 double d = extract_float (arg);
420 IN_FLOAT (d = erfc (d), "erfc", arg);
421 return make_float (d);
422 }
423
424 DEFUN ("log-gamma", Flog_gamma, Slog_gamma, 1, 1, 0,
425 doc: /* Return the log gamma of ARG. */)
426 (register Lisp_Object arg)
427 {
428 double d = extract_float (arg);
429 IN_FLOAT (d = lgamma (d), "log-gamma", arg);
430 return make_float (d);
431 }
432
433 DEFUN ("cube-root", Fcube_root, Scube_root, 1, 1, 0,
434 doc: /* Return the cube root of ARG. */)
435 (register Lisp_Object arg)
436 {
437 double d = extract_float (arg);
438 #ifdef HAVE_CBRT
439 IN_FLOAT (d = cbrt (d), "cube-root", arg);
440 #else
441 if (d >= 0.0)
442 IN_FLOAT (d = pow (d, 1.0/3.0), "cube-root", arg);
443 else
444 IN_FLOAT (d = -pow (-d, 1.0/3.0), "cube-root", arg);
445 #endif
446 return make_float (d);
447 }
448
449 #endif
450 \f
451 DEFUN ("exp", Fexp, Sexp, 1, 1, 0,
452 doc: /* Return the exponential base e of ARG. */)
453 (register Lisp_Object arg)
454 {
455 double d = extract_float (arg);
456 #ifdef FLOAT_CHECK_DOMAIN
457 if (d > 709.7827) /* Assume IEEE doubles here */
458 range_error ("exp", arg);
459 else if (d < -709.0)
460 return make_float (0.0);
461 else
462 #endif
463 IN_FLOAT (d = exp (d), "exp", arg);
464 return make_float (d);
465 }
466
467 DEFUN ("expt", Fexpt, Sexpt, 2, 2, 0,
468 doc: /* Return the exponential ARG1 ** ARG2. */)
469 (register Lisp_Object arg1, Lisp_Object arg2)
470 {
471 double f1, f2, f3;
472
473 CHECK_NUMBER_OR_FLOAT (arg1);
474 CHECK_NUMBER_OR_FLOAT (arg2);
475 if (INTEGERP (arg1) /* common lisp spec */
476 && INTEGERP (arg2) /* don't promote, if both are ints, and */
477 && 0 <= XINT (arg2)) /* we are sure the result is not fractional */
478 { /* this can be improved by pre-calculating */
479 EMACS_INT y; /* some binary powers of x then accumulating */
480 EMACS_UINT acc, x; /* Unsigned so that overflow is well defined. */
481 Lisp_Object val;
482
483 x = XINT (arg1);
484 y = XINT (arg2);
485 acc = (y & 1 ? x : 1);
486
487 while ((y >>= 1) != 0)
488 {
489 x *= x;
490 if (y & 1)
491 acc *= x;
492 }
493 XSETINT (val, acc);
494 return val;
495 }
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)
500 f1 = 1.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);
504 #endif
505 IN_FLOAT2 (f3 = pow (f1, f2), "expt", arg1, arg2);
506 /* Check for overflow in the result. */
507 if (f1 != 0.0 && f3 == 0.0)
508 range_error ("expt", arg1);
509 return make_float (f3);
510 }
511
512 DEFUN ("log", Flog, Slog, 1, 2, 0,
513 doc: /* Return the natural logarithm of ARG.
514 If the optional argument BASE is given, return log ARG using that base. */)
515 (register Lisp_Object arg, Lisp_Object base)
516 {
517 double d = extract_float (arg);
518
519 #ifdef FLOAT_CHECK_DOMAIN
520 if (d <= 0.0)
521 domain_error2 ("log", arg, base);
522 #endif
523 if (NILP (base))
524 IN_FLOAT (d = log (d), "log", arg);
525 else
526 {
527 double b = extract_float (base);
528
529 #ifdef FLOAT_CHECK_DOMAIN
530 if (b <= 0.0 || b == 1.0)
531 domain_error2 ("log", arg, base);
532 #endif
533 if (b == 10.0)
534 IN_FLOAT2 (d = log10 (d), "log", arg, base);
535 else
536 IN_FLOAT2 (d = log (d) / log (b), "log", arg, base);
537 }
538 return make_float (d);
539 }
540
541 DEFUN ("log10", Flog10, Slog10, 1, 1, 0,
542 doc: /* Return the logarithm base 10 of ARG. */)
543 (register Lisp_Object arg)
544 {
545 double d = extract_float (arg);
546 #ifdef FLOAT_CHECK_DOMAIN
547 if (d <= 0.0)
548 domain_error ("log10", arg);
549 #endif
550 IN_FLOAT (d = log10 (d), "log10", arg);
551 return make_float (d);
552 }
553
554 DEFUN ("sqrt", Fsqrt, Ssqrt, 1, 1, 0,
555 doc: /* Return the square root of ARG. */)
556 (register Lisp_Object arg)
557 {
558 double d = extract_float (arg);
559 #ifdef FLOAT_CHECK_DOMAIN
560 if (d < 0.0)
561 domain_error ("sqrt", arg);
562 #endif
563 IN_FLOAT (d = sqrt (d), "sqrt", arg);
564 return make_float (d);
565 }
566 \f
567 #if 0 /* Not clearly worth adding. */
568
569 DEFUN ("acosh", Facosh, Sacosh, 1, 1, 0,
570 doc: /* Return the inverse hyperbolic cosine of ARG. */)
571 (register Lisp_Object arg)
572 {
573 double d = extract_float (arg);
574 #ifdef FLOAT_CHECK_DOMAIN
575 if (d < 1.0)
576 domain_error ("acosh", arg);
577 #endif
578 #ifdef HAVE_INVERSE_HYPERBOLIC
579 IN_FLOAT (d = acosh (d), "acosh", arg);
580 #else
581 IN_FLOAT (d = log (d + sqrt (d*d - 1.0)), "acosh", arg);
582 #endif
583 return make_float (d);
584 }
585
586 DEFUN ("asinh", Fasinh, Sasinh, 1, 1, 0,
587 doc: /* Return the inverse hyperbolic sine of ARG. */)
588 (register Lisp_Object arg)
589 {
590 double d = extract_float (arg);
591 #ifdef HAVE_INVERSE_HYPERBOLIC
592 IN_FLOAT (d = asinh (d), "asinh", arg);
593 #else
594 IN_FLOAT (d = log (d + sqrt (d*d + 1.0)), "asinh", arg);
595 #endif
596 return make_float (d);
597 }
598
599 DEFUN ("atanh", Fatanh, Satanh, 1, 1, 0,
600 doc: /* Return the inverse hyperbolic tangent of ARG. */)
601 (register Lisp_Object arg)
602 {
603 double d = extract_float (arg);
604 #ifdef FLOAT_CHECK_DOMAIN
605 if (d >= 1.0 || d <= -1.0)
606 domain_error ("atanh", arg);
607 #endif
608 #ifdef HAVE_INVERSE_HYPERBOLIC
609 IN_FLOAT (d = atanh (d), "atanh", arg);
610 #else
611 IN_FLOAT (d = 0.5 * log ((1.0 + d) / (1.0 - d)), "atanh", arg);
612 #endif
613 return make_float (d);
614 }
615
616 DEFUN ("cosh", Fcosh, Scosh, 1, 1, 0,
617 doc: /* Return the hyperbolic cosine of ARG. */)
618 (register Lisp_Object arg)
619 {
620 double d = extract_float (arg);
621 #ifdef FLOAT_CHECK_DOMAIN
622 if (d > 710.0 || d < -710.0)
623 range_error ("cosh", arg);
624 #endif
625 IN_FLOAT (d = cosh (d), "cosh", arg);
626 return make_float (d);
627 }
628
629 DEFUN ("sinh", Fsinh, Ssinh, 1, 1, 0,
630 doc: /* Return the hyperbolic sine of ARG. */)
631 (register Lisp_Object arg)
632 {
633 double d = extract_float (arg);
634 #ifdef FLOAT_CHECK_DOMAIN
635 if (d > 710.0 || d < -710.0)
636 range_error ("sinh", arg);
637 #endif
638 IN_FLOAT (d = sinh (d), "sinh", arg);
639 return make_float (d);
640 }
641
642 DEFUN ("tanh", Ftanh, Stanh, 1, 1, 0,
643 doc: /* Return the hyperbolic tangent of ARG. */)
644 (register Lisp_Object arg)
645 {
646 double d = extract_float (arg);
647 IN_FLOAT (d = tanh (d), "tanh", arg);
648 return make_float (d);
649 }
650 #endif
651 \f
652 DEFUN ("abs", Fabs, Sabs, 1, 1, 0,
653 doc: /* Return the absolute value of ARG. */)
654 (register Lisp_Object arg)
655 {
656 CHECK_NUMBER_OR_FLOAT (arg);
657
658 if (FLOATP (arg))
659 arg = make_float (fabs (XFLOAT_DATA (arg)));
660 else if (XINT (arg) < 0)
661 XSETINT (arg, - XINT (arg));
662
663 return arg;
664 }
665
666 DEFUN ("float", Ffloat, Sfloat, 1, 1, 0,
667 doc: /* Return the floating point number equal to ARG. */)
668 (register Lisp_Object arg)
669 {
670 CHECK_NUMBER_OR_FLOAT (arg);
671
672 if (INTEGERP (arg))
673 return make_float ((double) XINT (arg));
674 else /* give 'em the same float back */
675 return arg;
676 }
677
678 DEFUN ("logb", Flogb, Slogb, 1, 1, 0,
679 doc: /* Returns largest integer <= the base 2 log of the magnitude of ARG.
680 This is the same as the exponent of a float. */)
681 (Lisp_Object arg)
682 {
683 Lisp_Object val;
684 EMACS_INT value;
685 double f = extract_float (arg);
686
687 if (f == 0.0)
688 value = MOST_NEGATIVE_FIXNUM;
689 else
690 {
691 #ifdef HAVE_LOGB
692 IN_FLOAT (value = logb (f), "logb", arg);
693 #else
694 #ifdef HAVE_FREXP
695 int ivalue;
696 IN_FLOAT (frexp (f, &ivalue), "logb", arg);
697 value = ivalue - 1;
698 #else
699 int i;
700 double d;
701 if (f < 0.0)
702 f = -f;
703 value = -1;
704 while (f < 0.5)
705 {
706 for (i = 1, d = 0.5; d * d >= f; i += i)
707 d *= d;
708 f /= d;
709 value -= i;
710 }
711 while (f >= 1.0)
712 {
713 for (i = 1, d = 2.0; d * d <= f; i += i)
714 d *= d;
715 f /= d;
716 value += i;
717 }
718 #endif
719 #endif
720 }
721 XSETINT (val, value);
722 return val;
723 }
724
725
726 /* the rounding functions */
727
728 static Lisp_Object
729 rounding_driver (Lisp_Object arg, Lisp_Object divisor,
730 double (*double_round) (double),
731 EMACS_INT (*int_round2) (EMACS_INT, EMACS_INT),
732 const char *name)
733 {
734 CHECK_NUMBER_OR_FLOAT (arg);
735
736 if (! NILP (divisor))
737 {
738 EMACS_INT i1, i2;
739
740 CHECK_NUMBER_OR_FLOAT (divisor);
741
742 if (FLOATP (arg) || FLOATP (divisor))
743 {
744 double f1, f2;
745
746 f1 = FLOATP (arg) ? XFLOAT_DATA (arg) : XINT (arg);
747 f2 = (FLOATP (divisor) ? XFLOAT_DATA (divisor) : XINT (divisor));
748 if (! IEEE_FLOATING_POINT && f2 == 0)
749 xsignal0 (Qarith_error);
750
751 IN_FLOAT2 (f1 = (*double_round) (f1 / f2), name, arg, divisor);
752 FLOAT_TO_INT2 (f1, arg, name, arg, divisor);
753 return arg;
754 }
755
756 i1 = XINT (arg);
757 i2 = XINT (divisor);
758
759 if (i2 == 0)
760 xsignal0 (Qarith_error);
761
762 XSETINT (arg, (*int_round2) (i1, i2));
763 return arg;
764 }
765
766 if (FLOATP (arg))
767 {
768 double d;
769
770 IN_FLOAT (d = (*double_round) (XFLOAT_DATA (arg)), name, arg);
771 FLOAT_TO_INT (d, arg, name, arg);
772 }
773
774 return arg;
775 }
776
777 /* With C's /, the result is implementation-defined if either operand
778 is negative, so take care with negative operands in the following
779 integer functions. */
780
781 static EMACS_INT
782 ceiling2 (EMACS_INT i1, EMACS_INT i2)
783 {
784 return (i2 < 0
785 ? (i1 < 0 ? ((-1 - i1) / -i2) + 1 : - (i1 / -i2))
786 : (i1 <= 0 ? - (-i1 / i2) : ((i1 - 1) / i2) + 1));
787 }
788
789 static EMACS_INT
790 floor2 (EMACS_INT i1, EMACS_INT i2)
791 {
792 return (i2 < 0
793 ? (i1 <= 0 ? -i1 / -i2 : -1 - ((i1 - 1) / -i2))
794 : (i1 < 0 ? -1 - ((-1 - i1) / i2) : i1 / i2));
795 }
796
797 static EMACS_INT
798 truncate2 (EMACS_INT i1, EMACS_INT i2)
799 {
800 return (i2 < 0
801 ? (i1 < 0 ? -i1 / -i2 : - (i1 / -i2))
802 : (i1 < 0 ? - (-i1 / i2) : i1 / i2));
803 }
804
805 static EMACS_INT
806 round2 (EMACS_INT i1, EMACS_INT i2)
807 {
808 /* The C language's division operator gives us one remainder R, but
809 we want the remainder R1 on the other side of 0 if R1 is closer
810 to 0 than R is; because we want to round to even, we also want R1
811 if R and R1 are the same distance from 0 and if C's quotient is
812 odd. */
813 EMACS_INT q = i1 / i2;
814 EMACS_INT r = i1 % i2;
815 EMACS_INT abs_r = r < 0 ? -r : r;
816 EMACS_INT abs_r1 = (i2 < 0 ? -i2 : i2) - abs_r;
817 return q + (abs_r + (q & 1) <= abs_r1 ? 0 : (i2 ^ r) < 0 ? -1 : 1);
818 }
819
820 /* The code uses emacs_rint, so that it works to undefine HAVE_RINT
821 if `rint' exists but does not work right. */
822 #ifdef HAVE_RINT
823 #define emacs_rint rint
824 #else
825 static double
826 emacs_rint (double d)
827 {
828 return floor (d + 0.5);
829 }
830 #endif
831
832 static double
833 double_identity (double d)
834 {
835 return d;
836 }
837
838 DEFUN ("ceiling", Fceiling, Sceiling, 1, 2, 0,
839 doc: /* Return the smallest integer no less than ARG.
840 This rounds the value towards +inf.
841 With optional DIVISOR, return the smallest integer no less than ARG/DIVISOR. */)
842 (Lisp_Object arg, Lisp_Object divisor)
843 {
844 return rounding_driver (arg, divisor, ceil, ceiling2, "ceiling");
845 }
846
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. */)
851 (Lisp_Object arg, Lisp_Object divisor)
852 {
853 return rounding_driver (arg, divisor, floor, floor2, "floor");
854 }
855
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.
859
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. */)
864 (Lisp_Object arg, Lisp_Object divisor)
865 {
866 return rounding_driver (arg, divisor, emacs_rint, round2, "round");
867 }
868
869 DEFUN ("truncate", Ftruncate, Struncate, 1, 2, 0,
870 doc: /* Truncate a floating point number to an int.
871 Rounds ARG toward zero.
872 With optional DIVISOR, truncate ARG/DIVISOR. */)
873 (Lisp_Object arg, Lisp_Object divisor)
874 {
875 return rounding_driver (arg, divisor, double_identity, truncate2,
876 "truncate");
877 }
878
879
880 Lisp_Object
881 fmod_float (Lisp_Object x, Lisp_Object y)
882 {
883 double f1, f2;
884
885 f1 = FLOATP (x) ? XFLOAT_DATA (x) : XINT (x);
886 f2 = FLOATP (y) ? XFLOAT_DATA (y) : XINT (y);
887
888 if (! IEEE_FLOATING_POINT && f2 == 0)
889 xsignal0 (Qarith_error);
890
891 /* If the "remainder" comes out with the wrong sign, fix it. */
892 IN_FLOAT2 ((f1 = fmod (f1, f2),
893 f1 = (f2 < 0 ? f1 > 0 : f1 < 0) ? f1 + f2 : f1),
894 "mod", x, y);
895 return make_float (f1);
896 }
897 \f
898 /* It's not clear these are worth adding. */
899
900 DEFUN ("fceiling", Ffceiling, Sfceiling, 1, 1, 0,
901 doc: /* Return the smallest integer no less than ARG, as a float.
902 \(Round toward +inf.\) */)
903 (register Lisp_Object arg)
904 {
905 double d = extract_float (arg);
906 IN_FLOAT (d = ceil (d), "fceiling", arg);
907 return make_float (d);
908 }
909
910 DEFUN ("ffloor", Fffloor, Sffloor, 1, 1, 0,
911 doc: /* Return the largest integer no greater than ARG, as a float.
912 \(Round towards -inf.\) */)
913 (register Lisp_Object arg)
914 {
915 double d = extract_float (arg);
916 IN_FLOAT (d = floor (d), "ffloor", arg);
917 return make_float (d);
918 }
919
920 DEFUN ("fround", Ffround, Sfround, 1, 1, 0,
921 doc: /* Return the nearest integer to ARG, as a float. */)
922 (register Lisp_Object arg)
923 {
924 double d = extract_float (arg);
925 IN_FLOAT (d = emacs_rint (d), "fround", arg);
926 return make_float (d);
927 }
928
929 DEFUN ("ftruncate", Fftruncate, Sftruncate, 1, 1, 0,
930 doc: /* Truncate a floating point number to an integral float value.
931 Rounds the value toward zero. */)
932 (register Lisp_Object arg)
933 {
934 double d = extract_float (arg);
935 if (d >= 0.0)
936 IN_FLOAT (d = floor (d), "ftruncate", arg);
937 else
938 IN_FLOAT (d = ceil (d), "ftruncate", arg);
939 return make_float (d);
940 }
941 \f
942 #ifdef HAVE_MATHERR
943 int
944 matherr (struct exception *x)
945 {
946 Lisp_Object args;
947 const char *name = x->name;
948
949 if (! in_float)
950 /* Not called from emacs-lisp float routines; do the default thing. */
951 return 0;
952 if (!strcmp (x->name, "pow"))
953 name = "expt";
954
955 args
956 = Fcons (build_string (name),
957 Fcons (make_float (x->arg1),
958 ((!strcmp (name, "log") || !strcmp (name, "pow"))
959 ? Fcons (make_float (x->arg2), Qnil)
960 : Qnil)));
961 switch (x->type)
962 {
963 case DOMAIN: xsignal (Qdomain_error, args); break;
964 case SING: xsignal (Qsingularity_error, args); break;
965 case OVERFLOW: xsignal (Qoverflow_error, args); break;
966 case UNDERFLOW: xsignal (Qunderflow_error, args); break;
967 default: xsignal (Qarith_error, args); break;
968 }
969 return (1); /* don't set errno or print a message */
970 }
971 #endif /* HAVE_MATHERR */
972
973 void
974 init_floatfns (void)
975 {
976 in_float = 0;
977 }
978
979 void
980 syms_of_floatfns (void)
981 {
982 defsubr (&Sacos);
983 defsubr (&Sasin);
984 defsubr (&Satan);
985 defsubr (&Scos);
986 defsubr (&Ssin);
987 defsubr (&Stan);
988 defsubr (&Sisnan);
989 #ifdef HAVE_COPYSIGN
990 defsubr (&Scopysign);
991 defsubr (&Sfrexp);
992 defsubr (&Sldexp);
993 #endif
994 #if 0
995 defsubr (&Sacosh);
996 defsubr (&Sasinh);
997 defsubr (&Satanh);
998 defsubr (&Scosh);
999 defsubr (&Ssinh);
1000 defsubr (&Stanh);
1001 defsubr (&Sbessel_y0);
1002 defsubr (&Sbessel_y1);
1003 defsubr (&Sbessel_yn);
1004 defsubr (&Sbessel_j0);
1005 defsubr (&Sbessel_j1);
1006 defsubr (&Sbessel_jn);
1007 defsubr (&Serf);
1008 defsubr (&Serfc);
1009 defsubr (&Slog_gamma);
1010 defsubr (&Scube_root);
1011 #endif
1012 defsubr (&Sfceiling);
1013 defsubr (&Sffloor);
1014 defsubr (&Sfround);
1015 defsubr (&Sftruncate);
1016 defsubr (&Sexp);
1017 defsubr (&Sexpt);
1018 defsubr (&Slog);
1019 defsubr (&Slog10);
1020 defsubr (&Ssqrt);
1021
1022 defsubr (&Sabs);
1023 defsubr (&Sfloat);
1024 defsubr (&Slogb);
1025 defsubr (&Sceiling);
1026 defsubr (&Sfloor);
1027 defsubr (&Sround);
1028 defsubr (&Struncate);
1029 }