1 /* Primitive operations on floating point for GNU Emacs Lisp interpreter.
3 Copyright (C) 1988, 1993-1994, 1999, 2001-2012
4 Free Software Foundation, Inc.
6 Author: Wolfgang Rupprecht
7 (according to ack.texi)
9 This file is part of GNU Emacs.
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.
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.
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/>. */
25 /* C89 requires only these math.h 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.
33 #include "syssignal.h"
36 #if (FLT_RADIX == 2 && FLT_MANT_DIG == 24 \
37 && FLT_MIN_EXP == -125 && FLT_MAX_EXP == 128)
38 #define IEEE_FLOATING_POINT 1
40 #define IEEE_FLOATING_POINT 0
45 /* This declaration is omitted on some systems, like Ultrix. */
46 #if !defined (HPUX) && defined (HAVE_LOGB) && !defined (logb)
47 extern double logb (double);
48 #endif /* not HPUX and HAVE_LOGB and no logb macro */
50 /* Extract a Lisp number as a `double', or signal an error. */
53 extract_float (Lisp_Object num
)
55 CHECK_NUMBER_OR_FLOAT (num
);
58 return XFLOAT_DATA (num
);
59 return (double) XINT (num
);
64 DEFUN ("acos", Facos
, Sacos
, 1, 1, 0,
65 doc
: /* Return the inverse cosine of ARG. */)
68 double d
= extract_float (arg
);
70 return make_float (d
);
73 DEFUN ("asin", Fasin
, Sasin
, 1, 1, 0,
74 doc
: /* Return the inverse sine of ARG. */)
77 double d
= extract_float (arg
);
79 return make_float (d
);
82 DEFUN ("atan", Fatan
, Satan
, 1, 2, 0,
83 doc
: /* Return the inverse tangent of the arguments.
84 If only one argument Y is given, return the inverse tangent of Y.
85 If two arguments Y and X are given, return the inverse tangent of Y
86 divided by X, i.e. the angle in radians between the vector (X, Y)
88 (Lisp_Object y
, Lisp_Object x
)
90 double d
= extract_float (y
);
96 double d2
= extract_float (x
);
99 return make_float (d
);
102 DEFUN ("cos", Fcos
, Scos
, 1, 1, 0,
103 doc
: /* Return the cosine of ARG. */)
106 double d
= extract_float (arg
);
108 return make_float (d
);
111 DEFUN ("sin", Fsin
, Ssin
, 1, 1, 0,
112 doc
: /* Return the sine of ARG. */)
115 double d
= extract_float (arg
);
117 return make_float (d
);
120 DEFUN ("tan", Ftan
, Stan
, 1, 1, 0,
121 doc
: /* Return the tangent of ARG. */)
124 double d
= extract_float (arg
);
126 return make_float (d
);
130 #define isnan(x) ((x) != (x))
132 DEFUN ("isnan", Fisnan
, Sisnan
, 1, 1, 0,
133 doc
: /* Return non nil iff argument X is a NaN. */)
137 return isnan (XFLOAT_DATA (x
)) ? Qt
: Qnil
;
141 DEFUN ("copysign", Fcopysign
, Scopysign
, 2, 2, 0,
142 doc
: /* Copy sign of X2 to value of X1, and return the result.
143 Cause an error if X1 or X2 is not a float. */)
144 (Lisp_Object x1
, Lisp_Object x2
)
151 f1
= XFLOAT_DATA (x1
);
152 f2
= XFLOAT_DATA (x2
);
154 return make_float (copysign (f1
, f2
));
157 DEFUN ("frexp", Ffrexp
, Sfrexp
, 1, 1, 0,
158 doc
: /* Get significand and exponent of a floating point number.
159 Breaks the floating point number X into its binary significand SGNFCAND
160 \(a floating point value between 0.5 (included) and 1.0 (excluded))
161 and an integral exponent EXP for 2, such that:
165 The function returns the cons cell (SGNFCAND . EXP).
166 If X is zero, both parts (SGNFCAND and EXP) are zero. */)
169 double f
= XFLOATINT (x
);
172 return Fcons (make_float (0.0), make_number (0));
176 double sgnfcand
= frexp (f
, &exponent
);
177 return Fcons (make_float (sgnfcand
), make_number (exponent
));
181 DEFUN ("ldexp", Fldexp
, Sldexp
, 1, 2, 0,
182 doc
: /* Construct number X from significand SGNFCAND and exponent EXP.
183 Returns the floating point value resulting from multiplying SGNFCAND
184 (the significand) by 2 raised to the power of EXP (the exponent). */)
185 (Lisp_Object sgnfcand
, Lisp_Object exponent
)
187 CHECK_NUMBER (exponent
);
188 return make_float (ldexp (XFLOATINT (sgnfcand
), XINT (exponent
)));
192 #if 0 /* Leave these out unless we find there's a reason for them. */
194 DEFUN ("bessel-j0", Fbessel_j0
, Sbessel_j0
, 1, 1, 0,
195 doc
: /* Return the bessel function j0 of ARG. */)
198 double d
= extract_float (arg
);
200 return make_float (d
);
203 DEFUN ("bessel-j1", Fbessel_j1
, Sbessel_j1
, 1, 1, 0,
204 doc
: /* Return the bessel function j1 of ARG. */)
207 double d
= extract_float (arg
);
209 return make_float (d
);
212 DEFUN ("bessel-jn", Fbessel_jn
, Sbessel_jn
, 2, 2, 0,
213 doc
: /* Return the order N bessel function output jn of ARG.
214 The first arg (the order) is truncated to an integer. */)
215 (Lisp_Object n
, Lisp_Object arg
)
217 int i1
= extract_float (n
);
218 double f2
= extract_float (arg
);
221 return make_float (f2
);
224 DEFUN ("bessel-y0", Fbessel_y0
, Sbessel_y0
, 1, 1, 0,
225 doc
: /* Return the bessel function y0 of ARG. */)
228 double d
= extract_float (arg
);
230 return make_float (d
);
233 DEFUN ("bessel-y1", Fbessel_y1
, Sbessel_y1
, 1, 1, 0,
234 doc
: /* Return the bessel function y1 of ARG. */)
237 double d
= extract_float (arg
);
239 return make_float (d
);
242 DEFUN ("bessel-yn", Fbessel_yn
, Sbessel_yn
, 2, 2, 0,
243 doc
: /* Return the order N bessel function output yn of ARG.
244 The first arg (the order) is truncated to an integer. */)
245 (Lisp_Object n
, Lisp_Object arg
)
247 int i1
= extract_float (n
);
248 double f2
= extract_float (arg
);
251 return make_float (f2
);
256 #if 0 /* Leave these out unless we see they are worth having. */
258 DEFUN ("erf", Ferf
, Serf
, 1, 1, 0,
259 doc
: /* Return the mathematical error function of ARG. */)
262 double d
= extract_float (arg
);
264 return make_float (d
);
267 DEFUN ("erfc", Ferfc
, Serfc
, 1, 1, 0,
268 doc
: /* Return the complementary error function of ARG. */)
271 double d
= extract_float (arg
);
273 return make_float (d
);
276 DEFUN ("log-gamma", Flog_gamma
, Slog_gamma
, 1, 1, 0,
277 doc
: /* Return the log gamma of ARG. */)
280 double d
= extract_float (arg
);
282 return make_float (d
);
285 DEFUN ("cube-root", Fcube_root
, Scube_root
, 1, 1, 0,
286 doc
: /* Return the cube root of ARG. */)
289 double d
= extract_float (arg
);
294 d
= pow (d
, 1.0/3.0);
296 d
= -pow (-d
, 1.0/3.0);
298 return make_float (d
);
303 DEFUN ("exp", Fexp
, Sexp
, 1, 1, 0,
304 doc
: /* Return the exponential base e of ARG. */)
307 double d
= extract_float (arg
);
309 return make_float (d
);
312 DEFUN ("expt", Fexpt
, Sexpt
, 2, 2, 0,
313 doc
: /* Return the exponential ARG1 ** ARG2. */)
314 (Lisp_Object arg1
, Lisp_Object arg2
)
318 CHECK_NUMBER_OR_FLOAT (arg1
);
319 CHECK_NUMBER_OR_FLOAT (arg2
);
320 if (INTEGERP (arg1
) /* common lisp spec */
321 && INTEGERP (arg2
) /* don't promote, if both are ints, and */
322 && 0 <= XINT (arg2
)) /* we are sure the result is not fractional */
323 { /* this can be improved by pre-calculating */
324 EMACS_INT y
; /* some binary powers of x then accumulating */
325 EMACS_UINT acc
, x
; /* Unsigned so that overflow is well defined. */
330 acc
= (y
& 1 ? x
: 1);
332 while ((y
>>= 1) != 0)
341 f1
= FLOATP (arg1
) ? XFLOAT_DATA (arg1
) : XINT (arg1
);
342 f2
= FLOATP (arg2
) ? XFLOAT_DATA (arg2
) : XINT (arg2
);
344 return make_float (f3
);
347 DEFUN ("log", Flog
, Slog
, 1, 2, 0,
348 doc
: /* Return the natural logarithm of ARG.
349 If the optional argument BASE is given, return log ARG using that base. */)
350 (Lisp_Object arg
, Lisp_Object base
)
352 double d
= extract_float (arg
);
358 double b
= extract_float (base
);
363 d
= log (d
) / log (b
);
365 return make_float (d
);
368 DEFUN ("log10", Flog10
, Slog10
, 1, 1, 0,
369 doc
: /* Return the logarithm base 10 of ARG. */)
372 double d
= extract_float (arg
);
374 return make_float (d
);
377 DEFUN ("sqrt", Fsqrt
, Ssqrt
, 1, 1, 0,
378 doc
: /* Return the square root of ARG. */)
381 double d
= extract_float (arg
);
383 return make_float (d
);
386 #if 0 /* Not clearly worth adding. */
388 DEFUN ("acosh", Facosh
, Sacosh
, 1, 1, 0,
389 doc
: /* Return the inverse hyperbolic cosine of ARG. */)
392 double d
= extract_float (arg
);
394 return make_float (d
);
397 DEFUN ("asinh", Fasinh
, Sasinh
, 1, 1, 0,
398 doc
: /* Return the inverse hyperbolic sine of ARG. */)
401 double d
= extract_float (arg
);
403 return make_float (d
);
406 DEFUN ("atanh", Fatanh
, Satanh
, 1, 1, 0,
407 doc
: /* Return the inverse hyperbolic tangent of ARG. */)
410 double d
= extract_float (arg
);
412 return make_float (d
);
415 DEFUN ("cosh", Fcosh
, Scosh
, 1, 1, 0,
416 doc
: /* Return the hyperbolic cosine of ARG. */)
419 double d
= extract_float (arg
);
421 return make_float (d
);
424 DEFUN ("sinh", Fsinh
, Ssinh
, 1, 1, 0,
425 doc
: /* Return the hyperbolic sine of ARG. */)
428 double d
= extract_float (arg
);
430 return make_float (d
);
433 DEFUN ("tanh", Ftanh
, Stanh
, 1, 1, 0,
434 doc
: /* Return the hyperbolic tangent of ARG. */)
437 double d
= extract_float (arg
);
439 return make_float (d
);
443 DEFUN ("abs", Fabs
, Sabs
, 1, 1, 0,
444 doc
: /* Return the absolute value of ARG. */)
445 (register Lisp_Object arg
)
447 CHECK_NUMBER_OR_FLOAT (arg
);
450 arg
= make_float (fabs (XFLOAT_DATA (arg
)));
451 else if (XINT (arg
) < 0)
452 XSETINT (arg
, - XINT (arg
));
457 DEFUN ("float", Ffloat
, Sfloat
, 1, 1, 0,
458 doc
: /* Return the floating point number equal to ARG. */)
459 (register Lisp_Object arg
)
461 CHECK_NUMBER_OR_FLOAT (arg
);
464 return make_float ((double) XINT (arg
));
465 else /* give 'em the same float back */
469 DEFUN ("logb", Flogb
, Slogb
, 1, 1, 0,
470 doc
: /* Returns largest integer <= the base 2 log of the magnitude of ARG.
471 This is the same as the exponent of a float. */)
476 double f
= extract_float (arg
);
479 value
= MOST_NEGATIVE_FIXNUM
;
490 XSETINT (val
, value
);
495 /* the rounding functions */
498 rounding_driver (Lisp_Object arg
, Lisp_Object divisor
,
499 double (*double_round
) (double),
500 EMACS_INT (*int_round2
) (EMACS_INT
, EMACS_INT
),
503 CHECK_NUMBER_OR_FLOAT (arg
);
505 if (! NILP (divisor
))
509 CHECK_NUMBER_OR_FLOAT (divisor
);
511 if (FLOATP (arg
) || FLOATP (divisor
))
515 f1
= FLOATP (arg
) ? XFLOAT_DATA (arg
) : XINT (arg
);
516 f2
= (FLOATP (divisor
) ? XFLOAT_DATA (divisor
) : XINT (divisor
));
517 if (! IEEE_FLOATING_POINT
&& f2
== 0)
518 xsignal0 (Qarith_error
);
520 f1
= (*double_round
) (f1
/ f2
);
521 if (FIXNUM_OVERFLOW_P (f1
))
522 xsignal3 (Qrange_error
, build_string (name
), arg
, divisor
);
523 arg
= make_number (f1
);
531 xsignal0 (Qarith_error
);
533 XSETINT (arg
, (*int_round2
) (i1
, i2
));
539 double d
= (*double_round
) (XFLOAT_DATA (arg
));
540 if (FIXNUM_OVERFLOW_P (d
))
541 xsignal2 (Qrange_error
, build_string (name
), arg
);
542 arg
= make_number (d
);
548 /* With C's /, the result is implementation-defined if either operand
549 is negative, so take care with negative operands in the following
550 integer functions. */
553 ceiling2 (EMACS_INT i1
, EMACS_INT i2
)
556 ? (i1
< 0 ? ((-1 - i1
) / -i2
) + 1 : - (i1
/ -i2
))
557 : (i1
<= 0 ? - (-i1
/ i2
) : ((i1
- 1) / i2
) + 1));
561 floor2 (EMACS_INT i1
, EMACS_INT i2
)
564 ? (i1
<= 0 ? -i1
/ -i2
: -1 - ((i1
- 1) / -i2
))
565 : (i1
< 0 ? -1 - ((-1 - i1
) / i2
) : i1
/ i2
));
569 truncate2 (EMACS_INT i1
, EMACS_INT i2
)
572 ? (i1
< 0 ? -i1
/ -i2
: - (i1
/ -i2
))
573 : (i1
< 0 ? - (-i1
/ i2
) : i1
/ i2
));
577 round2 (EMACS_INT i1
, EMACS_INT i2
)
579 /* The C language's division operator gives us one remainder R, but
580 we want the remainder R1 on the other side of 0 if R1 is closer
581 to 0 than R is; because we want to round to even, we also want R1
582 if R and R1 are the same distance from 0 and if C's quotient is
584 EMACS_INT q
= i1
/ i2
;
585 EMACS_INT r
= i1
% i2
;
586 EMACS_INT abs_r
= r
< 0 ? -r
: r
;
587 EMACS_INT abs_r1
= (i2
< 0 ? -i2
: i2
) - abs_r
;
588 return q
+ (abs_r
+ (q
& 1) <= abs_r1
? 0 : (i2
^ r
) < 0 ? -1 : 1);
591 /* The code uses emacs_rint, so that it works to undefine HAVE_RINT
592 if `rint' exists but does not work right. */
594 #define emacs_rint rint
597 emacs_rint (double d
)
599 return floor (d
+ 0.5);
604 double_identity (double d
)
609 DEFUN ("ceiling", Fceiling
, Sceiling
, 1, 2, 0,
610 doc
: /* Return the smallest integer no less than ARG.
611 This rounds the value towards +inf.
612 With optional DIVISOR, return the smallest integer no less than ARG/DIVISOR. */)
613 (Lisp_Object arg
, Lisp_Object divisor
)
615 return rounding_driver (arg
, divisor
, ceil
, ceiling2
, "ceiling");
618 DEFUN ("floor", Ffloor
, Sfloor
, 1, 2, 0,
619 doc
: /* Return the largest integer no greater than ARG.
620 This rounds the value towards -inf.
621 With optional DIVISOR, return the largest integer no greater than ARG/DIVISOR. */)
622 (Lisp_Object arg
, Lisp_Object divisor
)
624 return rounding_driver (arg
, divisor
, floor
, floor2
, "floor");
627 DEFUN ("round", Fround
, Sround
, 1, 2, 0,
628 doc
: /* Return the nearest integer to ARG.
629 With optional DIVISOR, return the nearest integer to ARG/DIVISOR.
631 Rounding a value equidistant between two integers may choose the
632 integer closer to zero, or it may prefer an even integer, depending on
633 your machine. For example, \(round 2.5\) can return 3 on some
634 systems, but 2 on others. */)
635 (Lisp_Object arg
, Lisp_Object divisor
)
637 return rounding_driver (arg
, divisor
, emacs_rint
, round2
, "round");
640 DEFUN ("truncate", Ftruncate
, Struncate
, 1, 2, 0,
641 doc
: /* Truncate a floating point number to an int.
642 Rounds ARG toward zero.
643 With optional DIVISOR, truncate ARG/DIVISOR. */)
644 (Lisp_Object arg
, Lisp_Object divisor
)
646 return rounding_driver (arg
, divisor
, double_identity
, truncate2
,
652 fmod_float (Lisp_Object x
, Lisp_Object y
)
656 f1
= FLOATP (x
) ? XFLOAT_DATA (x
) : XINT (x
);
657 f2
= FLOATP (y
) ? XFLOAT_DATA (y
) : XINT (y
);
661 /* If the "remainder" comes out with the wrong sign, fix it. */
662 if (f2
< 0 ? 0 < f1
: f1
< 0)
665 return make_float (f1
);
668 DEFUN ("fceiling", Ffceiling
, Sfceiling
, 1, 1, 0,
669 doc
: /* Return the smallest integer no less than ARG, as a float.
670 \(Round toward +inf.\) */)
673 double d
= extract_float (arg
);
675 return make_float (d
);
678 DEFUN ("ffloor", Fffloor
, Sffloor
, 1, 1, 0,
679 doc
: /* Return the largest integer no greater than ARG, as a float.
680 \(Round towards -inf.\) */)
683 double d
= extract_float (arg
);
685 return make_float (d
);
688 DEFUN ("fround", Ffround
, Sfround
, 1, 1, 0,
689 doc
: /* Return the nearest integer to ARG, as a float. */)
692 double d
= extract_float (arg
);
694 return make_float (d
);
697 DEFUN ("ftruncate", Fftruncate
, Sftruncate
, 1, 1, 0,
698 doc
: /* Truncate a floating point number to an integral float value.
699 Rounds the value toward zero. */)
702 double d
= extract_float (arg
);
707 return make_float (d
);
711 syms_of_floatfns (void)
721 defsubr (&Scopysign
);
732 defsubr (&Sbessel_y0
);
733 defsubr (&Sbessel_y1
);
734 defsubr (&Sbessel_yn
);
735 defsubr (&Sbessel_j0
);
736 defsubr (&Sbessel_j1
);
737 defsubr (&Sbessel_jn
);
740 defsubr (&Slog_gamma
);
741 defsubr (&Scube_root
);
743 defsubr (&Sfceiling
);
746 defsubr (&Sftruncate
);
759 defsubr (&Struncate
);