/* Primitive operations on floating point for GNU Emacs Lisp interpreter.
-Copyright (C) 1988, 1993-1994, 1999, 2001-2011
+Copyright (C) 1988, 1993-1994, 1999, 2001-2012
Free Software Foundation, Inc.
Author: Wolfgang Rupprecht
#include "lisp.h"
#include "syssignal.h"
-#if STDC_HEADERS
#include <float.h>
-#endif
-
/* If IEEE_FLOATING_POINT isn't defined, default it from FLT_*. */
#ifndef IEEE_FLOATING_POINT
#if (FLT_RADIX == 2 && FLT_MANT_DIG == 24 \
extern double logb (double);
#endif /* not HPUX and HAVE_LOGB and no logb macro */
-#if defined(DOMAIN) && defined(SING) && defined(OVERFLOW)
+#if defined (DOMAIN) && defined (SING) && defined (OVERFLOW)
/* If those are defined, then this is probably a `matherr' machine. */
# ifndef HAVE_MATHERR
# define HAVE_MATHERR
return make_float (d);
}
-#if defined HAVE_ISNAN && defined HAVE_COPYSIGN
+#undef isnan
+#define isnan(x) ((x) != (x))
+
DEFUN ("isnan", Fisnan, Sisnan, 1, 1, 0,
doc: /* Return non nil iff argument X is a NaN. */)
(Lisp_Object x)
return isnan (XFLOAT_DATA (x)) ? Qt : Qnil;
}
-DEFUN ("copysign", Fcopysign, Scopysign, 1, 2, 0,
+#ifdef HAVE_COPYSIGN
+DEFUN ("copysign", Fcopysign, Scopysign, 2, 2, 0,
doc: /* Copy sign of X2 to value of X1, and return the result.
Cause an error if X1 or X2 is not a float. */)
(Lisp_Object x1, Lisp_Object x2)
y = XINT (arg2);
acc = 1;
- if ((x == 0 && y != 0) || x == 1 || (x == -1 && (y & 1)))
- return arg1;
- if (x == -1)
- y = 0;
-
- while (1)
+ if (y < 0)
{
- if (y & 1)
- {
- if (x < 0
- ? (acc < 0
- ? acc < MOST_POSITIVE_FIXNUM / x
- : MOST_NEGATIVE_FIXNUM / x < acc)
- : (acc < 0
- ? acc < MOST_NEGATIVE_FIXNUM / x
- : MOST_POSITIVE_FIXNUM / x < acc))
- break;
- acc *= x;
- }
-
- y >>= 1;
- if (y == 0)
+ if (x == 1)
+ acc = 1;
+ else if (x == -1)
+ acc = (y & 1) ? -1 : 1;
+ else
+ acc = 0;
+ }
+ else
+ {
+ while (y > 0)
{
- XSETINT (val, acc);
- return val;
+ if (y & 1)
+ acc *= x;
+ x *= x;
+ y >>= 1;
}
-
- if (x < 0
- ? x < MOST_POSITIVE_FIXNUM / x
- : MOST_POSITIVE_FIXNUM / x < x)
- break;
- x *= x;
}
+ XSETINT (val, acc);
+ return val;
}
f1 = FLOATP (arg1) ? XFLOAT_DATA (arg1) : XINT (arg1);
f2 = FLOATP (arg2) ? XFLOAT_DATA (arg2) : XINT (arg2);
if (f1 == 0.0 && f2 == 0.0)
f1 = 1.0;
#ifdef FLOAT_CHECK_DOMAIN
- else if ((f1 == 0.0 && f2 < 0.0) || (f1 < 0 && f2 != floor(f2)))
+ else if ((f1 == 0.0 && f2 < 0.0) || (f1 < 0 && f2 != floor (f2)))
domain_error2 ("expt", arg1, arg2);
#endif
IN_FLOAT2 (f3 = pow (f1, f2), "expt", arg1, arg2);
\f
#ifdef FLOAT_CATCH_SIGILL
static void
-float_error (signo)
- int signo;
+float_error (int signo)
{
if (! in_float)
fatal_error_signal (signo);
defsubr (&Scos);
defsubr (&Ssin);
defsubr (&Stan);
-#if defined HAVE_ISNAN && defined HAVE_COPYSIGN
defsubr (&Sisnan);
+#ifdef HAVE_COPYSIGN
defsubr (&Scopysign);
defsubr (&Sfrexp);
defsubr (&Sldexp);