]>
code.delx.au - gnu-emacs/blob - src/floatfns.c
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 /* Check that X is a floating point number. */
47 CHECK_FLOAT (Lisp_Object x
)
49 CHECK_TYPE (FLOATP (x
), Qfloatp
, x
);
52 /* Extract a Lisp number as a `double', or signal an error. */
55 extract_float (Lisp_Object num
)
57 CHECK_NUMBER_OR_FLOAT (num
);
60 return XFLOAT_DATA (num
);
61 return (double) XINT (num
);
66 DEFUN ("acos", Facos
, Sacos
, 1, 1, 0,
67 doc
: /* Return the inverse cosine of ARG. */)
70 double d
= extract_float (arg
);
72 return make_float (d
);
75 DEFUN ("asin", Fasin
, Sasin
, 1, 1, 0,
76 doc
: /* Return the inverse sine of ARG. */)
79 double d
= extract_float (arg
);
81 return make_float (d
);
84 DEFUN ("atan", Fatan
, Satan
, 1, 2, 0,
85 doc
: /* Return the inverse tangent of the arguments.
86 If only one argument Y is given, return the inverse tangent of Y.
87 If two arguments Y and X are given, return the inverse tangent of Y
88 divided by X, i.e. the angle in radians between the vector (X, Y)
90 (Lisp_Object y
, Lisp_Object x
)
92 double d
= extract_float (y
);
98 double d2
= extract_float (x
);
101 return make_float (d
);
104 DEFUN ("cos", Fcos
, Scos
, 1, 1, 0,
105 doc
: /* Return the cosine of ARG. */)
108 double d
= extract_float (arg
);
110 return make_float (d
);
113 DEFUN ("sin", Fsin
, Ssin
, 1, 1, 0,
114 doc
: /* Return the sine of ARG. */)
117 double d
= extract_float (arg
);
119 return make_float (d
);
122 DEFUN ("tan", Ftan
, Stan
, 1, 1, 0,
123 doc
: /* Return the tangent of ARG. */)
126 double d
= extract_float (arg
);
128 return make_float (d
);
131 DEFUN ("isnan", Fisnan
, Sisnan
, 1, 1, 0,
132 doc
: /* Return non nil iff argument X is a NaN. */)
136 return isnan (XFLOAT_DATA (x
)) ? Qt
: Qnil
;
140 DEFUN ("copysign", Fcopysign
, Scopysign
, 2, 2, 0,
141 doc
: /* Copy sign of X2 to value of X1, and return the result.
142 Cause an error if X1 or X2 is not a float. */)
143 (Lisp_Object x1
, Lisp_Object x2
)
150 f1
= XFLOAT_DATA (x1
);
151 f2
= XFLOAT_DATA (x2
);
153 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
);
171 double sgnfcand
= frexp (f
, &exponent
);
172 return Fcons (make_float (sgnfcand
), make_number (exponent
));
175 DEFUN ("ldexp", Fldexp
, Sldexp
, 1, 2, 0,
176 doc
: /* Construct number X from significand SGNFCAND and exponent EXP.
177 Returns the floating point value resulting from multiplying SGNFCAND
178 (the significand) by 2 raised to the power of EXP (the exponent). */)
179 (Lisp_Object sgnfcand
, Lisp_Object exponent
)
181 CHECK_NUMBER (exponent
);
182 return make_float (ldexp (XFLOATINT (sgnfcand
), XINT (exponent
)));
185 DEFUN ("exp", Fexp
, Sexp
, 1, 1, 0,
186 doc
: /* Return the exponential base e of ARG. */)
189 double d
= extract_float (arg
);
191 return make_float (d
);
194 DEFUN ("expt", Fexpt
, Sexpt
, 2, 2, 0,
195 doc
: /* Return the exponential ARG1 ** ARG2. */)
196 (Lisp_Object arg1
, Lisp_Object arg2
)
200 CHECK_NUMBER_OR_FLOAT (arg1
);
201 CHECK_NUMBER_OR_FLOAT (arg2
);
202 if (INTEGERP (arg1
) /* common lisp spec */
203 && INTEGERP (arg2
) /* don't promote, if both are ints, and */
204 && XINT (arg2
) >= 0) /* we are sure the result is not fractional */
205 { /* this can be improved by pre-calculating */
206 EMACS_INT y
; /* some binary powers of x then accumulating */
207 EMACS_UINT acc
, x
; /* Unsigned so that overflow is well defined. */
212 acc
= (y
& 1 ? x
: 1);
214 while ((y
>>= 1) != 0)
223 f1
= FLOATP (arg1
) ? XFLOAT_DATA (arg1
) : XINT (arg1
);
224 f2
= FLOATP (arg2
) ? XFLOAT_DATA (arg2
) : XINT (arg2
);
226 return make_float (f3
);
229 DEFUN ("log", Flog
, Slog
, 1, 2, 0,
230 doc
: /* Return the natural logarithm of ARG.
231 If the optional argument BASE is given, return log ARG using that base. */)
232 (Lisp_Object arg
, Lisp_Object base
)
234 double d
= extract_float (arg
);
240 double b
= extract_float (base
);
245 d
= log (d
) / log (b
);
247 return make_float (d
);
250 DEFUN ("log10", Flog10
, Slog10
, 1, 1, 0,
251 doc
: /* Return the logarithm base 10 of ARG. */)
254 double d
= extract_float (arg
);
256 return make_float (d
);
259 DEFUN ("sqrt", Fsqrt
, Ssqrt
, 1, 1, 0,
260 doc
: /* Return the square root of ARG. */)
263 double d
= extract_float (arg
);
265 return make_float (d
);
268 DEFUN ("abs", Fabs
, Sabs
, 1, 1, 0,
269 doc
: /* Return the absolute value of ARG. */)
270 (register Lisp_Object arg
)
272 CHECK_NUMBER_OR_FLOAT (arg
);
275 arg
= make_float (fabs (XFLOAT_DATA (arg
)));
276 else if (XINT (arg
) < 0)
277 XSETINT (arg
, - XINT (arg
));
282 DEFUN ("float", Ffloat
, Sfloat
, 1, 1, 0,
283 doc
: /* Return the floating point number equal to ARG. */)
284 (register Lisp_Object arg
)
286 CHECK_NUMBER_OR_FLOAT (arg
);
289 return make_float ((double) XINT (arg
));
290 else /* give 'em the same float back */
294 DEFUN ("logb", Flogb
, Slogb
, 1, 1, 0,
295 doc
: /* Returns largest integer <= the base 2 log of the magnitude of ARG.
296 This is the same as the exponent of a float. */)
301 double f
= extract_float (arg
);
304 value
= MOST_NEGATIVE_FIXNUM
;
305 else if (isfinite (f
))
312 value
= MOST_POSITIVE_FIXNUM
;
314 XSETINT (val
, value
);
319 /* the rounding functions */
322 rounding_driver (Lisp_Object arg
, Lisp_Object divisor
,
323 double (*double_round
) (double),
324 EMACS_INT (*int_round2
) (EMACS_INT
, EMACS_INT
),
327 CHECK_NUMBER_OR_FLOAT (arg
);
329 if (! NILP (divisor
))
333 CHECK_NUMBER_OR_FLOAT (divisor
);
335 if (FLOATP (arg
) || FLOATP (divisor
))
339 f1
= FLOATP (arg
) ? XFLOAT_DATA (arg
) : XINT (arg
);
340 f2
= (FLOATP (divisor
) ? XFLOAT_DATA (divisor
) : XINT (divisor
));
341 if (! IEEE_FLOATING_POINT
&& f2
== 0)
342 xsignal0 (Qarith_error
);
344 f1
= (*double_round
) (f1
/ f2
);
345 if (FIXNUM_OVERFLOW_P (f1
))
346 xsignal3 (Qrange_error
, build_string (name
), arg
, divisor
);
347 arg
= make_number (f1
);
355 xsignal0 (Qarith_error
);
357 XSETINT (arg
, (*int_round2
) (i1
, i2
));
363 double d
= (*double_round
) (XFLOAT_DATA (arg
));
364 if (FIXNUM_OVERFLOW_P (d
))
365 xsignal2 (Qrange_error
, build_string (name
), arg
);
366 arg
= make_number (d
);
372 /* With C's /, the result is implementation-defined if either operand
373 is negative, so take care with negative operands in the following
374 integer functions. */
377 ceiling2 (EMACS_INT i1
, EMACS_INT i2
)
380 ? (i1
< 0 ? ((-1 - i1
) / -i2
) + 1 : - (i1
/ -i2
))
381 : (i1
<= 0 ? - (-i1
/ i2
) : ((i1
- 1) / i2
) + 1));
385 floor2 (EMACS_INT i1
, EMACS_INT i2
)
388 ? (i1
<= 0 ? -i1
/ -i2
: -1 - ((i1
- 1) / -i2
))
389 : (i1
< 0 ? -1 - ((-1 - i1
) / i2
) : i1
/ i2
));
393 truncate2 (EMACS_INT i1
, EMACS_INT i2
)
396 ? (i1
< 0 ? -i1
/ -i2
: - (i1
/ -i2
))
397 : (i1
< 0 ? - (-i1
/ i2
) : i1
/ i2
));
401 round2 (EMACS_INT i1
, EMACS_INT i2
)
403 /* The C language's division operator gives us one remainder R, but
404 we want the remainder R1 on the other side of 0 if R1 is closer
405 to 0 than R is; because we want to round to even, we also want R1
406 if R and R1 are the same distance from 0 and if C's quotient is
408 EMACS_INT q
= i1
/ i2
;
409 EMACS_INT r
= i1
% i2
;
410 EMACS_INT abs_r
= eabs (r
);
411 EMACS_INT abs_r1
= eabs (i2
) - abs_r
;
412 return q
+ (abs_r
+ (q
& 1) <= abs_r1
? 0 : (i2
^ r
) < 0 ? -1 : 1);
415 /* The code uses emacs_rint, so that it works to undefine HAVE_RINT
416 if `rint' exists but does not work right. */
418 #define emacs_rint rint
421 emacs_rint (double d
)
423 return floor (d
+ 0.5);
428 double_identity (double d
)
433 DEFUN ("ceiling", Fceiling
, Sceiling
, 1, 2, 0,
434 doc
: /* Return the smallest integer no less than ARG.
435 This rounds the value towards +inf.
436 With optional DIVISOR, return the smallest integer no less than ARG/DIVISOR. */)
437 (Lisp_Object arg
, Lisp_Object divisor
)
439 return rounding_driver (arg
, divisor
, ceil
, ceiling2
, "ceiling");
442 DEFUN ("floor", Ffloor
, Sfloor
, 1, 2, 0,
443 doc
: /* Return the largest integer no greater than ARG.
444 This rounds the value towards -inf.
445 With optional DIVISOR, return the largest integer no greater than ARG/DIVISOR. */)
446 (Lisp_Object arg
, Lisp_Object divisor
)
448 return rounding_driver (arg
, divisor
, floor
, floor2
, "floor");
451 DEFUN ("round", Fround
, Sround
, 1, 2, 0,
452 doc
: /* Return the nearest integer to ARG.
453 With optional DIVISOR, return the nearest integer to ARG/DIVISOR.
455 Rounding a value equidistant between two integers may choose the
456 integer closer to zero, or it may prefer an even integer, depending on
457 your machine. For example, \(round 2.5\) can return 3 on some
458 systems, but 2 on others. */)
459 (Lisp_Object arg
, Lisp_Object divisor
)
461 return rounding_driver (arg
, divisor
, emacs_rint
, round2
, "round");
464 DEFUN ("truncate", Ftruncate
, Struncate
, 1, 2, 0,
465 doc
: /* Truncate a floating point number to an int.
466 Rounds ARG toward zero.
467 With optional DIVISOR, truncate ARG/DIVISOR. */)
468 (Lisp_Object arg
, Lisp_Object divisor
)
470 return rounding_driver (arg
, divisor
, double_identity
, truncate2
,
476 fmod_float (Lisp_Object x
, Lisp_Object y
)
480 f1
= FLOATP (x
) ? XFLOAT_DATA (x
) : XINT (x
);
481 f2
= FLOATP (y
) ? XFLOAT_DATA (y
) : XINT (y
);
485 /* If the "remainder" comes out with the wrong sign, fix it. */
486 if (f2
< 0 ? f1
> 0 : f1
< 0)
489 return make_float (f1
);
492 DEFUN ("fceiling", Ffceiling
, Sfceiling
, 1, 1, 0,
493 doc
: /* Return the smallest integer no less than ARG, as a float.
494 \(Round toward +inf.\) */)
497 double d
= extract_float (arg
);
499 return make_float (d
);
502 DEFUN ("ffloor", Fffloor
, Sffloor
, 1, 1, 0,
503 doc
: /* Return the largest integer no greater than ARG, as a float.
504 \(Round towards -inf.\) */)
507 double d
= extract_float (arg
);
509 return make_float (d
);
512 DEFUN ("fround", Ffround
, Sfround
, 1, 1, 0,
513 doc
: /* Return the nearest integer to ARG, as a float. */)
516 double d
= extract_float (arg
);
518 return make_float (d
);
521 DEFUN ("ftruncate", Fftruncate
, Sftruncate
, 1, 1, 0,
522 doc
: /* Truncate a floating point number to an integral float value.
523 Rounds the value toward zero. */)
526 double d
= extract_float (arg
);
531 return make_float (d
);
535 syms_of_floatfns (void)
545 defsubr (&Scopysign
);
549 defsubr (&Sfceiling
);
552 defsubr (&Sftruncate
);
565 defsubr (&Struncate
);