X-Git-Url: https://git.hcoop.net/bpt/emacs.git/blobdiff_plain/8c4b24b2ab14be6d33d4e979f3de6fb85eff6518..33813370fcaa4ad70449cc4068154e1e073cb7a9:/src/floatfns.c diff --git a/src/floatfns.c b/src/floatfns.c index 43576a1624..ed0c14926d 100644 --- a/src/floatfns.c +++ b/src/floatfns.c @@ -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 . */ /* 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 @@ -34,12 +45,21 @@ along with GNU Emacs. If not, see . */ #include -#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" }