1 /* Primitive operations on floating point for GNU Emacs Lisp interpreter.
2 
3 Copyright (C) 1988, 1993-1994, 1999, 2001-2021 Free Software Foundation,
4 Inc.
5 
6 Author: Wolfgang Rupprecht (according to ack.texi)
7 
8 This file is part of GNU Emacs.
9 
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.
14 
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.
19 
20 You should have received a copy of the GNU General Public License
21 along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
22 
23 
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,
28    sqrt, tan, *tanh.
29 
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.
40  */
41 
42 #include <config.h>
43 
44 #include "lisp.h"
45 #include "bignum.h"
46 
47 #include <math.h>
48 
49 #include <count-leading-zeros.h>
50 
51 /* Emacs needs proper handling of +/-inf; correct printing as well as
52    important packages depend on it.  Make sure the user didn't specify
53    -ffinite-math-only, either directly or implicitly with -Ofast or
54    -ffast-math.  */
55 #if defined __FINITE_MATH_ONLY__ && __FINITE_MATH_ONLY__
56  #error Emacs cannot be built with -ffinite-math-only
57 #endif
58 
59 /* Check that X is a floating point number.  */
60 
61 static void
CHECK_FLOAT(Lisp_Object x)62 CHECK_FLOAT (Lisp_Object x)
63 {
64   CHECK_TYPE (FLOATP (x), Qfloatp, x);
65 }
66 
67 /* Extract a Lisp number as a `double', or signal an error.  */
68 
69 double
extract_float(Lisp_Object num)70 extract_float (Lisp_Object num)
71 {
72   CHECK_NUMBER (num);
73   return XFLOATINT (num);
74 }
75 
76 /* Trig functions.  */
77 
78 DEFUN ("acos", Facos, Sacos, 1, 1, 0,
79        doc: /* Return the inverse cosine of ARG.  */)
80   (Lisp_Object arg)
81 {
82   double d = extract_float (arg);
83   d = acos (d);
84   return make_float (d);
85 }
86 
87 DEFUN ("asin", Fasin, Sasin, 1, 1, 0,
88        doc: /* Return the inverse sine of ARG.  */)
89   (Lisp_Object arg)
90 {
91   double d = extract_float (arg);
92   d = asin (d);
93   return make_float (d);
94 }
95 
96 DEFUN ("atan", Fatan, Satan, 1, 2, 0,
97        doc: /* Return the inverse tangent of the arguments.
98 If only one argument Y is given, return the inverse tangent of Y.
99 If two arguments Y and X are given, return the inverse tangent of Y
100 divided by X, i.e. the angle in radians between the vector (X, Y)
101 and the x-axis.  */)
102   (Lisp_Object y, Lisp_Object x)
103 {
104   double d = extract_float (y);
105 
106   if (NILP (x))
107     d = atan (d);
108   else
109     {
110       double d2 = extract_float (x);
111       d = atan2 (d, d2);
112     }
113   return make_float (d);
114 }
115 
116 DEFUN ("cos", Fcos, Scos, 1, 1, 0,
117        doc: /* Return the cosine of ARG.  */)
118   (Lisp_Object arg)
119 {
120   double d = extract_float (arg);
121   d = cos (d);
122   return make_float (d);
123 }
124 
125 DEFUN ("sin", Fsin, Ssin, 1, 1, 0,
126        doc: /* Return the sine of ARG.  */)
127   (Lisp_Object arg)
128 {
129   double d = extract_float (arg);
130   d = sin (d);
131   return make_float (d);
132 }
133 
134 DEFUN ("tan", Ftan, Stan, 1, 1, 0,
135        doc: /* Return the tangent of ARG.  */)
136   (Lisp_Object arg)
137 {
138   double d = extract_float (arg);
139   d = tan (d);
140   return make_float (d);
141 }
142 
143 DEFUN ("isnan", Fisnan, Sisnan, 1, 1, 0,
144        doc: /* Return non-nil if argument X is a NaN.  */)
145   (Lisp_Object x)
146 {
147   CHECK_FLOAT (x);
148   return isnan (XFLOAT_DATA (x)) ? Qt : Qnil;
149 }
150 
151 /* Although the substitute does not work on NaNs, it is good enough
152    for platforms lacking the signbit macro.  */
153 #ifndef signbit
154 # define signbit(x) ((x) < 0 || (IEEE_FLOATING_POINT && !(x) && 1 / (x) < 0))
155 #endif
156 
157 DEFUN ("copysign", Fcopysign, Scopysign, 2, 2, 0,
158        doc: /* Copy sign of X2 to value of X1, and return the result.
159 Cause an error if X1 or X2 is not a float.  */)
160   (Lisp_Object x1, Lisp_Object x2)
161 {
162   double f1, f2;
163 
164   CHECK_FLOAT (x1);
165   CHECK_FLOAT (x2);
166 
167   f1 = XFLOAT_DATA (x1);
168   f2 = XFLOAT_DATA (x2);
169 
170   /* Use signbit instead of copysign, to avoid calling make_float when
171      the result is X1.  */
172   return signbit (f1) != signbit (f2) ? make_float (-f1) : x1;
173 }
174 
175 DEFUN ("frexp", Ffrexp, Sfrexp, 1, 1, 0,
176        doc: /* Get significand and exponent of a floating point number.
177 Breaks the floating point number X into its binary significand SGNFCAND
178 \(a floating point value between 0.5 (included) and 1.0 (excluded))
179 and an integral exponent EXP for 2, such that:
180 
181   X = SGNFCAND * 2^EXP
182 
183 The function returns the cons cell (SGNFCAND . EXP).
184 If X is zero, both parts (SGNFCAND and EXP) are zero.  */)
185   (Lisp_Object x)
186 {
187   double f = extract_float (x);
188   int exponent;
189   double sgnfcand = frexp (f, &exponent);
190   return Fcons (make_float (sgnfcand), make_fixnum (exponent));
191 }
192 
193 DEFUN ("ldexp", Fldexp, Sldexp, 2, 2, 0,
194        doc: /* Return SGNFCAND * 2**EXPONENT, as a floating point number.
195 EXPONENT must be an integer.   */)
196   (Lisp_Object sgnfcand, Lisp_Object exponent)
197 {
198   CHECK_FIXNUM (exponent);
199   int e = min (max (INT_MIN, XFIXNUM (exponent)), INT_MAX);
200   return make_float (ldexp (extract_float (sgnfcand), e));
201 }
202 
203 DEFUN ("exp", Fexp, Sexp, 1, 1, 0,
204        doc: /* Return the exponential base e of ARG.  */)
205   (Lisp_Object arg)
206 {
207   double d = extract_float (arg);
208   d = exp (d);
209   return make_float (d);
210 }
211 
212 DEFUN ("expt", Fexpt, Sexpt, 2, 2, 0,
213        doc: /* Return the exponential ARG1 ** ARG2.  */)
214   (Lisp_Object arg1, Lisp_Object arg2)
215 {
216   CHECK_NUMBER (arg1);
217   CHECK_NUMBER (arg2);
218 
219   /* Common Lisp spec: don't promote if both are integers, and if the
220      result is not fractional.  */
221   if (INTEGERP (arg1) && !NILP (Fnatnump (arg2)))
222     return expt_integer (arg1, arg2);
223 
224   return make_float (pow (XFLOATINT (arg1), XFLOATINT (arg2)));
225 }
226 
227 DEFUN ("log", Flog, Slog, 1, 2, 0,
228        doc: /* Return the natural logarithm of ARG.
229 If the optional argument BASE is given, return log ARG using that base.  */)
230   (Lisp_Object arg, Lisp_Object base)
231 {
232   double d = extract_float (arg);
233 
234   if (NILP (base))
235     d = log (d);
236   else
237     {
238       double b = extract_float (base);
239 
240       if (b == 10.0)
241 	d = log10 (d);
242 #if HAVE_LOG2
243       else if (b == 2.0)
244 	d = log2 (d);
245 #endif
246       else
247 	d = log (d) / log (b);
248     }
249   return make_float (d);
250 }
251 
252 DEFUN ("sqrt", Fsqrt, Ssqrt, 1, 1, 0,
253        doc: /* Return the square root of ARG.  */)
254   (Lisp_Object arg)
255 {
256   double d = extract_float (arg);
257   d = sqrt (d);
258   return make_float (d);
259 }
260 
261 DEFUN ("abs", Fabs, Sabs, 1, 1, 0,
262        doc: /* Return the absolute value of ARG.  */)
263   (Lisp_Object arg)
264 {
265   CHECK_NUMBER (arg);
266 
267   if (FIXNUMP (arg))
268     {
269       if (XFIXNUM (arg) < 0)
270 	arg = make_int (-XFIXNUM (arg));
271     }
272   else if (FLOATP (arg))
273     {
274       if (signbit (XFLOAT_DATA (arg)))
275 	arg = make_float (- XFLOAT_DATA (arg));
276     }
277   else
278     {
279       if (mpz_sgn (*xbignum_val (arg)) < 0)
280 	{
281 	  mpz_neg (mpz[0], *xbignum_val (arg));
282 	  arg = make_integer_mpz ();
283 	}
284     }
285 
286   return arg;
287 }
288 
289 DEFUN ("float", Ffloat, Sfloat, 1, 1, 0,
290        doc: /* Return the floating point number equal to ARG.  */)
291   (register Lisp_Object arg)
292 {
293   CHECK_NUMBER (arg);
294   /* If ARG is a float, give 'em the same float back.  */
295   return FLOATP (arg) ? arg : make_float (XFLOATINT (arg));
296 }
297 
298 static int
ecount_leading_zeros(EMACS_UINT x)299 ecount_leading_zeros (EMACS_UINT x)
300 {
301   return (EMACS_UINT_WIDTH == UINT_WIDTH ? count_leading_zeros (x)
302 	  : EMACS_UINT_WIDTH == ULONG_WIDTH ? count_leading_zeros_l (x)
303 	  : count_leading_zeros_ll (x));
304 }
305 
306 DEFUN ("logb", Flogb, Slogb, 1, 1, 0,
307        doc: /* Returns largest integer <= the base 2 log of the magnitude of ARG.
308 This is the same as the exponent of a float.  */)
309   (Lisp_Object arg)
310 {
311   EMACS_INT value;
312   CHECK_NUMBER (arg);
313 
314   if (FLOATP (arg))
315     {
316       double f = XFLOAT_DATA (arg);
317       if (f == 0)
318 	return make_float (-HUGE_VAL);
319       if (!isfinite (f))
320 	return f < 0 ? make_float (-f) : arg;
321       int ivalue;
322       frexp (f, &ivalue);
323       value = ivalue - 1;
324     }
325   else if (!FIXNUMP (arg))
326     value = mpz_sizeinbase (*xbignum_val (arg), 2) - 1;
327   else
328     {
329       EMACS_INT i = XFIXNUM (arg);
330       if (i == 0)
331 	return make_float (-HUGE_VAL);
332       value = EMACS_UINT_WIDTH - 1 - ecount_leading_zeros (eabs (i));
333     }
334 
335   return make_fixnum (value);
336 }
337 
338 /* Return the integer exponent E such that D * FLT_RADIX**E (i.e.,
339    scalbn (D, E)) is an integer that has precision equal to D and is
340    representable as a double.
341 
342    Return DBL_MANT_DIG - DBL_MIN_EXP (the maximum possible valid
343    scale) if D is zero or tiny.  Return one greater than that if
344    D is infinite, and two greater than that if D is a NaN.  */
345 
346 int
double_integer_scale(double d)347 double_integer_scale (double d)
348 {
349   int exponent = ilogb (d);
350 #ifdef HAIKU
351   /* On Haiku, the values returned by ilogb are nonsensical when
352      confronted with tiny numbers, inf, or NaN, which breaks the trick
353      used by code on other platforms, so we have to test for each case
354      manually, and return the appropriate value.  */
355   if (exponent == FP_ILOGB0)
356     {
357       if (isnan (d))
358 	return (DBL_MANT_DIG - DBL_MIN_EXP) + 2;
359       if (isinf (d))
360 	return (DBL_MANT_DIG - DBL_MIN_EXP) + 1;
361 
362       return (DBL_MANT_DIG - DBL_MIN_EXP);
363     }
364 #endif
365   return (DBL_MIN_EXP - 1 <= exponent && exponent < INT_MAX
366 	  ? DBL_MANT_DIG - 1 - exponent
367 	  : (DBL_MANT_DIG - DBL_MIN_EXP
368 	     + (isnan (d) ? 2 : exponent == INT_MAX)));
369 }
370 
371 /* Convert the Lisp number N to an integer and return a pointer to the
372    converted integer, represented as an mpz_t *.  Use *T as a
373    temporary; the returned value might be T.  Scale N by the maximum
374    of NSCALE and DSCALE while converting.  If NSCALE is nonzero, N
375    must be a float; signal an overflow if NSCALE is greater than
376    DBL_MANT_DIG - DBL_MIN_EXP, otherwise scalbn (XFLOAT_DATA (N), NSCALE)
377    must return an integer value, without rounding or overflow.  */
378 
379 static mpz_t const *
rescale_for_division(Lisp_Object n,mpz_t * t,int nscale,int dscale)380 rescale_for_division (Lisp_Object n, mpz_t *t, int nscale, int dscale)
381 {
382   mpz_t const *pn;
383 
384   if (FLOATP (n))
385     {
386       if (DBL_MANT_DIG - DBL_MIN_EXP < nscale)
387 	overflow_error ();
388       mpz_set_d (*t, scalbn (XFLOAT_DATA (n), nscale));
389       pn = t;
390     }
391   else
392     pn = bignum_integer (t, n);
393 
394   if (nscale < dscale)
395     {
396       emacs_mpz_mul_2exp (*t, *pn, (dscale - nscale) * LOG2_FLT_RADIX);
397       pn = t;
398     }
399   return pn;
400 }
401 
402 /* the rounding functions  */
403 
404 static Lisp_Object
rounding_driver(Lisp_Object n,Lisp_Object d,double (* double_round)(double),void (* int_divide)(mpz_t,mpz_t const,mpz_t const),EMACS_INT (* fixnum_divide)(EMACS_INT,EMACS_INT))405 rounding_driver (Lisp_Object n, Lisp_Object d,
406 		 double (*double_round) (double),
407 		 void (*int_divide) (mpz_t, mpz_t const, mpz_t const),
408 		 EMACS_INT (*fixnum_divide) (EMACS_INT, EMACS_INT))
409 {
410   CHECK_NUMBER (n);
411 
412   if (NILP (d))
413     return FLOATP (n) ? double_to_integer (double_round (XFLOAT_DATA (n))) : n;
414 
415   CHECK_NUMBER (d);
416 
417   int dscale = 0;
418   if (FIXNUMP (d))
419     {
420       if (XFIXNUM (d) == 0)
421 	xsignal0 (Qarith_error);
422 
423       /* Divide fixnum by fixnum specially, for speed.  */
424       if (FIXNUMP (n))
425 	return make_int (fixnum_divide (XFIXNUM (n), XFIXNUM (d)));
426     }
427   else if (FLOATP (d))
428     {
429       if (XFLOAT_DATA (d) == 0)
430 	xsignal0 (Qarith_error);
431       dscale = double_integer_scale (XFLOAT_DATA (d));
432     }
433 
434   int nscale = FLOATP (n) ? double_integer_scale (XFLOAT_DATA (n)) : 0;
435 
436   /* If the numerator is finite and the denominator infinite, the
437      quotient is zero and there is no need to try the impossible task
438      of rescaling the denominator.  */
439   if (dscale == DBL_MANT_DIG - DBL_MIN_EXP + 1 && nscale < dscale)
440     return make_fixnum (0);
441 
442   int_divide (mpz[0],
443 	      *rescale_for_division (n, &mpz[0], nscale, dscale),
444 	      *rescale_for_division (d, &mpz[1], dscale, nscale));
445   return make_integer_mpz ();
446 }
447 
448 static EMACS_INT
ceiling2(EMACS_INT n,EMACS_INT d)449 ceiling2 (EMACS_INT n, EMACS_INT d)
450 {
451   return n / d + ((n % d != 0) & ((n < 0) == (d < 0)));
452 }
453 
454 static EMACS_INT
floor2(EMACS_INT n,EMACS_INT d)455 floor2 (EMACS_INT n, EMACS_INT d)
456 {
457   return n / d - ((n % d != 0) & ((n < 0) != (d < 0)));
458 }
459 
460 static EMACS_INT
truncate2(EMACS_INT n,EMACS_INT d)461 truncate2 (EMACS_INT n, EMACS_INT d)
462 {
463   return n / d;
464 }
465 
466 static EMACS_INT
round2(EMACS_INT n,EMACS_INT d)467 round2 (EMACS_INT n, EMACS_INT d)
468 {
469   /* The C language's division operator gives us the remainder R
470      corresponding to truncated division, but we want the remainder R1
471      on the other side of 0 if R1 is closer to 0 than R is; because we
472      want to round to even, we also want R1 if R and R1 are the same
473      distance from 0 and if the truncated quotient is odd.  */
474   EMACS_INT q = n / d;
475   EMACS_INT r = n % d;
476   bool neg_d = d < 0;
477   bool neg_r = r < 0;
478   EMACS_INT abs_r = eabs (r);
479   EMACS_INT abs_r1 = eabs (d) - abs_r;
480   if (abs_r1 < abs_r + (q & 1))
481     q += neg_d == neg_r ? 1 : -1;
482   return q;
483 }
484 
485 static void
rounddiv_q(mpz_t q,mpz_t const n,mpz_t const d)486 rounddiv_q (mpz_t q, mpz_t const n, mpz_t const d)
487 {
488   /* Mimic the source code of round2, using mpz_t instead of EMACS_INT.  */
489   mpz_t *r = &mpz[2], *abs_r = r, *abs_r1 = &mpz[3];
490   mpz_tdiv_qr (q, *r, n, d);
491   bool neg_d = mpz_sgn (d) < 0;
492   bool neg_r = mpz_sgn (*r) < 0;
493   mpz_abs (*abs_r, *r);
494   mpz_abs (*abs_r1, d);
495   mpz_sub (*abs_r1, *abs_r1, *abs_r);
496   if (mpz_cmp (*abs_r1, *abs_r) < (mpz_odd_p (q) != 0))
497     (neg_d == neg_r ? mpz_add_ui : mpz_sub_ui) (q, q, 1);
498 }
499 
500 /* The code uses emacs_rint, so that it works to undefine HAVE_RINT
501    if `rint' exists but does not work right.  */
502 #ifdef HAVE_RINT
503 #define emacs_rint rint
504 #else
505 static double
emacs_rint(double d)506 emacs_rint (double d)
507 {
508   double d1 = d + 0.5;
509   double r = floor (d1);
510   return r - (r == d1 && fmod (r, 2) != 0);
511 }
512 #endif
513 
514 #ifndef HAVE_TRUNC
515 double
trunc(double d)516 trunc (double d)
517 {
518   return (d < 0 ? ceil : floor) (d);
519 }
520 #endif
521 
522 DEFUN ("ceiling", Fceiling, Sceiling, 1, 2, 0,
523        doc: /* Return the smallest integer no less than ARG.
524 This rounds the value towards +inf.
525 With optional DIVISOR, return the smallest integer no less than ARG/DIVISOR.  */)
526   (Lisp_Object arg, Lisp_Object divisor)
527 {
528   return rounding_driver (arg, divisor, ceil, mpz_cdiv_q, ceiling2);
529 }
530 
531 DEFUN ("floor", Ffloor, Sfloor, 1, 2, 0,
532        doc: /* Return the largest integer no greater than ARG.
533 This rounds the value towards -inf.
534 With optional DIVISOR, return the largest integer no greater than ARG/DIVISOR.  */)
535   (Lisp_Object arg, Lisp_Object divisor)
536 {
537   return rounding_driver (arg, divisor, floor, mpz_fdiv_q, floor2);
538 }
539 
540 DEFUN ("round", Fround, Sround, 1, 2, 0,
541        doc: /* Return the nearest integer to ARG.
542 With optional DIVISOR, return the nearest integer to ARG/DIVISOR.
543 
544 Rounding a value equidistant between two integers may choose the
545 integer closer to zero, or it may prefer an even integer, depending on
546 your machine.  For example, (round 2.5) can return 3 on some
547 systems, but 2 on others.  */)
548   (Lisp_Object arg, Lisp_Object divisor)
549 {
550   return rounding_driver (arg, divisor, emacs_rint, rounddiv_q, round2);
551 }
552 
553 /* Since rounding_driver truncates anyway, no need to call 'trunc'.  */
554 static double
identity(double x)555 identity (double x)
556 {
557   return x;
558 }
559 
560 DEFUN ("truncate", Ftruncate, Struncate, 1, 2, 0,
561        doc: /* Truncate a floating point number to an int.
562 Rounds ARG toward zero.
563 With optional DIVISOR, truncate ARG/DIVISOR.  */)
564   (Lisp_Object arg, Lisp_Object divisor)
565 {
566   return rounding_driver (arg, divisor, identity, mpz_tdiv_q, truncate2);
567 }
568 
569 
570 Lisp_Object
fmod_float(Lisp_Object x,Lisp_Object y)571 fmod_float (Lisp_Object x, Lisp_Object y)
572 {
573   double f1 = XFLOATINT (x);
574   double f2 = XFLOATINT (y);
575 
576   f1 = fmod (f1, f2);
577 
578   /* If the "remainder" comes out with the wrong sign, fix it.  */
579   if (f2 < 0 ? f1 > 0 : f1 < 0)
580     f1 += f2;
581 
582   return make_float (f1);
583 }
584 
585 DEFUN ("fceiling", Ffceiling, Sfceiling, 1, 1, 0,
586        doc: /* Return the smallest integer no less than ARG, as a float.
587 \(Round toward +inf.)  */)
588   (Lisp_Object arg)
589 {
590   CHECK_FLOAT (arg);
591   double d = XFLOAT_DATA (arg);
592   d = ceil (d);
593   return make_float (d);
594 }
595 
596 DEFUN ("ffloor", Fffloor, Sffloor, 1, 1, 0,
597        doc: /* Return the largest integer no greater than ARG, as a float.
598 \(Round toward -inf.)  */)
599   (Lisp_Object arg)
600 {
601   CHECK_FLOAT (arg);
602   double d = XFLOAT_DATA (arg);
603   d = floor (d);
604   return make_float (d);
605 }
606 
607 DEFUN ("fround", Ffround, Sfround, 1, 1, 0,
608        doc: /* Return the nearest integer to ARG, as a float.  */)
609   (Lisp_Object arg)
610 {
611   CHECK_FLOAT (arg);
612   double d = XFLOAT_DATA (arg);
613   d = emacs_rint (d);
614   return make_float (d);
615 }
616 
617 DEFUN ("ftruncate", Fftruncate, Sftruncate, 1, 1, 0,
618        doc: /* Truncate a floating point number to an integral float value.
619 \(Round toward zero.)  */)
620   (Lisp_Object arg)
621 {
622   CHECK_FLOAT (arg);
623   double d = XFLOAT_DATA (arg);
624   d = trunc (d);
625   return make_float (d);
626 }
627 
628 void
syms_of_floatfns(void)629 syms_of_floatfns (void)
630 {
631   defsubr (&Sacos);
632   defsubr (&Sasin);
633   defsubr (&Satan);
634   defsubr (&Scos);
635   defsubr (&Ssin);
636   defsubr (&Stan);
637   defsubr (&Sisnan);
638   defsubr (&Scopysign);
639   defsubr (&Sfrexp);
640   defsubr (&Sldexp);
641   defsubr (&Sfceiling);
642   defsubr (&Sffloor);
643   defsubr (&Sfround);
644   defsubr (&Sftruncate);
645   defsubr (&Sexp);
646   defsubr (&Sexpt);
647   defsubr (&Slog);
648   defsubr (&Ssqrt);
649 
650   defsubr (&Sabs);
651   defsubr (&Sfloat);
652   defsubr (&Slogb);
653   defsubr (&Sceiling);
654   defsubr (&Sfloor);
655   defsubr (&Sround);
656   defsubr (&Struncate);
657 }
658