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, *modf, pow, sin, *sinh, sqrt, tan, *tanh.
38 # define isfinite(x) ((x) - (x) == 0)
41 # define isnan(x) ((x) != (x))
44 /* Extract a Lisp number as a `double', or signal an error. */
47 extract_float (Lisp_Object num
)
49 CHECK_NUMBER_OR_FLOAT (num
);
52 return XFLOAT_DATA (num
);
53 return (double) XINT (num
);
58 DEFUN ("acos", Facos
, Sacos
, 1, 1, 0,
59 doc
: /* Return the inverse cosine of ARG. */)
62 double d
= extract_float (arg
);
64 return make_float (d
);
67 DEFUN ("asin", Fasin
, Sasin
, 1, 1, 0,
68 doc
: /* Return the inverse sine of ARG. */)
71 double d
= extract_float (arg
);
73 return make_float (d
);
76 DEFUN ("atan", Fatan
, Satan
, 1, 2, 0,
77 doc
: /* Return the inverse tangent of the arguments.
78 If only one argument Y is given, return the inverse tangent of Y.
79 If two arguments Y and X are given, return the inverse tangent of Y
80 divided by X, i.e. the angle in radians between the vector (X, Y)
82 (Lisp_Object y
, Lisp_Object x
)
84 double d
= extract_float (y
);
90 double d2
= extract_float (x
);
93 return make_float (d
);
96 DEFUN ("cos", Fcos
, Scos
, 1, 1, 0,
97 doc
: /* Return the cosine of ARG. */)
100 double d
= extract_float (arg
);
102 return make_float (d
);
105 DEFUN ("sin", Fsin
, Ssin
, 1, 1, 0,
106 doc
: /* Return the sine of ARG. */)
109 double d
= extract_float (arg
);
111 return make_float (d
);
114 DEFUN ("tan", Ftan
, Stan
, 1, 1, 0,
115 doc
: /* Return the tangent of ARG. */)
118 double d
= extract_float (arg
);
120 return make_float (d
);
123 DEFUN ("isnan", Fisnan
, Sisnan
, 1, 1, 0,
124 doc
: /* Return non nil iff argument X is a NaN. */)
128 return isnan (XFLOAT_DATA (x
)) ? Qt
: Qnil
;
132 DEFUN ("copysign", Fcopysign
, Scopysign
, 2, 2, 0,
133 doc
: /* Copy sign of X2 to value of X1, and return the result.
134 Cause an error if X1 or X2 is not a float. */)
135 (Lisp_Object x1
, Lisp_Object x2
)
142 f1
= XFLOAT_DATA (x1
);
143 f2
= XFLOAT_DATA (x2
);
145 return make_float (copysign (f1
, f2
));
149 DEFUN ("frexp", Ffrexp
, Sfrexp
, 1, 1, 0,
150 doc
: /* Get significand and exponent of a floating point number.
151 Breaks the floating point number X into its binary significand SGNFCAND
152 \(a floating point value between 0.5 (included) and 1.0 (excluded))
153 and an integral exponent EXP for 2, such that:
157 The function returns the cons cell (SGNFCAND . EXP).
158 If X is zero, both parts (SGNFCAND and EXP) are zero. */)
161 double f
= XFLOATINT (x
);
163 double sgnfcand
= frexp (f
, &exponent
);
164 return Fcons (make_float (sgnfcand
), make_number (exponent
));
167 DEFUN ("ldexp", Fldexp
, Sldexp
, 1, 2, 0,
168 doc
: /* Construct number X from significand SGNFCAND and exponent EXP.
169 Returns the floating point value resulting from multiplying SGNFCAND
170 (the significand) by 2 raised to the power of EXP (the exponent). */)
171 (Lisp_Object sgnfcand
, Lisp_Object exponent
)
173 CHECK_NUMBER (exponent
);
174 return make_float (ldexp (XFLOATINT (sgnfcand
), XINT (exponent
)));
177 DEFUN ("exp", Fexp
, Sexp
, 1, 1, 0,
178 doc
: /* Return the exponential base e of ARG. */)
181 double d
= extract_float (arg
);
183 return make_float (d
);
186 DEFUN ("expt", Fexpt
, Sexpt
, 2, 2, 0,
187 doc
: /* Return the exponential ARG1 ** ARG2. */)
188 (Lisp_Object arg1
, Lisp_Object arg2
)
192 CHECK_NUMBER_OR_FLOAT (arg1
);
193 CHECK_NUMBER_OR_FLOAT (arg2
);
194 if (INTEGERP (arg1
) /* common lisp spec */
195 && INTEGERP (arg2
) /* don't promote, if both are ints, and */
196 && 0 <= XINT (arg2
)) /* we are sure the result is not fractional */
197 { /* this can be improved by pre-calculating */
198 EMACS_INT y
; /* some binary powers of x then accumulating */
199 EMACS_UINT acc
, x
; /* Unsigned so that overflow is well defined. */
204 acc
= (y
& 1 ? x
: 1);
206 while ((y
>>= 1) != 0)
215 f1
= FLOATP (arg1
) ? XFLOAT_DATA (arg1
) : XINT (arg1
);
216 f2
= FLOATP (arg2
) ? XFLOAT_DATA (arg2
) : XINT (arg2
);
218 return make_float (f3
);
221 DEFUN ("log", Flog
, Slog
, 1, 2, 0,
222 doc
: /* Return the natural logarithm of ARG.
223 If the optional argument BASE is given, return log ARG using that base. */)
224 (Lisp_Object arg
, Lisp_Object base
)
226 double d
= extract_float (arg
);
232 double b
= extract_float (base
);
237 d
= log (d
) / log (b
);
239 return make_float (d
);
242 DEFUN ("log10", Flog10
, Slog10
, 1, 1, 0,
243 doc
: /* Return the logarithm base 10 of ARG. */)
246 double d
= extract_float (arg
);
248 return make_float (d
);
251 DEFUN ("sqrt", Fsqrt
, Ssqrt
, 1, 1, 0,
252 doc
: /* Return the square root of ARG. */)
255 double d
= extract_float (arg
);
257 return make_float (d
);
260 DEFUN ("abs", Fabs
, Sabs
, 1, 1, 0,
261 doc
: /* Return the absolute value of ARG. */)
262 (register Lisp_Object arg
)
264 CHECK_NUMBER_OR_FLOAT (arg
);
267 arg
= make_float (fabs (XFLOAT_DATA (arg
)));
268 else if (XINT (arg
) < 0)
269 XSETINT (arg
, - XINT (arg
));
274 DEFUN ("float", Ffloat
, Sfloat
, 1, 1, 0,
275 doc
: /* Return the floating point number equal to ARG. */)
276 (register Lisp_Object arg
)
278 CHECK_NUMBER_OR_FLOAT (arg
);
281 return make_float ((double) XINT (arg
));
282 else /* give 'em the same float back */
286 DEFUN ("logb", Flogb
, Slogb
, 1, 1, 0,
287 doc
: /* Returns largest integer <= the base 2 log of the magnitude of ARG.
288 This is the same as the exponent of a float. */)
293 double f
= extract_float (arg
);
296 value
= MOST_NEGATIVE_FIXNUM
;
297 else if (isfinite (f
))
304 value
= MOST_POSITIVE_FIXNUM
;
306 XSETINT (val
, value
);
311 /* the rounding functions */
314 rounding_driver (Lisp_Object arg
, Lisp_Object divisor
,
315 double (*double_round
) (double),
316 EMACS_INT (*int_round2
) (EMACS_INT
, EMACS_INT
),
319 CHECK_NUMBER_OR_FLOAT (arg
);
321 if (! NILP (divisor
))
325 CHECK_NUMBER_OR_FLOAT (divisor
);
327 if (FLOATP (arg
) || FLOATP (divisor
))
331 f1
= FLOATP (arg
) ? XFLOAT_DATA (arg
) : XINT (arg
);
332 f2
= (FLOATP (divisor
) ? XFLOAT_DATA (divisor
) : XINT (divisor
));
333 if (! IEEE_FLOATING_POINT
&& f2
== 0)
334 xsignal0 (Qarith_error
);
336 f1
= (*double_round
) (f1
/ f2
);
337 if (FIXNUM_OVERFLOW_P (f1
))
338 xsignal3 (Qrange_error
, build_string (name
), arg
, divisor
);
339 arg
= make_number (f1
);
347 xsignal0 (Qarith_error
);
349 XSETINT (arg
, (*int_round2
) (i1
, i2
));
355 double d
= (*double_round
) (XFLOAT_DATA (arg
));
356 if (FIXNUM_OVERFLOW_P (d
))
357 xsignal2 (Qrange_error
, build_string (name
), arg
);
358 arg
= make_number (d
);
364 /* With C's /, the result is implementation-defined if either operand
365 is negative, so take care with negative operands in the following
366 integer functions. */
369 ceiling2 (EMACS_INT i1
, EMACS_INT i2
)
372 ? (i1
< 0 ? ((-1 - i1
) / -i2
) + 1 : - (i1
/ -i2
))
373 : (i1
<= 0 ? - (-i1
/ i2
) : ((i1
- 1) / i2
) + 1));
377 floor2 (EMACS_INT i1
, EMACS_INT i2
)
380 ? (i1
<= 0 ? -i1
/ -i2
: -1 - ((i1
- 1) / -i2
))
381 : (i1
< 0 ? -1 - ((-1 - i1
) / i2
) : i1
/ i2
));
385 truncate2 (EMACS_INT i1
, EMACS_INT i2
)
388 ? (i1
< 0 ? -i1
/ -i2
: - (i1
/ -i2
))
389 : (i1
< 0 ? - (-i1
/ i2
) : i1
/ i2
));
393 round2 (EMACS_INT i1
, EMACS_INT i2
)
395 /* The C language's division operator gives us one remainder R, but
396 we want the remainder R1 on the other side of 0 if R1 is closer
397 to 0 than R is; because we want to round to even, we also want R1
398 if R and R1 are the same distance from 0 and if C's quotient is
400 EMACS_INT q
= i1
/ i2
;
401 EMACS_INT r
= i1
% i2
;
402 EMACS_INT abs_r
= r
< 0 ? -r
: r
;
403 EMACS_INT abs_r1
= (i2
< 0 ? -i2
: i2
) - abs_r
;
404 return q
+ (abs_r
+ (q
& 1) <= abs_r1
? 0 : (i2
^ r
) < 0 ? -1 : 1);
407 /* The code uses emacs_rint, so that it works to undefine HAVE_RINT
408 if `rint' exists but does not work right. */
410 #define emacs_rint rint
413 emacs_rint (double d
)
415 return floor (d
+ 0.5);
420 double_identity (double d
)
425 DEFUN ("ceiling", Fceiling
, Sceiling
, 1, 2, 0,
426 doc
: /* Return the smallest integer no less than ARG.
427 This rounds the value towards +inf.
428 With optional DIVISOR, return the smallest integer no less than ARG/DIVISOR. */)
429 (Lisp_Object arg
, Lisp_Object divisor
)
431 return rounding_driver (arg
, divisor
, ceil
, ceiling2
, "ceiling");
434 DEFUN ("floor", Ffloor
, Sfloor
, 1, 2, 0,
435 doc
: /* Return the largest integer no greater than ARG.
436 This rounds the value towards -inf.
437 With optional DIVISOR, return the largest integer no greater than ARG/DIVISOR. */)
438 (Lisp_Object arg
, Lisp_Object divisor
)
440 return rounding_driver (arg
, divisor
, floor
, floor2
, "floor");
443 DEFUN ("round", Fround
, Sround
, 1, 2, 0,
444 doc
: /* Return the nearest integer to ARG.
445 With optional DIVISOR, return the nearest integer to ARG/DIVISOR.
447 Rounding a value equidistant between two integers may choose the
448 integer closer to zero, or it may prefer an even integer, depending on
449 your machine. For example, \(round 2.5\) can return 3 on some
450 systems, but 2 on others. */)
451 (Lisp_Object arg
, Lisp_Object divisor
)
453 return rounding_driver (arg
, divisor
, emacs_rint
, round2
, "round");
456 DEFUN ("truncate", Ftruncate
, Struncate
, 1, 2, 0,
457 doc
: /* Truncate a floating point number to an int.
458 Rounds ARG toward zero.
459 With optional DIVISOR, truncate ARG/DIVISOR. */)
460 (Lisp_Object arg
, Lisp_Object divisor
)
462 return rounding_driver (arg
, divisor
, double_identity
, truncate2
,
468 fmod_float (Lisp_Object x
, Lisp_Object y
)
472 f1
= FLOATP (x
) ? XFLOAT_DATA (x
) : XINT (x
);
473 f2
= FLOATP (y
) ? XFLOAT_DATA (y
) : XINT (y
);
477 /* If the "remainder" comes out with the wrong sign, fix it. */
478 if (f2
< 0 ? 0 < f1
: f1
< 0)
481 return make_float (f1
);
484 DEFUN ("fceiling", Ffceiling
, Sfceiling
, 1, 1, 0,
485 doc
: /* Return the smallest integer no less than ARG, as a float.
486 \(Round toward +inf.\) */)
489 double d
= extract_float (arg
);
491 return make_float (d
);
494 DEFUN ("ffloor", Fffloor
, Sffloor
, 1, 1, 0,
495 doc
: /* Return the largest integer no greater than ARG, as a float.
496 \(Round towards -inf.\) */)
499 double d
= extract_float (arg
);
501 return make_float (d
);
504 DEFUN ("fround", Ffround
, Sfround
, 1, 1, 0,
505 doc
: /* Return the nearest integer to ARG, as a float. */)
508 double d
= extract_float (arg
);
510 return make_float (d
);
513 DEFUN ("ftruncate", Fftruncate
, Sftruncate
, 1, 1, 0,
514 doc
: /* Truncate a floating point number to an integral float value.
515 Rounds the value toward zero. */)
518 double d
= extract_float (arg
);
523 return make_float (d
);
527 syms_of_floatfns (void)
537 defsubr (&Scopysign
);
541 defsubr (&Sfceiling
);
544 defsubr (&Sftruncate
);
557 defsubr (&Struncate
);