1 /* Primitive operations on floating point for GNU Emacs Lisp interpreter.
3 Copyright (C) 1988, 1993-1994, 1999, 2001-2013 Free Software Foundation,
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 the following math.h functions, and Emacs omits
26 the starred functions since we haven't found a use for them:
27 acos, asin, atan, atan2, ceil, cos, *cosh, exp, fabs, floor, fmod,
28 frexp, ldexp, log, log10 [via (log X 10)], *modf, pow, sin, *sinh,
31 C99 and C11 require the following math.h functions in addition to
32 the C89 functions. Of these, Emacs currently exports only the
33 starred ones to Lisp, since we haven't found a use for the others:
34 acosh, atanh, cbrt, *copysign, erf, erfc, exp2, expm1, fdim, fma,
35 fmax, fmin, fpclassify, hypot, ilogb, isfinite, isgreater,
36 isgreaterequal, isinf, isless, islessequal, islessgreater, *isnan,
37 isnormal, isunordered, lgamma, log1p, *log2 [via (log X 2)], *logb
38 (approximately), lrint/llrint, lround/llround, nan, nearbyint,
39 nextafter, nexttoward, remainder, remquo, *rint, round, scalbln,
40 scalbn, signbit, tgamma, trunc.
50 # define isfinite(x) ((x) - (x) == 0)
53 # define isnan(x) ((x) != (x))
56 /* Check that X is a floating point number. */
59 CHECK_FLOAT (Lisp_Object x
)
61 CHECK_TYPE (FLOATP (x
), Qfloatp
, x
);
64 /* Extract a Lisp number as a `double', or signal an error. */
67 extract_float (Lisp_Object num
)
69 CHECK_NUMBER_OR_FLOAT (num
);
72 return XFLOAT_DATA (num
);
73 return (double) XINT (num
);
78 DEFUN ("acos", Facos
, Sacos
, 1, 1, 0,
79 doc
: /* Return the inverse cosine of ARG. */)
82 double d
= extract_float (arg
);
84 return make_float (d
);
87 DEFUN ("asin", Fasin
, Sasin
, 1, 1, 0,
88 doc
: /* Return the inverse sine of ARG. */)
91 double d
= extract_float (arg
);
93 return make_float (d
);
96 DEFUN ("atan", Fatan
, Satan
, 1, 2, 0,
97 doc
: /* Return the inverse tangent of the arguments.
98 If only one argument Y is given, return the inverse tangent of Y.
99 If two arguments Y and X are given, return the inverse tangent of Y
100 divided by X, i.e. the angle in radians between the vector (X, Y)
102 (Lisp_Object y
, Lisp_Object x
)
104 double d
= extract_float (y
);
110 double d2
= extract_float (x
);
113 return make_float (d
);
116 DEFUN ("cos", Fcos
, Scos
, 1, 1, 0,
117 doc
: /* Return the cosine of ARG. */)
120 double d
= extract_float (arg
);
122 return make_float (d
);
125 DEFUN ("sin", Fsin
, Ssin
, 1, 1, 0,
126 doc
: /* Return the sine of ARG. */)
129 double d
= extract_float (arg
);
131 return make_float (d
);
134 DEFUN ("tan", Ftan
, Stan
, 1, 1, 0,
135 doc
: /* Return the tangent of ARG. */)
138 double d
= extract_float (arg
);
140 return make_float (d
);
143 DEFUN ("isnan", Fisnan
, Sisnan
, 1, 1, 0,
144 doc
: /* Return non nil iff argument X is a NaN. */)
148 return isnan (XFLOAT_DATA (x
)) ? Qt
: Qnil
;
152 DEFUN ("copysign", Fcopysign
, Scopysign
, 2, 2, 0,
153 doc
: /* Copy sign of X2 to value of X1, and return the result.
154 Cause an error if X1 or X2 is not a float. */)
155 (Lisp_Object x1
, Lisp_Object x2
)
162 f1
= XFLOAT_DATA (x1
);
163 f2
= XFLOAT_DATA (x2
);
165 return make_float (copysign (f1
, f2
));
169 DEFUN ("frexp", Ffrexp
, Sfrexp
, 1, 1, 0,
170 doc
: /* Get significand and exponent of a floating point number.
171 Breaks the floating point number X into its binary significand SGNFCAND
172 \(a floating point value between 0.5 (included) and 1.0 (excluded))
173 and an integral exponent EXP for 2, such that:
177 The function returns the cons cell (SGNFCAND . EXP).
178 If X is zero, both parts (SGNFCAND and EXP) are zero. */)
181 double f
= XFLOATINT (x
);
183 double sgnfcand
= frexp (f
, &exponent
);
184 return Fcons (make_float (sgnfcand
), make_number (exponent
));
187 DEFUN ("ldexp", Fldexp
, Sldexp
, 1, 2, 0,
188 doc
: /* Construct number X from significand SGNFCAND and exponent EXP.
189 Returns the floating point value resulting from multiplying SGNFCAND
190 (the significand) by 2 raised to the power of EXP (the exponent). */)
191 (Lisp_Object sgnfcand
, Lisp_Object exponent
)
193 CHECK_NUMBER (exponent
);
194 return make_float (ldexp (XFLOATINT (sgnfcand
), XINT (exponent
)));
197 DEFUN ("exp", Fexp
, Sexp
, 1, 1, 0,
198 doc
: /* Return the exponential base e of ARG. */)
201 double d
= extract_float (arg
);
203 return make_float (d
);
206 DEFUN ("expt", Fexpt
, Sexpt
, 2, 2, 0,
207 doc
: /* Return the exponential ARG1 ** ARG2. */)
208 (Lisp_Object arg1
, Lisp_Object arg2
)
212 CHECK_NUMBER_OR_FLOAT (arg1
);
213 CHECK_NUMBER_OR_FLOAT (arg2
);
214 if (INTEGERP (arg1
) /* common lisp spec */
215 && INTEGERP (arg2
) /* don't promote, if both are ints, and */
216 && XINT (arg2
) >= 0) /* we are sure the result is not fractional */
217 { /* this can be improved by pre-calculating */
218 EMACS_INT y
; /* some binary powers of x then accumulating */
219 EMACS_UINT acc
, x
; /* Unsigned so that overflow is well defined. */
224 acc
= (y
& 1 ? x
: 1);
226 while ((y
>>= 1) != 0)
235 f1
= FLOATP (arg1
) ? XFLOAT_DATA (arg1
) : XINT (arg1
);
236 f2
= FLOATP (arg2
) ? XFLOAT_DATA (arg2
) : XINT (arg2
);
238 return make_float (f3
);
241 DEFUN ("log", Flog
, Slog
, 1, 2, 0,
242 doc
: /* Return the natural logarithm of ARG.
243 If the optional argument BASE is given, return log ARG using that base. */)
244 (Lisp_Object arg
, Lisp_Object base
)
246 double d
= extract_float (arg
);
252 double b
= extract_float (base
);
261 d
= log (d
) / log (b
);
263 return make_float (d
);
266 DEFUN ("sqrt", Fsqrt
, Ssqrt
, 1, 1, 0,
267 doc
: /* Return the square root of ARG. */)
270 double d
= extract_float (arg
);
272 return make_float (d
);
275 DEFUN ("abs", Fabs
, Sabs
, 1, 1, 0,
276 doc
: /* Return the absolute value of ARG. */)
277 (register Lisp_Object arg
)
279 CHECK_NUMBER_OR_FLOAT (arg
);
282 arg
= make_float (fabs (XFLOAT_DATA (arg
)));
283 else if (XINT (arg
) < 0)
284 XSETINT (arg
, - XINT (arg
));
289 DEFUN ("float", Ffloat
, Sfloat
, 1, 1, 0,
290 doc
: /* Return the floating point number equal to ARG. */)
291 (register Lisp_Object arg
)
293 CHECK_NUMBER_OR_FLOAT (arg
);
296 return make_float ((double) XINT (arg
));
297 else /* give 'em the same float back */
301 DEFUN ("logb", Flogb
, Slogb
, 1, 1, 0,
302 doc
: /* Returns largest integer <= the base 2 log of the magnitude of ARG.
303 This is the same as the exponent of a float. */)
308 double f
= extract_float (arg
);
311 value
= MOST_NEGATIVE_FIXNUM
;
312 else if (isfinite (f
))
319 value
= MOST_POSITIVE_FIXNUM
;
321 XSETINT (val
, value
);
326 /* the rounding functions */
329 rounding_driver (Lisp_Object arg
, Lisp_Object divisor
,
330 double (*double_round
) (double),
331 EMACS_INT (*int_round2
) (EMACS_INT
, EMACS_INT
),
334 CHECK_NUMBER_OR_FLOAT (arg
);
336 if (! NILP (divisor
))
340 CHECK_NUMBER_OR_FLOAT (divisor
);
342 if (FLOATP (arg
) || FLOATP (divisor
))
346 f1
= FLOATP (arg
) ? XFLOAT_DATA (arg
) : XINT (arg
);
347 f2
= (FLOATP (divisor
) ? XFLOAT_DATA (divisor
) : XINT (divisor
));
348 if (! IEEE_FLOATING_POINT
&& f2
== 0)
349 xsignal0 (Qarith_error
);
351 f1
= (*double_round
) (f1
/ f2
);
352 if (FIXNUM_OVERFLOW_P (f1
))
353 xsignal3 (Qrange_error
, build_string (name
), arg
, divisor
);
354 arg
= make_number (f1
);
362 xsignal0 (Qarith_error
);
364 XSETINT (arg
, (*int_round2
) (i1
, i2
));
370 double d
= (*double_round
) (XFLOAT_DATA (arg
));
371 if (FIXNUM_OVERFLOW_P (d
))
372 xsignal2 (Qrange_error
, build_string (name
), arg
);
373 arg
= make_number (d
);
379 /* With C's /, the result is implementation-defined if either operand
380 is negative, so take care with negative operands in the following
381 integer functions. */
384 ceiling2 (EMACS_INT i1
, EMACS_INT i2
)
387 ? (i1
< 0 ? ((-1 - i1
) / -i2
) + 1 : - (i1
/ -i2
))
388 : (i1
<= 0 ? - (-i1
/ i2
) : ((i1
- 1) / i2
) + 1));
392 floor2 (EMACS_INT i1
, EMACS_INT i2
)
395 ? (i1
<= 0 ? -i1
/ -i2
: -1 - ((i1
- 1) / -i2
))
396 : (i1
< 0 ? -1 - ((-1 - i1
) / i2
) : i1
/ i2
));
400 truncate2 (EMACS_INT i1
, EMACS_INT i2
)
403 ? (i1
< 0 ? -i1
/ -i2
: - (i1
/ -i2
))
404 : (i1
< 0 ? - (-i1
/ i2
) : i1
/ i2
));
408 round2 (EMACS_INT i1
, EMACS_INT i2
)
410 /* The C language's division operator gives us one remainder R, but
411 we want the remainder R1 on the other side of 0 if R1 is closer
412 to 0 than R is; because we want to round to even, we also want R1
413 if R and R1 are the same distance from 0 and if C's quotient is
415 EMACS_INT q
= i1
/ i2
;
416 EMACS_INT r
= i1
% i2
;
417 EMACS_INT abs_r
= eabs (r
);
418 EMACS_INT abs_r1
= eabs (i2
) - abs_r
;
419 return q
+ (abs_r
+ (q
& 1) <= abs_r1
? 0 : (i2
^ r
) < 0 ? -1 : 1);
422 /* The code uses emacs_rint, so that it works to undefine HAVE_RINT
423 if `rint' exists but does not work right. */
425 #define emacs_rint rint
428 emacs_rint (double d
)
430 return floor (d
+ 0.5);
435 double_identity (double d
)
440 DEFUN ("ceiling", Fceiling
, Sceiling
, 1, 2, 0,
441 doc
: /* Return the smallest integer no less than ARG.
442 This rounds the value towards +inf.
443 With optional DIVISOR, return the smallest integer no less than ARG/DIVISOR. */)
444 (Lisp_Object arg
, Lisp_Object divisor
)
446 return rounding_driver (arg
, divisor
, ceil
, ceiling2
, "ceiling");
449 DEFUN ("floor", Ffloor
, Sfloor
, 1, 2, 0,
450 doc
: /* Return the largest integer no greater than ARG.
451 This rounds the value towards -inf.
452 With optional DIVISOR, return the largest integer no greater than ARG/DIVISOR. */)
453 (Lisp_Object arg
, Lisp_Object divisor
)
455 return rounding_driver (arg
, divisor
, floor
, floor2
, "floor");
458 DEFUN ("round", Fround
, Sround
, 1, 2, 0,
459 doc
: /* Return the nearest integer to ARG.
460 With optional DIVISOR, return the nearest integer to ARG/DIVISOR.
462 Rounding a value equidistant between two integers may choose the
463 integer closer to zero, or it may prefer an even integer, depending on
464 your machine. For example, \(round 2.5\) can return 3 on some
465 systems, but 2 on others. */)
466 (Lisp_Object arg
, Lisp_Object divisor
)
468 return rounding_driver (arg
, divisor
, emacs_rint
, round2
, "round");
471 DEFUN ("truncate", Ftruncate
, Struncate
, 1, 2, 0,
472 doc
: /* Truncate a floating point number to an int.
473 Rounds ARG toward zero.
474 With optional DIVISOR, truncate ARG/DIVISOR. */)
475 (Lisp_Object arg
, Lisp_Object divisor
)
477 return rounding_driver (arg
, divisor
, double_identity
, truncate2
,
483 fmod_float (Lisp_Object x
, Lisp_Object y
)
487 f1
= FLOATP (x
) ? XFLOAT_DATA (x
) : XINT (x
);
488 f2
= FLOATP (y
) ? XFLOAT_DATA (y
) : XINT (y
);
492 /* If the "remainder" comes out with the wrong sign, fix it. */
493 if (f2
< 0 ? f1
> 0 : f1
< 0)
496 return make_float (f1
);
499 DEFUN ("fceiling", Ffceiling
, Sfceiling
, 1, 1, 0,
500 doc
: /* Return the smallest integer no less than ARG, as a float.
501 \(Round toward +inf.\) */)
504 double d
= extract_float (arg
);
506 return make_float (d
);
509 DEFUN ("ffloor", Fffloor
, Sffloor
, 1, 1, 0,
510 doc
: /* Return the largest integer no greater than ARG, as a float.
511 \(Round towards -inf.\) */)
514 double d
= extract_float (arg
);
516 return make_float (d
);
519 DEFUN ("fround", Ffround
, Sfround
, 1, 1, 0,
520 doc
: /* Return the nearest integer to ARG, as a float. */)
523 double d
= extract_float (arg
);
525 return make_float (d
);
528 DEFUN ("ftruncate", Fftruncate
, Sftruncate
, 1, 1, 0,
529 doc
: /* Truncate a floating point number to an integral float value.
530 Rounds the value toward zero. */)
533 double d
= extract_float (arg
);
538 return make_float (d
);
542 syms_of_floatfns (void)
552 defsubr (&Scopysign
);
556 defsubr (&Sfceiling
);
559 defsubr (&Sftruncate
);
571 defsubr (&Struncate
);