Improve vc-bzr-working-revision for lightweight checkouts
[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
c990426a
PE
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.
4b6baf5f
RS
29 */
30
18160b98 31#include <config.h>
d7306fe6 32#include <setjmp.h>
523e9291
RS
33#include "lisp.h"
34#include "syssignal.h"
35
2f261542 36#include <float.h>
d137ae2f
PE
37#if (FLT_RADIX == 2 && FLT_MANT_DIG == 24 \
38 && FLT_MIN_EXP == -125 && FLT_MAX_EXP == 128)
39#define IEEE_FLOATING_POINT 1
40#else
41#define IEEE_FLOATING_POINT 0
42#endif
d137ae2f 43
b70021f4 44#include <math.h>
4b6baf5f 45
c990426a
PE
46#ifndef isfinite
47# define isfinite(x) ((x) - (x) == 0)
48#endif
49#ifndef isnan
50# define isnan(x) ((x) != (x))
51#endif
c26406fe 52
b70021f4
MR
53/* Extract a Lisp number as a `double', or signal an error. */
54
55double
d5a3eaaf 56extract_float (Lisp_Object num)
b70021f4 57{
b7826503 58 CHECK_NUMBER_OR_FLOAT (num);
b70021f4 59
207a45c1 60 if (FLOATP (num))
70949dac 61 return XFLOAT_DATA (num);
b70021f4
MR
62 return (double) XINT (num);
63}
c2d4ea74
RS
64\f
65/* Trig functions. */
b70021f4
MR
66
67DEFUN ("acos", Facos, Sacos, 1, 1, 0,
335c5470 68 doc: /* Return the inverse cosine of ARG. */)
f6196b87 69 (Lisp_Object arg)
b70021f4 70{
4b6baf5f 71 double d = extract_float (arg);
f6196b87 72 d = acos (d);
b70021f4
MR
73 return make_float (d);
74}
75
c2d4ea74 76DEFUN ("asin", Fasin, Sasin, 1, 1, 0,
335c5470 77 doc: /* Return the inverse sine of ARG. */)
f6196b87 78 (Lisp_Object arg)
b70021f4 79{
4b6baf5f 80 double d = extract_float (arg);
f6196b87 81 d = asin (d);
b70021f4
MR
82 return make_float (d);
83}
84
250ffca6
EZ
85DEFUN ("atan", Fatan, Satan, 1, 2, 0,
86 doc: /* Return the inverse tangent of the arguments.
87If only one argument Y is given, return the inverse tangent of Y.
88If two arguments Y and X are given, return the inverse tangent of Y
89divided by X, i.e. the angle in radians between the vector (X, Y)
90and the x-axis. */)
f6196b87 91 (Lisp_Object y, Lisp_Object x)
b70021f4 92{
250ffca6
EZ
93 double d = extract_float (y);
94
95 if (NILP (x))
f6196b87 96 d = atan (d);
250ffca6
EZ
97 else
98 {
99 double d2 = extract_float (x);
f6196b87 100 d = atan2 (d, d2);
250ffca6 101 }
b70021f4
MR
102 return make_float (d);
103}
104
c2d4ea74 105DEFUN ("cos", Fcos, Scos, 1, 1, 0,
335c5470 106 doc: /* Return the cosine of ARG. */)
f6196b87 107 (Lisp_Object arg)
b70021f4 108{
4b6baf5f 109 double d = extract_float (arg);
f6196b87 110 d = cos (d);
b70021f4
MR
111 return make_float (d);
112}
113
c2d4ea74 114DEFUN ("sin", Fsin, Ssin, 1, 1, 0,
335c5470 115 doc: /* Return the sine of ARG. */)
f6196b87 116 (Lisp_Object arg)
b70021f4 117{
4b6baf5f 118 double d = extract_float (arg);
f6196b87 119 d = sin (d);
b70021f4
MR
120 return make_float (d);
121}
122
c2d4ea74 123DEFUN ("tan", Ftan, Stan, 1, 1, 0,
335c5470 124 doc: /* Return the tangent of ARG. */)
f6196b87 125 (Lisp_Object arg)
4b6baf5f
RS
126{
127 double d = extract_float (arg);
f6196b87 128 d = tan (d);
b70021f4
MR
129 return make_float (d);
130}
15e12598 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}
c990426a 156#endif
15e12598
VB
157
158DEFUN ("frexp", Ffrexp, Sfrexp, 1, 1, 0,
159 doc: /* Get significand and exponent of a floating point number.
160Breaks the floating point number X into its binary significand SGNFCAND
161\(a floating point value between 0.5 (included) and 1.0 (excluded))
162and an integral exponent EXP for 2, such that:
163
164 X = SGNFCAND * 2^EXP
165
166The function returns the cons cell (SGNFCAND . EXP).
167If X is zero, both parts (SGNFCAND and EXP) are zero. */)
5842a27b 168 (Lisp_Object x)
15e12598
VB
169{
170 double f = XFLOATINT (x);
c990426a
PE
171 int exponent;
172 double sgnfcand = frexp (f, &exponent);
173 return Fcons (make_float (sgnfcand), make_number (exponent));
15e12598
VB
174}
175
176DEFUN ("ldexp", Fldexp, Sldexp, 1, 2, 0,
177 doc: /* Construct number X from significand SGNFCAND and exponent EXP.
178Returns the floating point value resulting from multiplying SGNFCAND
179(the significand) by 2 raised to the power of EXP (the exponent). */)
a885e2ed 180 (Lisp_Object sgnfcand, Lisp_Object exponent)
15e12598 181{
a885e2ed
PE
182 CHECK_NUMBER (exponent);
183 return make_float (ldexp (XFLOATINT (sgnfcand), XINT (exponent)));
15e12598 184}
706ac90d 185\f
c2d4ea74 186DEFUN ("exp", Fexp, Sexp, 1, 1, 0,
335c5470 187 doc: /* Return the exponential base e of ARG. */)
f6196b87 188 (Lisp_Object arg)
4b6baf5f
RS
189{
190 double d = extract_float (arg);
f6196b87 191 d = exp (d);
b70021f4
MR
192 return make_float (d);
193}
194
b70021f4 195DEFUN ("expt", Fexpt, Sexpt, 2, 2, 0,
335c5470 196 doc: /* Return the exponential ARG1 ** ARG2. */)
f6196b87 197 (Lisp_Object arg1, Lisp_Object arg2)
b70021f4 198{
2742fe30 199 double f1, f2, f3;
b70021f4 200
b7826503
PJ
201 CHECK_NUMBER_OR_FLOAT (arg1);
202 CHECK_NUMBER_OR_FLOAT (arg2);
207a45c1 203 if (INTEGERP (arg1) /* common lisp spec */
5a9807a8
TTN
204 && INTEGERP (arg2) /* don't promote, if both are ints, and */
205 && 0 <= XINT (arg2)) /* we are sure the result is not fractional */
b70021f4 206 { /* this can be improved by pre-calculating */
125b3835
PE
207 EMACS_INT y; /* some binary powers of x then accumulating */
208 EMACS_UINT acc, x; /* Unsigned so that overflow is well defined. */
4be1d460
RS
209 Lisp_Object val;
210
4b6baf5f
RS
211 x = XINT (arg1);
212 y = XINT (arg2);
8d1da888 213 acc = (y & 1 ? x : 1);
177c0ea7 214
8d1da888 215 while ((y >>= 1) != 0)
b70021f4 216 {
8d1da888
PE
217 x *= x;
218 if (y & 1)
219 acc *= x;
b70021f4 220 }
e0cb2a68 221 XSETINT (val, acc);
4be1d460 222 return val;
b70021f4 223 }
70949dac
KR
224 f1 = FLOATP (arg1) ? XFLOAT_DATA (arg1) : XINT (arg1);
225 f2 = FLOATP (arg2) ? XFLOAT_DATA (arg2) : XINT (arg2);
f6196b87 226 f3 = pow (f1, f2);
2742fe30 227 return make_float (f3);
b70021f4 228}
c2d4ea74 229
56abb480 230DEFUN ("log", Flog, Slog, 1, 2, 0,
335c5470 231 doc: /* Return the natural logarithm of ARG.
356e6d8d 232If the optional argument BASE is given, return log ARG using that base. */)
f6196b87 233 (Lisp_Object arg, Lisp_Object base)
b70021f4 234{
4b6baf5f 235 double d = extract_float (arg);
56abb480
JB
236
237 if (NILP (base))
f6196b87 238 d = log (d);
56abb480
JB
239 else
240 {
241 double b = extract_float (base);
242
4b6baf5f 243 if (b == 10.0)
f6196b87 244 d = log10 (d);
4b6baf5f 245 else
f6196b87 246 d = log (d) / log (b);
56abb480 247 }
b70021f4
MR
248 return make_float (d);
249}
250
c2d4ea74 251DEFUN ("log10", Flog10, Slog10, 1, 1, 0,
335c5470 252 doc: /* Return the logarithm base 10 of ARG. */)
f6196b87 253 (Lisp_Object arg)
b70021f4 254{
4b6baf5f 255 double d = extract_float (arg);
f6196b87 256 d = log10 (d);
c2d4ea74
RS
257 return make_float (d);
258}
259
b70021f4 260DEFUN ("sqrt", Fsqrt, Ssqrt, 1, 1, 0,
335c5470 261 doc: /* Return the square root of ARG. */)
f6196b87 262 (Lisp_Object arg)
b70021f4 263{
4b6baf5f 264 double d = extract_float (arg);
f6196b87 265 d = sqrt (d);
b70021f4
MR
266 return make_float (d);
267}
c2d4ea74 268\f
b70021f4 269DEFUN ("abs", Fabs, Sabs, 1, 1, 0,
335c5470 270 doc: /* Return the absolute value of ARG. */)
5842a27b 271 (register Lisp_Object arg)
b70021f4 272{
b7826503 273 CHECK_NUMBER_OR_FLOAT (arg);
b70021f4 274
207a45c1 275 if (FLOATP (arg))
7c26cf3c 276 arg = make_float (fabs (XFLOAT_DATA (arg)));
4b6baf5f 277 else if (XINT (arg) < 0)
db37cb37 278 XSETINT (arg, - XINT (arg));
b70021f4 279
4b6baf5f 280 return arg;
b70021f4
MR
281}
282
a7ca3326 283DEFUN ("float", Ffloat, Sfloat, 1, 1, 0,
335c5470 284 doc: /* Return the floating point number equal to ARG. */)
5842a27b 285 (register Lisp_Object arg)
b70021f4 286{
b7826503 287 CHECK_NUMBER_OR_FLOAT (arg);
b70021f4 288
207a45c1 289 if (INTEGERP (arg))
4b6baf5f 290 return make_float ((double) XINT (arg));
b70021f4 291 else /* give 'em the same float back */
4b6baf5f 292 return arg;
b70021f4
MR
293}
294
295DEFUN ("logb", Flogb, Slogb, 1, 1, 0,
335c5470
PJ
296 doc: /* Returns largest integer <= the base 2 log of the magnitude of ARG.
297This is the same as the exponent of a float. */)
5842a27b 298 (Lisp_Object arg)
b70021f4 299{
340176df 300 Lisp_Object val;
a7bf3c54 301 EMACS_INT value;
5bf54166 302 double f = extract_float (arg);
340176df 303
6694b327 304 if (f == 0.0)
b916d672 305 value = MOST_NEGATIVE_FIXNUM;
c990426a 306 else if (isfinite (f))
6694b327 307 {
c8bf6cf3 308 int ivalue;
f6196b87 309 frexp (f, &ivalue);
c8bf6cf3 310 value = ivalue - 1;
6694b327 311 }
c990426a
PE
312 else
313 value = MOST_POSITIVE_FIXNUM;
314
e0cb2a68 315 XSETINT (val, value);
c26406fe 316 return val;
b70021f4
MR
317}
318
fc2157cb 319
acbbacbe
PE
320/* the rounding functions */
321
322static Lisp_Object
d2aa42f8
DN
323rounding_driver (Lisp_Object arg, Lisp_Object divisor,
324 double (*double_round) (double),
325 EMACS_INT (*int_round2) (EMACS_INT, EMACS_INT),
8ea90aa3 326 const char *name)
b70021f4 327{
b7826503 328 CHECK_NUMBER_OR_FLOAT (arg);
b70021f4 329
fc2157cb
PE
330 if (! NILP (divisor))
331 {
9a51b24a 332 EMACS_INT i1, i2;
fc2157cb 333
b7826503 334 CHECK_NUMBER_OR_FLOAT (divisor);
fc2157cb 335
207a45c1 336 if (FLOATP (arg) || FLOATP (divisor))
fc2157cb
PE
337 {
338 double f1, f2;
339
70949dac
KR
340 f1 = FLOATP (arg) ? XFLOAT_DATA (arg) : XINT (arg);
341 f2 = (FLOATP (divisor) ? XFLOAT_DATA (divisor) : XINT (divisor));
d137ae2f 342 if (! IEEE_FLOATING_POINT && f2 == 0)
edef1631 343 xsignal0 (Qarith_error);
fc2157cb 344
f6196b87
PE
345 f1 = (*double_round) (f1 / f2);
346 if (FIXNUM_OVERFLOW_P (f1))
347 xsignal3 (Qrange_error, build_string (name), arg, divisor);
348 arg = make_number (f1);
fc2157cb
PE
349 return arg;
350 }
fc2157cb
PE
351
352 i1 = XINT (arg);
353 i2 = XINT (divisor);
354
355 if (i2 == 0)
edef1631 356 xsignal0 (Qarith_error);
fc2157cb 357
acbbacbe 358 XSETINT (arg, (*int_round2) (i1, i2));
fc2157cb
PE
359 return arg;
360 }
361
207a45c1 362 if (FLOATP (arg))
81a63ccc 363 {
f6196b87
PE
364 double d = (*double_round) (XFLOAT_DATA (arg));
365 if (FIXNUM_OVERFLOW_P (d))
366 xsignal2 (Qrange_error, build_string (name), arg);
367 arg = make_number (d);
81a63ccc 368 }
b70021f4 369
4b6baf5f 370 return arg;
b70021f4
MR
371}
372
acbbacbe
PE
373/* With C's /, the result is implementation-defined if either operand
374 is negative, so take care with negative operands in the following
375 integer functions. */
376
377static EMACS_INT
d2aa42f8 378ceiling2 (EMACS_INT i1, EMACS_INT i2)
acbbacbe
PE
379{
380 return (i2 < 0
381 ? (i1 < 0 ? ((-1 - i1) / -i2) + 1 : - (i1 / -i2))
382 : (i1 <= 0 ? - (-i1 / i2) : ((i1 - 1) / i2) + 1));
383}
384
385static EMACS_INT
d2aa42f8 386floor2 (EMACS_INT i1, EMACS_INT i2)
acbbacbe
PE
387{
388 return (i2 < 0
389 ? (i1 <= 0 ? -i1 / -i2 : -1 - ((i1 - 1) / -i2))
390 : (i1 < 0 ? -1 - ((-1 - i1) / i2) : i1 / i2));
391}
392
393static EMACS_INT
d2aa42f8 394truncate2 (EMACS_INT i1, EMACS_INT i2)
acbbacbe
PE
395{
396 return (i2 < 0
397 ? (i1 < 0 ? -i1 / -i2 : - (i1 / -i2))
398 : (i1 < 0 ? - (-i1 / i2) : i1 / i2));
399}
400
401static EMACS_INT
d2aa42f8 402round2 (EMACS_INT i1, EMACS_INT i2)
acbbacbe
PE
403{
404 /* The C language's division operator gives us one remainder R, but
405 we want the remainder R1 on the other side of 0 if R1 is closer
406 to 0 than R is; because we want to round to even, we also want R1
407 if R and R1 are the same distance from 0 and if C's quotient is
408 odd. */
409 EMACS_INT q = i1 / i2;
410 EMACS_INT r = i1 % i2;
411 EMACS_INT abs_r = r < 0 ? -r : r;
412 EMACS_INT abs_r1 = (i2 < 0 ? -i2 : i2) - abs_r;
413 return q + (abs_r + (q & 1) <= abs_r1 ? 0 : (i2 ^ r) < 0 ? -1 : 1);
414}
415
dca6c914
RS
416/* The code uses emacs_rint, so that it works to undefine HAVE_RINT
417 if `rint' exists but does not work right. */
418#ifdef HAVE_RINT
419#define emacs_rint rint
420#else
4b5878a8 421static double
d2aa42f8 422emacs_rint (double d)
4b5878a8 423{
1b65c684 424 return floor (d + 0.5);
4b5878a8
KH
425}
426#endif
427
acbbacbe 428static double
d2aa42f8 429double_identity (double d)
acbbacbe
PE
430{
431 return d;
432}
433
434DEFUN ("ceiling", Fceiling, Sceiling, 1, 2, 0,
1d6ea92f
RS
435 doc: /* Return the smallest integer no less than ARG.
436This rounds the value towards +inf.
335c5470 437With optional DIVISOR, return the smallest integer no less than ARG/DIVISOR. */)
5842a27b 438 (Lisp_Object arg, Lisp_Object divisor)
acbbacbe
PE
439{
440 return rounding_driver (arg, divisor, ceil, ceiling2, "ceiling");
441}
442
443DEFUN ("floor", Ffloor, Sfloor, 1, 2, 0,
1d6ea92f 444 doc: /* Return the largest integer no greater than ARG.
568b6e41 445This rounds the value towards -inf.
335c5470 446With optional DIVISOR, return the largest integer no greater than ARG/DIVISOR. */)
5842a27b 447 (Lisp_Object arg, Lisp_Object divisor)
acbbacbe
PE
448{
449 return rounding_driver (arg, divisor, floor, floor2, "floor");
450}
451
452DEFUN ("round", Fround, Sround, 1, 2, 0,
335c5470 453 doc: /* Return the nearest integer to ARG.
6ded2c89
EZ
454With optional DIVISOR, return the nearest integer to ARG/DIVISOR.
455
a32a4857
EZ
456Rounding a value equidistant between two integers may choose the
457integer closer to zero, or it may prefer an even integer, depending on
458your machine. For example, \(round 2.5\) can return 3 on some
59fe0cee 459systems, but 2 on others. */)
5842a27b 460 (Lisp_Object arg, Lisp_Object divisor)
acbbacbe 461{
dca6c914 462 return rounding_driver (arg, divisor, emacs_rint, round2, "round");
acbbacbe
PE
463}
464
a7ca3326 465DEFUN ("truncate", Ftruncate, Struncate, 1, 2, 0,
335c5470
PJ
466 doc: /* Truncate a floating point number to an int.
467Rounds ARG toward zero.
468With optional DIVISOR, truncate ARG/DIVISOR. */)
5842a27b 469 (Lisp_Object arg, Lisp_Object divisor)
acbbacbe
PE
470{
471 return rounding_driver (arg, divisor, double_identity, truncate2,
472 "truncate");
473}
474
fc2157cb 475
d137ae2f 476Lisp_Object
dd4c5104 477fmod_float (Lisp_Object x, Lisp_Object y)
d137ae2f
PE
478{
479 double f1, f2;
480
70949dac
KR
481 f1 = FLOATP (x) ? XFLOAT_DATA (x) : XINT (x);
482 f2 = FLOATP (y) ? XFLOAT_DATA (y) : XINT (y);
d137ae2f 483
f6196b87 484 f1 = fmod (f1, f2);
d137ae2f
PE
485
486 /* If the "remainder" comes out with the wrong sign, fix it. */
f6196b87
PE
487 if (f2 < 0 ? 0 < f1 : f1 < 0)
488 f1 += f2;
489
d137ae2f
PE
490 return make_float (f1);
491}
4b6baf5f 492\f
4b6baf5f 493DEFUN ("fceiling", Ffceiling, Sfceiling, 1, 1, 0,
335c5470
PJ
494 doc: /* Return the smallest integer no less than ARG, as a float.
495\(Round toward +inf.\) */)
f6196b87 496 (Lisp_Object arg)
4b6baf5f
RS
497{
498 double d = extract_float (arg);
f6196b87 499 d = ceil (d);
4b6baf5f
RS
500 return make_float (d);
501}
502
503DEFUN ("ffloor", Fffloor, Sffloor, 1, 1, 0,
335c5470
PJ
504 doc: /* Return the largest integer no greater than ARG, as a float.
505\(Round towards -inf.\) */)
f6196b87 506 (Lisp_Object arg)
4b6baf5f
RS
507{
508 double d = extract_float (arg);
f6196b87 509 d = floor (d);
4b6baf5f
RS
510 return make_float (d);
511}
b70021f4 512
4b6baf5f 513DEFUN ("fround", Ffround, Sfround, 1, 1, 0,
335c5470 514 doc: /* Return the nearest integer to ARG, as a float. */)
f6196b87 515 (Lisp_Object arg)
4b6baf5f
RS
516{
517 double d = extract_float (arg);
f6196b87 518 d = emacs_rint (d);
4b6baf5f
RS
519 return make_float (d);
520}
521
522DEFUN ("ftruncate", Fftruncate, Sftruncate, 1, 1, 0,
335c5470
PJ
523 doc: /* Truncate a floating point number to an integral float value.
524Rounds the value toward zero. */)
f6196b87 525 (Lisp_Object arg)
4b6baf5f
RS
526{
527 double d = extract_float (arg);
528 if (d >= 0.0)
f6196b87 529 d = floor (d);
4b6baf5f 530 else
f6196b87 531 d = ceil (d);
4b6baf5f 532 return make_float (d);
b70021f4
MR
533}
534\f
dfcf069d 535void
d5a3eaaf 536syms_of_floatfns (void)
b70021f4
MR
537{
538 defsubr (&Sacos);
b70021f4 539 defsubr (&Sasin);
b70021f4 540 defsubr (&Satan);
c2d4ea74
RS
541 defsubr (&Scos);
542 defsubr (&Ssin);
543 defsubr (&Stan);
15e12598 544 defsubr (&Sisnan);
c8199d0f 545#ifdef HAVE_COPYSIGN
15e12598 546 defsubr (&Scopysign);
c990426a 547#endif
15e12598
VB
548 defsubr (&Sfrexp);
549 defsubr (&Sldexp);
4b6baf5f
RS
550 defsubr (&Sfceiling);
551 defsubr (&Sffloor);
552 defsubr (&Sfround);
553 defsubr (&Sftruncate);
b70021f4 554 defsubr (&Sexp);
c2d4ea74 555 defsubr (&Sexpt);
b70021f4
MR
556 defsubr (&Slog);
557 defsubr (&Slog10);
b70021f4 558 defsubr (&Ssqrt);
b70021f4
MR
559
560 defsubr (&Sabs);
561 defsubr (&Sfloat);
562 defsubr (&Slogb);
563 defsubr (&Sceiling);
acbbacbe 564 defsubr (&Sfloor);
b70021f4
MR
565 defsubr (&Sround);
566 defsubr (&Struncate);
567}