1 /* Primitive operations on floating point for GNU Emacs Lisp interpreter.
3 Copyright (C) 1988, 1993-1994, 1999, 2001-2017 Free Software Foundation,
6 Author: Wolfgang Rupprecht (according to ack.texi)
8 This file is part of GNU Emacs.
10 GNU Emacs is free software: you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation, either version 3 of the License, or (at
13 your option) any later version.
15 GNU Emacs is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
24 /* C89 requires only the following math.h functions, and Emacs omits
25 the starred functions since we haven't found a use for them:
26 acos, asin, atan, atan2, ceil, cos, *cosh, exp, fabs, floor, fmod,
27 frexp, ldexp, log, log10 [via (log X 10)], *modf, pow, sin, *sinh,
30 C99 and C11 require the following math.h functions in addition to
31 the C89 functions. Of these, Emacs currently exports only the
32 starred ones to Lisp, since we haven't found a use for the others:
33 acosh, atanh, cbrt, *copysign, erf, erfc, exp2, expm1, fdim, fma,
34 fmax, fmin, fpclassify, hypot, ilogb, isfinite, isgreater,
35 isgreaterequal, isinf, isless, islessequal, islessgreater, *isnan,
36 isnormal, isunordered, lgamma, log1p, *log2 [via (log X 2)], *logb
37 (approximately), lrint/llrint, lround/llround, nan, nearbyint,
38 nextafter, nexttoward, remainder, remquo, *rint, round, scalbln,
39 scalbn, signbit, tgamma, *trunc.
48 /* 'isfinite' and 'isnan' cause build failures on Solaris 10 with the
49 bundled GCC in c99 mode. Work around the bugs with simple
50 implementations that are good enough. */
52 #define isfinite(x) ((x) - (x) == 0)
54 #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
);
70 return XFLOATINT (num
);
75 DEFUN ("acos", Facos
, Sacos
, 1, 1, 0,
76 doc
: /* Return the inverse cosine of ARG. */)
79 double d
= extract_float (arg
);
81 return make_float (d
);
84 DEFUN ("asin", Fasin
, Sasin
, 1, 1, 0,
85 doc
: /* Return the inverse sine of ARG. */)
88 double d
= extract_float (arg
);
90 return make_float (d
);
93 DEFUN ("atan", Fatan
, Satan
, 1, 2, 0,
94 doc
: /* Return the inverse tangent of the arguments.
95 If only one argument Y is given, return the inverse tangent of Y.
96 If two arguments Y and X are given, return the inverse tangent of Y
97 divided by X, i.e. the angle in radians between the vector (X, Y)
99 (Lisp_Object y
, Lisp_Object x
)
101 double d
= extract_float (y
);
107 double d2
= extract_float (x
);
110 return make_float (d
);
113 DEFUN ("cos", Fcos
, Scos
, 1, 1, 0,
114 doc
: /* Return the cosine of ARG. */)
117 double d
= extract_float (arg
);
119 return make_float (d
);
122 DEFUN ("sin", Fsin
, Ssin
, 1, 1, 0,
123 doc
: /* Return the sine of ARG. */)
126 double d
= extract_float (arg
);
128 return make_float (d
);
131 DEFUN ("tan", Ftan
, Stan
, 1, 1, 0,
132 doc
: /* Return the tangent of ARG. */)
135 double d
= extract_float (arg
);
137 return make_float (d
);
140 DEFUN ("isnan", Fisnan
, Sisnan
, 1, 1, 0,
141 doc
: /* Return non nil if argument X is a NaN. */)
145 return isnan (XFLOAT_DATA (x
)) ? Qt
: Qnil
;
149 DEFUN ("copysign", Fcopysign
, Scopysign
, 2, 2, 0,
150 doc
: /* Copy sign of X2 to value of X1, and return the result.
151 Cause an error if X1 or X2 is not a float. */)
152 (Lisp_Object x1
, Lisp_Object x2
)
159 f1
= XFLOAT_DATA (x1
);
160 f2
= XFLOAT_DATA (x2
);
162 return make_float (copysign (f1
, f2
));
166 DEFUN ("frexp", Ffrexp
, Sfrexp
, 1, 1, 0,
167 doc
: /* Get significand and exponent of a floating point number.
168 Breaks the floating point number X into its binary significand SGNFCAND
169 \(a floating point value between 0.5 (included) and 1.0 (excluded))
170 and an integral exponent EXP for 2, such that:
174 The function returns the cons cell (SGNFCAND . EXP).
175 If X is zero, both parts (SGNFCAND and EXP) are zero. */)
178 double f
= extract_float (x
);
180 double sgnfcand
= frexp (f
, &exponent
);
181 return Fcons (make_float (sgnfcand
), make_number (exponent
));
184 DEFUN ("ldexp", Fldexp
, Sldexp
, 2, 2, 0,
185 doc
: /* Return SGNFCAND * 2**EXPONENT, as a floating point number.
186 EXPONENT must be an integer. */)
187 (Lisp_Object sgnfcand
, Lisp_Object exponent
)
189 CHECK_NUMBER (exponent
);
190 int e
= min (max (INT_MIN
, XINT (exponent
)), INT_MAX
);
191 return make_float (ldexp (extract_float (sgnfcand
), e
));
194 DEFUN ("exp", Fexp
, Sexp
, 1, 1, 0,
195 doc
: /* Return the exponential base e of ARG. */)
198 double d
= extract_float (arg
);
200 return make_float (d
);
203 DEFUN ("expt", Fexpt
, Sexpt
, 2, 2, 0,
204 doc
: /* Return the exponential ARG1 ** ARG2. */)
205 (Lisp_Object arg1
, Lisp_Object arg2
)
207 CHECK_NUMBER_OR_FLOAT (arg1
);
208 CHECK_NUMBER_OR_FLOAT (arg2
);
209 if (INTEGERP (arg1
) /* common lisp spec */
210 && INTEGERP (arg2
) /* don't promote, if both are ints, and */
211 && XINT (arg2
) >= 0) /* we are sure the result is not fractional */
212 { /* this can be improved by pre-calculating */
213 EMACS_INT y
; /* some binary powers of x then accumulating */
214 EMACS_UINT acc
, x
; /* Unsigned so that overflow is well defined. */
219 acc
= (y
& 1 ? x
: 1);
221 while ((y
>>= 1) != 0)
230 return make_float (pow (XFLOATINT (arg1
), XFLOATINT (arg2
)));
233 DEFUN ("log", Flog
, Slog
, 1, 2, 0,
234 doc
: /* Return the natural logarithm of ARG.
235 If the optional argument BASE is given, return log ARG using that base. */)
236 (Lisp_Object arg
, Lisp_Object base
)
238 double d
= extract_float (arg
);
244 double b
= extract_float (base
);
253 d
= log (d
) / log (b
);
255 return make_float (d
);
258 DEFUN ("sqrt", Fsqrt
, Ssqrt
, 1, 1, 0,
259 doc
: /* Return the square root of ARG. */)
262 double d
= extract_float (arg
);
264 return make_float (d
);
267 DEFUN ("abs", Fabs
, Sabs
, 1, 1, 0,
268 doc
: /* Return the absolute value of ARG. */)
269 (register Lisp_Object arg
)
271 CHECK_NUMBER_OR_FLOAT (arg
);
274 arg
= make_float (fabs (XFLOAT_DATA (arg
)));
275 else if (XINT (arg
) < 0)
276 XSETINT (arg
, - XINT (arg
));
281 DEFUN ("float", Ffloat
, Sfloat
, 1, 1, 0,
282 doc
: /* Return the floating point number equal to ARG. */)
283 (register Lisp_Object arg
)
285 CHECK_NUMBER_OR_FLOAT (arg
);
288 return make_float ((double) XINT (arg
));
289 else /* give 'em the same float back */
293 DEFUN ("logb", Flogb
, Slogb
, 1, 1, 0,
294 doc
: /* Returns largest integer <= the base 2 log of the magnitude of ARG.
295 This is the same as the exponent of a float. */)
300 double f
= extract_float (arg
);
303 value
= MOST_NEGATIVE_FIXNUM
;
304 else if (isfinite (f
))
311 value
= MOST_POSITIVE_FIXNUM
;
313 XSETINT (val
, value
);
318 /* the rounding functions */
321 rounding_driver (Lisp_Object arg
, Lisp_Object divisor
,
322 double (*double_round
) (double),
323 EMACS_INT (*int_round2
) (EMACS_INT
, EMACS_INT
),
326 CHECK_NUMBER_OR_FLOAT (arg
);
333 d
= XFLOAT_DATA (arg
);
337 CHECK_NUMBER_OR_FLOAT (divisor
);
338 if (!FLOATP (arg
) && !FLOATP (divisor
))
340 if (XINT (divisor
) == 0)
341 xsignal0 (Qarith_error
);
342 return make_number (int_round2 (XINT (arg
), XINT (divisor
)));
345 double f1
= FLOATP (arg
) ? XFLOAT_DATA (arg
) : XINT (arg
);
346 double f2
= FLOATP (divisor
) ? XFLOAT_DATA (divisor
) : XINT (divisor
);
347 if (! IEEE_FLOATING_POINT
&& f2
== 0)
348 xsignal0 (Qarith_error
);
352 /* Round, coarsely test for fixnum overflow before converting to
353 EMACS_INT (to avoid undefined C behavior), and then exactly test
354 for overflow after converting (as FIXNUM_OVERFLOW_P is inaccurate
356 double dr
= double_round (d
);
357 if (fabs (dr
) < 2 * (MOST_POSITIVE_FIXNUM
+ 1))
360 if (! FIXNUM_OVERFLOW_P (ir
))
361 return make_number (ir
);
363 xsignal2 (Qrange_error
, build_string (name
), arg
);
367 ceiling2 (EMACS_INT i1
, EMACS_INT i2
)
369 return i1
/ i2
+ ((i1
% i2
!= 0) & ((i1
< 0) == (i2
< 0)));
373 floor2 (EMACS_INT i1
, EMACS_INT i2
)
375 return i1
/ i2
- ((i1
% i2
!= 0) & ((i1
< 0) != (i2
< 0)));
379 truncate2 (EMACS_INT i1
, EMACS_INT i2
)
385 round2 (EMACS_INT i1
, EMACS_INT i2
)
387 /* The C language's division operator gives us one remainder R, but
388 we want the remainder R1 on the other side of 0 if R1 is closer
389 to 0 than R is; because we want to round to even, we also want R1
390 if R and R1 are the same distance from 0 and if C's quotient is
392 EMACS_INT q
= i1
/ i2
;
393 EMACS_INT r
= i1
% i2
;
394 EMACS_INT abs_r
= eabs (r
);
395 EMACS_INT abs_r1
= eabs (i2
) - abs_r
;
396 return q
+ (abs_r
+ (q
& 1) <= abs_r1
? 0 : (i2
^ r
) < 0 ? -1 : 1);
399 /* The code uses emacs_rint, so that it works to undefine HAVE_RINT
400 if `rint' exists but does not work right. */
402 #define emacs_rint rint
405 emacs_rint (double d
)
408 double r
= floor (d1
);
409 return r
- (r
== d1
&& fmod (r
, 2) != 0);
414 #define emacs_trunc trunc
417 emacs_trunc (double d
)
419 return (d
< 0 ? ceil
: floor
) (d
);
423 DEFUN ("ceiling", Fceiling
, Sceiling
, 1, 2, 0,
424 doc
: /* Return the smallest integer no less than ARG.
425 This rounds the value towards +inf.
426 With optional DIVISOR, return the smallest integer no less than ARG/DIVISOR. */)
427 (Lisp_Object arg
, Lisp_Object divisor
)
429 return rounding_driver (arg
, divisor
, ceil
, ceiling2
, "ceiling");
432 DEFUN ("floor", Ffloor
, Sfloor
, 1, 2, 0,
433 doc
: /* Return the largest integer no greater than ARG.
434 This rounds the value towards -inf.
435 With optional DIVISOR, return the largest integer no greater than ARG/DIVISOR. */)
436 (Lisp_Object arg
, Lisp_Object divisor
)
438 return rounding_driver (arg
, divisor
, floor
, floor2
, "floor");
441 DEFUN ("round", Fround
, Sround
, 1, 2, 0,
442 doc
: /* Return the nearest integer to ARG.
443 With optional DIVISOR, return the nearest integer to ARG/DIVISOR.
445 Rounding a value equidistant between two integers may choose the
446 integer closer to zero, or it may prefer an even integer, depending on
447 your machine. For example, (round 2.5) can return 3 on some
448 systems, but 2 on others. */)
449 (Lisp_Object arg
, Lisp_Object divisor
)
451 return rounding_driver (arg
, divisor
, emacs_rint
, round2
, "round");
454 DEFUN ("truncate", Ftruncate
, Struncate
, 1, 2, 0,
455 doc
: /* Truncate a floating point number to an int.
456 Rounds ARG toward zero.
457 With optional DIVISOR, truncate ARG/DIVISOR. */)
458 (Lisp_Object arg
, Lisp_Object divisor
)
460 return rounding_driver (arg
, divisor
, emacs_trunc
, truncate2
,
466 fmod_float (Lisp_Object x
, Lisp_Object y
)
470 f1
= FLOATP (x
) ? XFLOAT_DATA (x
) : XINT (x
);
471 f2
= FLOATP (y
) ? XFLOAT_DATA (y
) : XINT (y
);
475 /* If the "remainder" comes out with the wrong sign, fix it. */
476 if (f2
< 0 ? f1
> 0 : f1
< 0)
479 return make_float (f1
);
482 DEFUN ("fceiling", Ffceiling
, Sfceiling
, 1, 1, 0,
483 doc
: /* Return the smallest integer no less than ARG, as a float.
484 \(Round toward +inf.) */)
487 double d
= extract_float (arg
);
489 return make_float (d
);
492 DEFUN ("ffloor", Fffloor
, Sffloor
, 1, 1, 0,
493 doc
: /* Return the largest integer no greater than ARG, as a float.
494 \(Round towards -inf.) */)
497 double d
= extract_float (arg
);
499 return make_float (d
);
502 DEFUN ("fround", Ffround
, Sfround
, 1, 1, 0,
503 doc
: /* Return the nearest integer to ARG, as a float. */)
506 double d
= extract_float (arg
);
508 return make_float (d
);
511 DEFUN ("ftruncate", Fftruncate
, Sftruncate
, 1, 1, 0,
512 doc
: /* Truncate a floating point number to an integral float value.
513 Rounds the value toward zero. */)
516 double d
= extract_float (arg
);
521 return make_float (d
);
525 syms_of_floatfns (void)
535 defsubr (&Scopysign
);
539 defsubr (&Sfceiling
);
542 defsubr (&Sftruncate
);
554 defsubr (&Struncate
);