remove `declare' macro
[bpt/emacs.git] / src / floatfns.c
index 43576a1..ed0c149 100644 (file)
@@ -1,7 +1,6 @@
 /* Primitive operations on floating point for GNU Emacs Lisp interpreter.
 
-Copyright (C) 1988, 1993-1994, 1999, 2001-2013 Free Software Foundation,
-Inc.
+Copyright (C) 1988, 1993-1994, 1999, 2001-2014 Free Software Foundation, Inc.
 
 Author: Wolfgang Rupprecht
 (according to ack.texi)
@@ -25,7 +24,19 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 /* C89 requires only the following math.h functions, and Emacs omits
    the starred functions since we haven't found a use for them:
    acos, asin, atan, atan2, ceil, cos, *cosh, exp, fabs, floor, fmod,
-   frexp, ldexp, log, log10, *modf, pow, sin, *sinh, sqrt, tan, *tanh.
+   frexp, ldexp, log, log10 [via (log X 10)], *modf, pow, sin, *sinh,
+   sqrt, tan, *tanh.
+
+   C99 and C11 require the following math.h functions in addition to
+   the C89 functions.  Of these, Emacs currently exports only the
+   starred ones to Lisp, since we haven't found a use for the others:
+   acosh, atanh, cbrt, *copysign, erf, erfc, exp2, expm1, fdim, fma,
+   fmax, fmin, fpclassify, hypot, ilogb, isfinite, isgreater,
+   isgreaterequal, isinf, isless, islessequal, islessgreater, *isnan,
+   isnormal, isunordered, lgamma, log1p, *log2 [via (log X 2)], *logb
+   (approximately), lrint/llrint, lround/llround, nan, nearbyint,
+   nextafter, nexttoward, remainder, remquo, *rint, round, scalbln,
+   scalbn, signbit, tgamma, trunc.
  */
 
 #include <config.h>
@@ -34,12 +45,21 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <math.h>
 
-#ifndef isfinite
-# define isfinite(x) ((x) - (x) == 0)
-#endif
-#ifndef isnan
-# define isnan(x) ((x) != (x))
-#endif
+/* 'isfinite' and 'isnan' cause build failures on Solaris 10 with the
+   bundled GCC in c99 mode.  Work around the bugs with simple
+   implementations that are good enough.  */
+#undef isfinite
+#define isfinite(x) ((x) - (x) == 0)
+#undef isnan
+#define isnan(x) ((x) != (x))
+
+/* Check that X is a floating point number.  */
+
+static void
+CHECK_FLOAT (Lisp_Object x)
+{
+  CHECK_TYPE (FLOATP (x), Qfloatp, x);
+}
 
 /* Extract a Lisp number as a `double', or signal an error.  */
 
@@ -121,7 +141,7 @@ DEFUN ("tan", Ftan, Stan, 1, 1, 0,
 }
 
 DEFUN ("isnan", Fisnan, Sisnan, 1, 1, 0,
-       doc: /* Return non nil iff argument X is a NaN.  */)
+       doc: /* Return non nil if argument X is a NaN.  */)
   (Lisp_Object x)
 {
   CHECK_FLOAT (x);
@@ -193,7 +213,7 @@ DEFUN ("expt", Fexpt, Sexpt, 2, 2, 0,
   CHECK_NUMBER_OR_FLOAT (arg2);
   if (INTEGERP (arg1)     /* common lisp spec */
       && INTEGERP (arg2)   /* don't promote, if both are ints, and */
-      && 0 <= XINT (arg2)) /* we are sure the result is not fractional */
+      && XINT (arg2) >= 0) /* we are sure the result is not fractional */
     {                          /* this can be improved by pre-calculating */
       EMACS_INT y;             /* some binary powers of x then accumulating */
       EMACS_UINT acc, x;  /* Unsigned so that overflow is well defined.  */
@@ -233,21 +253,16 @@ If the optional argument BASE is given, return log ARG using that base.  */)
 
       if (b == 10.0)
        d = log10 (d);
+#if HAVE_LOG2
+      else if (b == 2.0)
+       d = log2 (d);
+#endif
       else
        d = log (d) / log (b);
     }
   return make_float (d);
 }
 
-DEFUN ("log10", Flog10, Slog10, 1, 1, 0,
-       doc: /* Return the logarithm base 10 of ARG.  */)
-  (Lisp_Object arg)
-{
-  double d = extract_float (arg);
-  d = log10 (d);
-  return make_float (d);
-}
-
 DEFUN ("sqrt", Fsqrt, Ssqrt, 1, 1, 0,
        doc: /* Return the square root of ARG.  */)
   (Lisp_Object arg)
@@ -412,7 +427,9 @@ round2 (EMACS_INT i1, EMACS_INT i2)
 static double
 emacs_rint (double d)
 {
-  return floor (d + 0.5);
+  double d1 = d + 0.5;
+  double r = floor (d1);
+  return r - (r == d1 && fmod (r, 2) != 0);
 }
 #endif
 
@@ -475,7 +492,7 @@ fmod_float (Lisp_Object x, Lisp_Object y)
   f1 = fmod (f1, f2);
 
   /* If the "remainder" comes out with the wrong sign, fix it.  */
-  if (f2 < 0 ? 0 < f1 : f1 < 0)
+  if (f2 < 0 ? f1 > 0 : f1 < 0)
     f1 += f2;
 
   return make_float (f1);
@@ -526,33 +543,5 @@ Rounds the value toward zero.  */)
 void
 syms_of_floatfns (void)
 {
-  defsubr (&Sacos);
-  defsubr (&Sasin);
-  defsubr (&Satan);
-  defsubr (&Scos);
-  defsubr (&Ssin);
-  defsubr (&Stan);
-  defsubr (&Sisnan);
-#ifdef HAVE_COPYSIGN
-  defsubr (&Scopysign);
-#endif
-  defsubr (&Sfrexp);
-  defsubr (&Sldexp);
-  defsubr (&Sfceiling);
-  defsubr (&Sffloor);
-  defsubr (&Sfround);
-  defsubr (&Sftruncate);
-  defsubr (&Sexp);
-  defsubr (&Sexpt);
-  defsubr (&Slog);
-  defsubr (&Slog10);
-  defsubr (&Ssqrt);
-
-  defsubr (&Sabs);
-  defsubr (&Sfloat);
-  defsubr (&Slogb);
-  defsubr (&Sceiling);
-  defsubr (&Sfloor);
-  defsubr (&Sround);
-  defsubr (&Struncate);
+#include "floatfns.x"
 }