* xdisp.c (Qinhibit_debug_on_message): Now static.
[bpt/emacs.git] / src / floatfns.c
CommitLineData
b70021f4 1/* Primitive operations on floating point for GNU Emacs Lisp interpreter.
95df8112 2
acaf905b 3Copyright (C) 1988, 1993-1994, 1999, 2001-2012
95df8112 4 Free Software Foundation, Inc.
b70021f4 5
0a9dd3a7
GM
6Author: Wolfgang Rupprecht
7(according to ack.texi)
8
b70021f4
MR
9This file is part of GNU Emacs.
10
9ec0b715 11GNU Emacs is free software: you can redistribute it and/or modify
b70021f4 12it under the terms of the GNU General Public License as published by
9ec0b715
GM
13the Free Software Foundation, either version 3 of the License, or
14(at your option) any later version.
b70021f4
MR
15
16GNU Emacs is distributed in the hope that it will be useful,
17but WITHOUT ANY WARRANTY; without even the implied warranty of
18MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19GNU General Public License for more details.
20
21You should have received a copy of the GNU General Public License
9ec0b715 22along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
b70021f4
MR
23
24
f6196b87 25/* C89 requires only these math.h functions:
4b6baf5f
RS
26 acos, asin, atan, atan2, ceil, cos, cosh, exp, fabs, floor, fmod,
27 frexp, ldexp, log, log10, modf, pow, sin, sinh, sqrt, tan, tanh.
4b6baf5f
RS
28 */
29
18160b98 30#include <config.h>
d7306fe6 31#include <setjmp.h>
523e9291
RS
32#include "lisp.h"
33#include "syssignal.h"
34
2f261542 35#include <float.h>
d137ae2f
PE
36#if (FLT_RADIX == 2 && FLT_MANT_DIG == 24 \
37 && FLT_MIN_EXP == -125 && FLT_MAX_EXP == 128)
38#define IEEE_FLOATING_POINT 1
39#else
40#define IEEE_FLOATING_POINT 0
41#endif
d137ae2f 42
b70021f4 43#include <math.h>
4b6baf5f 44
32085e8e 45/* This declaration is omitted on some systems, like Ultrix. */
7a4720e2 46#if !defined (HPUX) && defined (HAVE_LOGB) && !defined (logb)
d2aa42f8 47extern double logb (double);
7a4720e2 48#endif /* not HPUX and HAVE_LOGB and no logb macro */
c26406fe 49
b70021f4
MR
50/* Extract a Lisp number as a `double', or signal an error. */
51
52double
d5a3eaaf 53extract_float (Lisp_Object num)
b70021f4 54{
b7826503 55 CHECK_NUMBER_OR_FLOAT (num);
b70021f4 56
207a45c1 57 if (FLOATP (num))
70949dac 58 return XFLOAT_DATA (num);
b70021f4
MR
59 return (double) XINT (num);
60}
c2d4ea74
RS
61\f
62/* Trig functions. */
b70021f4
MR
63
64DEFUN ("acos", Facos, Sacos, 1, 1, 0,
335c5470 65 doc: /* Return the inverse cosine of ARG. */)
f6196b87 66 (Lisp_Object arg)
b70021f4 67{
4b6baf5f 68 double d = extract_float (arg);
f6196b87 69 d = acos (d);
b70021f4
MR
70 return make_float (d);
71}
72
c2d4ea74 73DEFUN ("asin", Fasin, Sasin, 1, 1, 0,
335c5470 74 doc: /* Return the inverse sine of ARG. */)
f6196b87 75 (Lisp_Object arg)
b70021f4 76{
4b6baf5f 77 double d = extract_float (arg);
f6196b87 78 d = asin (d);
b70021f4
MR
79 return make_float (d);
80}
81
250ffca6
EZ
82DEFUN ("atan", Fatan, Satan, 1, 2, 0,
83 doc: /* Return the inverse tangent of the arguments.
84If only one argument Y is given, return the inverse tangent of Y.
85If two arguments Y and X are given, return the inverse tangent of Y
86divided by X, i.e. the angle in radians between the vector (X, Y)
87and the x-axis. */)
f6196b87 88 (Lisp_Object y, Lisp_Object x)
b70021f4 89{
250ffca6
EZ
90 double d = extract_float (y);
91
92 if (NILP (x))
f6196b87 93 d = atan (d);
250ffca6
EZ
94 else
95 {
96 double d2 = extract_float (x);
f6196b87 97 d = atan2 (d, d2);
250ffca6 98 }
b70021f4
MR
99 return make_float (d);
100}
101
c2d4ea74 102DEFUN ("cos", Fcos, Scos, 1, 1, 0,
335c5470 103 doc: /* Return the cosine of ARG. */)
f6196b87 104 (Lisp_Object arg)
b70021f4 105{
4b6baf5f 106 double d = extract_float (arg);
f6196b87 107 d = cos (d);
b70021f4
MR
108 return make_float (d);
109}
110
c2d4ea74 111DEFUN ("sin", Fsin, Ssin, 1, 1, 0,
335c5470 112 doc: /* Return the sine of ARG. */)
f6196b87 113 (Lisp_Object arg)
b70021f4 114{
4b6baf5f 115 double d = extract_float (arg);
f6196b87 116 d = sin (d);
b70021f4
MR
117 return make_float (d);
118}
119
c2d4ea74 120DEFUN ("tan", Ftan, Stan, 1, 1, 0,
335c5470 121 doc: /* Return the tangent of ARG. */)
f6196b87 122 (Lisp_Object arg)
4b6baf5f
RS
123{
124 double d = extract_float (arg);
f6196b87 125 d = tan (d);
b70021f4
MR
126 return make_float (d);
127}
15e12598 128
c8199d0f
PE
129#undef isnan
130#define isnan(x) ((x) != (x))
131
15e12598
VB
132DEFUN ("isnan", Fisnan, Sisnan, 1, 1, 0,
133 doc: /* Return non nil iff argument X is a NaN. */)
5842a27b 134 (Lisp_Object x)
15e12598
VB
135{
136 CHECK_FLOAT (x);
137 return isnan (XFLOAT_DATA (x)) ? Qt : Qnil;
138}
139
c8199d0f 140#ifdef HAVE_COPYSIGN
3c2907f7 141DEFUN ("copysign", Fcopysign, Scopysign, 2, 2, 0,
15e12598
VB
142 doc: /* Copy sign of X2 to value of X1, and return the result.
143Cause an error if X1 or X2 is not a float. */)
5842a27b 144 (Lisp_Object x1, Lisp_Object x2)
15e12598
VB
145{
146 double f1, f2;
147
148 CHECK_FLOAT (x1);
149 CHECK_FLOAT (x2);
150
151 f1 = XFLOAT_DATA (x1);
152 f2 = XFLOAT_DATA (x2);
153
154 return make_float (copysign (f1, f2));
155}
156
157DEFUN ("frexp", Ffrexp, Sfrexp, 1, 1, 0,
158 doc: /* Get significand and exponent of a floating point number.
159Breaks the floating point number X into its binary significand SGNFCAND
160\(a floating point value between 0.5 (included) and 1.0 (excluded))
161and an integral exponent EXP for 2, such that:
162
163 X = SGNFCAND * 2^EXP
164
165The function returns the cons cell (SGNFCAND . EXP).
166If X is zero, both parts (SGNFCAND and EXP) are zero. */)
5842a27b 167 (Lisp_Object x)
15e12598
VB
168{
169 double f = XFLOATINT (x);
170
171 if (f == 0.0)
172 return Fcons (make_float (0.0), make_number (0));
173 else
174 {
a885e2ed
PE
175 int exponent;
176 double sgnfcand = frexp (f, &exponent);
177 return Fcons (make_float (sgnfcand), make_number (exponent));
15e12598
VB
178 }
179}
180
181DEFUN ("ldexp", Fldexp, Sldexp, 1, 2, 0,
182 doc: /* Construct number X from significand SGNFCAND and exponent EXP.
183Returns the floating point value resulting from multiplying SGNFCAND
184(the significand) by 2 raised to the power of EXP (the exponent). */)
a885e2ed 185 (Lisp_Object sgnfcand, Lisp_Object exponent)
15e12598 186{
a885e2ed
PE
187 CHECK_NUMBER (exponent);
188 return make_float (ldexp (XFLOATINT (sgnfcand), XINT (exponent)));
15e12598
VB
189}
190#endif
b70021f4 191\f
c2d4ea74
RS
192#if 0 /* Leave these out unless we find there's a reason for them. */
193
b70021f4 194DEFUN ("bessel-j0", Fbessel_j0, Sbessel_j0, 1, 1, 0,
335c5470 195 doc: /* Return the bessel function j0 of ARG. */)
f6196b87 196 (Lisp_Object arg)
b70021f4 197{
4b6baf5f 198 double d = extract_float (arg);
f6196b87 199 d = j0 (d);
b70021f4
MR
200 return make_float (d);
201}
202
203DEFUN ("bessel-j1", Fbessel_j1, Sbessel_j1, 1, 1, 0,
335c5470 204 doc: /* Return the bessel function j1 of ARG. */)
f6196b87 205 (Lisp_Object arg)
b70021f4 206{
4b6baf5f 207 double d = extract_float (arg);
f6196b87 208 d = j1 (d);
b70021f4
MR
209 return make_float (d);
210}
211
212DEFUN ("bessel-jn", Fbessel_jn, Sbessel_jn, 2, 2, 0,
335c5470
PJ
213 doc: /* Return the order N bessel function output jn of ARG.
214The first arg (the order) is truncated to an integer. */)
f6196b87 215 (Lisp_Object n, Lisp_Object arg)
b70021f4 216{
3e670702
EN
217 int i1 = extract_float (n);
218 double f2 = extract_float (arg);
b70021f4 219
f6196b87 220 f2 = jn (i1, f2);
b70021f4
MR
221 return make_float (f2);
222}
223
224DEFUN ("bessel-y0", Fbessel_y0, Sbessel_y0, 1, 1, 0,
335c5470 225 doc: /* Return the bessel function y0 of ARG. */)
f6196b87 226 (Lisp_Object arg)
b70021f4 227{
4b6baf5f 228 double d = extract_float (arg);
f6196b87 229 d = y0 (d);
b70021f4
MR
230 return make_float (d);
231}
232
233DEFUN ("bessel-y1", Fbessel_y1, Sbessel_y1, 1, 1, 0,
335c5470 234 doc: /* Return the bessel function y1 of ARG. */)
f6196b87 235 (Lisp_Object arg)
b70021f4 236{
4b6baf5f 237 double d = extract_float (arg);
f6196b87 238 d = y1 (d);
b70021f4
MR
239 return make_float (d);
240}
241
242DEFUN ("bessel-yn", Fbessel_yn, Sbessel_yn, 2, 2, 0,
335c5470
PJ
243 doc: /* Return the order N bessel function output yn of ARG.
244The first arg (the order) is truncated to an integer. */)
f6196b87 245 (Lisp_Object n, Lisp_Object arg)
b70021f4 246{
3e670702
EN
247 int i1 = extract_float (n);
248 double f2 = extract_float (arg);
b70021f4 249
f6196b87 250 f2 = yn (i1, f2);
b70021f4
MR
251 return make_float (f2);
252}
b70021f4 253
c2d4ea74
RS
254#endif
255\f
256#if 0 /* Leave these out unless we see they are worth having. */
b70021f4
MR
257
258DEFUN ("erf", Ferf, Serf, 1, 1, 0,
335c5470 259 doc: /* Return the mathematical error function of ARG. */)
f6196b87 260 (Lisp_Object arg)
b70021f4 261{
4b6baf5f 262 double d = extract_float (arg);
f6196b87 263 d = erf (d);
b70021f4
MR
264 return make_float (d);
265}
266
267DEFUN ("erfc", Ferfc, Serfc, 1, 1, 0,
335c5470 268 doc: /* Return the complementary error function of ARG. */)
f6196b87 269 (Lisp_Object arg)
b70021f4 270{
4b6baf5f 271 double d = extract_float (arg);
f6196b87 272 d = erfc (d);
b70021f4
MR
273 return make_float (d);
274}
275
b70021f4 276DEFUN ("log-gamma", Flog_gamma, Slog_gamma, 1, 1, 0,
335c5470 277 doc: /* Return the log gamma of ARG. */)
f6196b87 278 (Lisp_Object arg)
b70021f4 279{
4b6baf5f 280 double d = extract_float (arg);
f6196b87 281 d = lgamma (d);
b70021f4
MR
282 return make_float (d);
283}
284
4b6baf5f 285DEFUN ("cube-root", Fcube_root, Scube_root, 1, 1, 0,
335c5470 286 doc: /* Return the cube root of ARG. */)
f6196b87 287 (Lisp_Object arg)
b70021f4 288{
4b6baf5f
RS
289 double d = extract_float (arg);
290#ifdef HAVE_CBRT
f6196b87 291 d = cbrt (d);
4b6baf5f
RS
292#else
293 if (d >= 0.0)
f6196b87 294 d = pow (d, 1.0/3.0);
4b6baf5f 295 else
f6196b87 296 d = -pow (-d, 1.0/3.0);
4b6baf5f 297#endif
b70021f4
MR
298 return make_float (d);
299}
300
706ac90d
RS
301#endif
302\f
c2d4ea74 303DEFUN ("exp", Fexp, Sexp, 1, 1, 0,
335c5470 304 doc: /* Return the exponential base e of ARG. */)
f6196b87 305 (Lisp_Object arg)
4b6baf5f
RS
306{
307 double d = extract_float (arg);
f6196b87 308 d = exp (d);
b70021f4
MR
309 return make_float (d);
310}
311
b70021f4 312DEFUN ("expt", Fexpt, Sexpt, 2, 2, 0,
335c5470 313 doc: /* Return the exponential ARG1 ** ARG2. */)
f6196b87 314 (Lisp_Object arg1, Lisp_Object arg2)
b70021f4 315{
2742fe30 316 double f1, f2, f3;
b70021f4 317
b7826503
PJ
318 CHECK_NUMBER_OR_FLOAT (arg1);
319 CHECK_NUMBER_OR_FLOAT (arg2);
207a45c1 320 if (INTEGERP (arg1) /* common lisp spec */
5a9807a8
TTN
321 && INTEGERP (arg2) /* don't promote, if both are ints, and */
322 && 0 <= XINT (arg2)) /* we are sure the result is not fractional */
b70021f4 323 { /* this can be improved by pre-calculating */
125b3835
PE
324 EMACS_INT y; /* some binary powers of x then accumulating */
325 EMACS_UINT acc, x; /* Unsigned so that overflow is well defined. */
4be1d460
RS
326 Lisp_Object val;
327
4b6baf5f
RS
328 x = XINT (arg1);
329 y = XINT (arg2);
8d1da888 330 acc = (y & 1 ? x : 1);
177c0ea7 331
8d1da888 332 while ((y >>= 1) != 0)
b70021f4 333 {
8d1da888
PE
334 x *= x;
335 if (y & 1)
336 acc *= x;
b70021f4 337 }
e0cb2a68 338 XSETINT (val, acc);
4be1d460 339 return val;
b70021f4 340 }
70949dac
KR
341 f1 = FLOATP (arg1) ? XFLOAT_DATA (arg1) : XINT (arg1);
342 f2 = FLOATP (arg2) ? XFLOAT_DATA (arg2) : XINT (arg2);
f6196b87 343 f3 = pow (f1, f2);
2742fe30 344 return make_float (f3);
b70021f4 345}
c2d4ea74 346
56abb480 347DEFUN ("log", Flog, Slog, 1, 2, 0,
335c5470 348 doc: /* Return the natural logarithm of ARG.
356e6d8d 349If the optional argument BASE is given, return log ARG using that base. */)
f6196b87 350 (Lisp_Object arg, Lisp_Object base)
b70021f4 351{
4b6baf5f 352 double d = extract_float (arg);
56abb480
JB
353
354 if (NILP (base))
f6196b87 355 d = log (d);
56abb480
JB
356 else
357 {
358 double b = extract_float (base);
359
4b6baf5f 360 if (b == 10.0)
f6196b87 361 d = log10 (d);
4b6baf5f 362 else
f6196b87 363 d = log (d) / log (b);
56abb480 364 }
b70021f4
MR
365 return make_float (d);
366}
367
c2d4ea74 368DEFUN ("log10", Flog10, Slog10, 1, 1, 0,
335c5470 369 doc: /* Return the logarithm base 10 of ARG. */)
f6196b87 370 (Lisp_Object arg)
b70021f4 371{
4b6baf5f 372 double d = extract_float (arg);
f6196b87 373 d = log10 (d);
c2d4ea74
RS
374 return make_float (d);
375}
376
b70021f4 377DEFUN ("sqrt", Fsqrt, Ssqrt, 1, 1, 0,
335c5470 378 doc: /* Return the square root of ARG. */)
f6196b87 379 (Lisp_Object arg)
b70021f4 380{
4b6baf5f 381 double d = extract_float (arg);
f6196b87 382 d = sqrt (d);
b70021f4
MR
383 return make_float (d);
384}
c2d4ea74 385\f
706ac90d 386#if 0 /* Not clearly worth adding. */
b70021f4 387
c2d4ea74 388DEFUN ("acosh", Facosh, Sacosh, 1, 1, 0,
335c5470 389 doc: /* Return the inverse hyperbolic cosine of ARG. */)
f6196b87 390 (Lisp_Object arg)
b70021f4 391{
4b6baf5f 392 double d = extract_float (arg);
f6196b87 393 d = acosh (d);
c2d4ea74
RS
394 return make_float (d);
395}
396
397DEFUN ("asinh", Fasinh, Sasinh, 1, 1, 0,
335c5470 398 doc: /* Return the inverse hyperbolic sine of ARG. */)
f6196b87 399 (Lisp_Object arg)
c2d4ea74 400{
4b6baf5f 401 double d = extract_float (arg);
f6196b87 402 d = asinh (d);
c2d4ea74
RS
403 return make_float (d);
404}
405
406DEFUN ("atanh", Fatanh, Satanh, 1, 1, 0,
335c5470 407 doc: /* Return the inverse hyperbolic tangent of ARG. */)
f6196b87 408 (Lisp_Object arg)
c2d4ea74 409{
4b6baf5f 410 double d = extract_float (arg);
f6196b87 411 d = atanh (d);
c2d4ea74
RS
412 return make_float (d);
413}
414
415DEFUN ("cosh", Fcosh, Scosh, 1, 1, 0,
335c5470 416 doc: /* Return the hyperbolic cosine of ARG. */)
f6196b87 417 (Lisp_Object arg)
c2d4ea74 418{
4b6baf5f 419 double d = extract_float (arg);
f6196b87 420 d = cosh (d);
c2d4ea74
RS
421 return make_float (d);
422}
423
424DEFUN ("sinh", Fsinh, Ssinh, 1, 1, 0,
335c5470 425 doc: /* Return the hyperbolic sine of ARG. */)
f6196b87 426 (Lisp_Object arg)
c2d4ea74 427{
4b6baf5f 428 double d = extract_float (arg);
f6196b87 429 d = sinh (d);
b70021f4
MR
430 return make_float (d);
431}
432
433DEFUN ("tanh", Ftanh, Stanh, 1, 1, 0,
335c5470 434 doc: /* Return the hyperbolic tangent of ARG. */)
f6196b87 435 (Lisp_Object arg)
b70021f4 436{
4b6baf5f 437 double d = extract_float (arg);
f6196b87 438 d = tanh (d);
b70021f4
MR
439 return make_float (d);
440}
c2d4ea74 441#endif
b70021f4
MR
442\f
443DEFUN ("abs", Fabs, Sabs, 1, 1, 0,
335c5470 444 doc: /* Return the absolute value of ARG. */)
5842a27b 445 (register Lisp_Object arg)
b70021f4 446{
b7826503 447 CHECK_NUMBER_OR_FLOAT (arg);
b70021f4 448
207a45c1 449 if (FLOATP (arg))
7c26cf3c 450 arg = make_float (fabs (XFLOAT_DATA (arg)));
4b6baf5f 451 else if (XINT (arg) < 0)
db37cb37 452 XSETINT (arg, - XINT (arg));
b70021f4 453
4b6baf5f 454 return arg;
b70021f4
MR
455}
456
a7ca3326 457DEFUN ("float", Ffloat, Sfloat, 1, 1, 0,
335c5470 458 doc: /* Return the floating point number equal to ARG. */)
5842a27b 459 (register Lisp_Object arg)
b70021f4 460{
b7826503 461 CHECK_NUMBER_OR_FLOAT (arg);
b70021f4 462
207a45c1 463 if (INTEGERP (arg))
4b6baf5f 464 return make_float ((double) XINT (arg));
b70021f4 465 else /* give 'em the same float back */
4b6baf5f 466 return arg;
b70021f4
MR
467}
468
469DEFUN ("logb", Flogb, Slogb, 1, 1, 0,
335c5470
PJ
470 doc: /* Returns largest integer <= the base 2 log of the magnitude of ARG.
471This is the same as the exponent of a float. */)
5842a27b 472 (Lisp_Object arg)
b70021f4 473{
340176df 474 Lisp_Object val;
a7bf3c54 475 EMACS_INT value;
5bf54166 476 double f = extract_float (arg);
340176df 477
6694b327 478 if (f == 0.0)
b916d672 479 value = MOST_NEGATIVE_FIXNUM;
6694b327
KH
480 else
481 {
6d3c6adb 482#ifdef HAVE_LOGB
f6196b87 483 value = logb (f);
6d3c6adb 484#else
c8bf6cf3 485 int ivalue;
f6196b87 486 frexp (f, &ivalue);
c8bf6cf3 487 value = ivalue - 1;
340176df 488#endif
6694b327 489 }
e0cb2a68 490 XSETINT (val, value);
c26406fe 491 return val;
b70021f4
MR
492}
493
fc2157cb 494
acbbacbe
PE
495/* the rounding functions */
496
497static Lisp_Object
d2aa42f8
DN
498rounding_driver (Lisp_Object arg, Lisp_Object divisor,
499 double (*double_round) (double),
500 EMACS_INT (*int_round2) (EMACS_INT, EMACS_INT),
8ea90aa3 501 const char *name)
b70021f4 502{
b7826503 503 CHECK_NUMBER_OR_FLOAT (arg);
b70021f4 504
fc2157cb
PE
505 if (! NILP (divisor))
506 {
9a51b24a 507 EMACS_INT i1, i2;
fc2157cb 508
b7826503 509 CHECK_NUMBER_OR_FLOAT (divisor);
fc2157cb 510
207a45c1 511 if (FLOATP (arg) || FLOATP (divisor))
fc2157cb
PE
512 {
513 double f1, f2;
514
70949dac
KR
515 f1 = FLOATP (arg) ? XFLOAT_DATA (arg) : XINT (arg);
516 f2 = (FLOATP (divisor) ? XFLOAT_DATA (divisor) : XINT (divisor));
d137ae2f 517 if (! IEEE_FLOATING_POINT && f2 == 0)
edef1631 518 xsignal0 (Qarith_error);
fc2157cb 519
f6196b87
PE
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);
fc2157cb
PE
524 return arg;
525 }
fc2157cb
PE
526
527 i1 = XINT (arg);
528 i2 = XINT (divisor);
529
530 if (i2 == 0)
edef1631 531 xsignal0 (Qarith_error);
fc2157cb 532
acbbacbe 533 XSETINT (arg, (*int_round2) (i1, i2));
fc2157cb
PE
534 return arg;
535 }
536
207a45c1 537 if (FLOATP (arg))
81a63ccc 538 {
f6196b87
PE
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);
81a63ccc 543 }
b70021f4 544
4b6baf5f 545 return arg;
b70021f4
MR
546}
547
acbbacbe
PE
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. */
551
552static EMACS_INT
d2aa42f8 553ceiling2 (EMACS_INT i1, EMACS_INT i2)
acbbacbe
PE
554{
555 return (i2 < 0
556 ? (i1 < 0 ? ((-1 - i1) / -i2) + 1 : - (i1 / -i2))
557 : (i1 <= 0 ? - (-i1 / i2) : ((i1 - 1) / i2) + 1));
558}
559
560static EMACS_INT
d2aa42f8 561floor2 (EMACS_INT i1, EMACS_INT i2)
acbbacbe
PE
562{
563 return (i2 < 0
564 ? (i1 <= 0 ? -i1 / -i2 : -1 - ((i1 - 1) / -i2))
565 : (i1 < 0 ? -1 - ((-1 - i1) / i2) : i1 / i2));
566}
567
568static EMACS_INT
d2aa42f8 569truncate2 (EMACS_INT i1, EMACS_INT i2)
acbbacbe
PE
570{
571 return (i2 < 0
572 ? (i1 < 0 ? -i1 / -i2 : - (i1 / -i2))
573 : (i1 < 0 ? - (-i1 / i2) : i1 / i2));
574}
575
576static EMACS_INT
d2aa42f8 577round2 (EMACS_INT i1, EMACS_INT i2)
acbbacbe
PE
578{
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
583 odd. */
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);
589}
590
dca6c914
RS
591/* The code uses emacs_rint, so that it works to undefine HAVE_RINT
592 if `rint' exists but does not work right. */
593#ifdef HAVE_RINT
594#define emacs_rint rint
595#else
4b5878a8 596static double
d2aa42f8 597emacs_rint (double d)
4b5878a8 598{
1b65c684 599 return floor (d + 0.5);
4b5878a8
KH
600}
601#endif
602
acbbacbe 603static double
d2aa42f8 604double_identity (double d)
acbbacbe
PE
605{
606 return d;
607}
608
609DEFUN ("ceiling", Fceiling, Sceiling, 1, 2, 0,
1d6ea92f
RS
610 doc: /* Return the smallest integer no less than ARG.
611This rounds the value towards +inf.
335c5470 612With optional DIVISOR, return the smallest integer no less than ARG/DIVISOR. */)
5842a27b 613 (Lisp_Object arg, Lisp_Object divisor)
acbbacbe
PE
614{
615 return rounding_driver (arg, divisor, ceil, ceiling2, "ceiling");
616}
617
618DEFUN ("floor", Ffloor, Sfloor, 1, 2, 0,
1d6ea92f 619 doc: /* Return the largest integer no greater than ARG.
568b6e41 620This rounds the value towards -inf.
335c5470 621With optional DIVISOR, return the largest integer no greater than ARG/DIVISOR. */)
5842a27b 622 (Lisp_Object arg, Lisp_Object divisor)
acbbacbe
PE
623{
624 return rounding_driver (arg, divisor, floor, floor2, "floor");
625}
626
627DEFUN ("round", Fround, Sround, 1, 2, 0,
335c5470 628 doc: /* Return the nearest integer to ARG.
6ded2c89
EZ
629With optional DIVISOR, return the nearest integer to ARG/DIVISOR.
630
a32a4857
EZ
631Rounding a value equidistant between two integers may choose the
632integer closer to zero, or it may prefer an even integer, depending on
633your machine. For example, \(round 2.5\) can return 3 on some
59fe0cee 634systems, but 2 on others. */)
5842a27b 635 (Lisp_Object arg, Lisp_Object divisor)
acbbacbe 636{
dca6c914 637 return rounding_driver (arg, divisor, emacs_rint, round2, "round");
acbbacbe
PE
638}
639
a7ca3326 640DEFUN ("truncate", Ftruncate, Struncate, 1, 2, 0,
335c5470
PJ
641 doc: /* Truncate a floating point number to an int.
642Rounds ARG toward zero.
643With optional DIVISOR, truncate ARG/DIVISOR. */)
5842a27b 644 (Lisp_Object arg, Lisp_Object divisor)
acbbacbe
PE
645{
646 return rounding_driver (arg, divisor, double_identity, truncate2,
647 "truncate");
648}
649
fc2157cb 650
d137ae2f 651Lisp_Object
dd4c5104 652fmod_float (Lisp_Object x, Lisp_Object y)
d137ae2f
PE
653{
654 double f1, f2;
655
70949dac
KR
656 f1 = FLOATP (x) ? XFLOAT_DATA (x) : XINT (x);
657 f2 = FLOATP (y) ? XFLOAT_DATA (y) : XINT (y);
d137ae2f 658
f6196b87 659 f1 = fmod (f1, f2);
d137ae2f
PE
660
661 /* If the "remainder" comes out with the wrong sign, fix it. */
f6196b87
PE
662 if (f2 < 0 ? 0 < f1 : f1 < 0)
663 f1 += f2;
664
d137ae2f
PE
665 return make_float (f1);
666}
4b6baf5f 667\f
4b6baf5f 668DEFUN ("fceiling", Ffceiling, Sfceiling, 1, 1, 0,
335c5470
PJ
669 doc: /* Return the smallest integer no less than ARG, as a float.
670\(Round toward +inf.\) */)
f6196b87 671 (Lisp_Object arg)
4b6baf5f
RS
672{
673 double d = extract_float (arg);
f6196b87 674 d = ceil (d);
4b6baf5f
RS
675 return make_float (d);
676}
677
678DEFUN ("ffloor", Fffloor, Sffloor, 1, 1, 0,
335c5470
PJ
679 doc: /* Return the largest integer no greater than ARG, as a float.
680\(Round towards -inf.\) */)
f6196b87 681 (Lisp_Object arg)
4b6baf5f
RS
682{
683 double d = extract_float (arg);
f6196b87 684 d = floor (d);
4b6baf5f
RS
685 return make_float (d);
686}
b70021f4 687
4b6baf5f 688DEFUN ("fround", Ffround, Sfround, 1, 1, 0,
335c5470 689 doc: /* Return the nearest integer to ARG, as a float. */)
f6196b87 690 (Lisp_Object arg)
4b6baf5f
RS
691{
692 double d = extract_float (arg);
f6196b87 693 d = emacs_rint (d);
4b6baf5f
RS
694 return make_float (d);
695}
696
697DEFUN ("ftruncate", Fftruncate, Sftruncate, 1, 1, 0,
335c5470
PJ
698 doc: /* Truncate a floating point number to an integral float value.
699Rounds the value toward zero. */)
f6196b87 700 (Lisp_Object arg)
4b6baf5f
RS
701{
702 double d = extract_float (arg);
703 if (d >= 0.0)
f6196b87 704 d = floor (d);
4b6baf5f 705 else
f6196b87 706 d = ceil (d);
4b6baf5f 707 return make_float (d);
b70021f4
MR
708}
709\f
dfcf069d 710void
d5a3eaaf 711syms_of_floatfns (void)
b70021f4
MR
712{
713 defsubr (&Sacos);
b70021f4 714 defsubr (&Sasin);
b70021f4 715 defsubr (&Satan);
c2d4ea74
RS
716 defsubr (&Scos);
717 defsubr (&Ssin);
718 defsubr (&Stan);
15e12598 719 defsubr (&Sisnan);
c8199d0f 720#ifdef HAVE_COPYSIGN
15e12598
VB
721 defsubr (&Scopysign);
722 defsubr (&Sfrexp);
723 defsubr (&Sldexp);
1384fa33 724#endif
c2d4ea74
RS
725#if 0
726 defsubr (&Sacosh);
727 defsubr (&Sasinh);
b70021f4 728 defsubr (&Satanh);
c2d4ea74
RS
729 defsubr (&Scosh);
730 defsubr (&Ssinh);
731 defsubr (&Stanh);
b70021f4
MR
732 defsubr (&Sbessel_y0);
733 defsubr (&Sbessel_y1);
734 defsubr (&Sbessel_yn);
735 defsubr (&Sbessel_j0);
736 defsubr (&Sbessel_j1);
737 defsubr (&Sbessel_jn);
b70021f4
MR
738 defsubr (&Serf);
739 defsubr (&Serfc);
c2d4ea74 740 defsubr (&Slog_gamma);
4b6baf5f 741 defsubr (&Scube_root);
892ed7e0 742#endif
4b6baf5f
RS
743 defsubr (&Sfceiling);
744 defsubr (&Sffloor);
745 defsubr (&Sfround);
746 defsubr (&Sftruncate);
b70021f4 747 defsubr (&Sexp);
c2d4ea74 748 defsubr (&Sexpt);
b70021f4
MR
749 defsubr (&Slog);
750 defsubr (&Slog10);
b70021f4 751 defsubr (&Ssqrt);
b70021f4
MR
752
753 defsubr (&Sabs);
754 defsubr (&Sfloat);
755 defsubr (&Slogb);
756 defsubr (&Sceiling);
acbbacbe 757 defsubr (&Sfloor);
b70021f4
MR
758 defsubr (&Sround);
759 defsubr (&Struncate);
760}