Commit f6196b87 authored by Paul Eggert's avatar Paul Eggert
Browse files

Assume C89 or later for math functions.

This simplifies the code, and makes it a bit smaller and faster,
and (most important) makes it easier to clean up signal handling
since we can stop worring about floating-point exceptions in
library code.  That was a problem before C89, but the problem
went away many years ago on all practical Emacs targets.
* configure.ac (frexp, fmod): Remove checks for these functions,
as we now assume them.
(FLOAT_CHECK_DOMAIN, HAVE_INVERSE_HYPERBOLIC, NO_MATHERR)
(HAVE_EXCEPTION):
Remove; no longer needed.
* admin/CPP-DEFINES (HAVE_FMOD, HAVE_FREXP, FLOAT_CHECK_DOMAIN)
(HAVE_INVERSE_HYPERBOLIC, NO_MATHERR): Remove.
* src/data.c, src/image.c, src/lread.c, src/print.c:
Don't include <math.h>; no longer needed.
* src/data.c, src/floatfns.c (IEEE_FLOATING_POINT): Don't worry that it
might be autoconfigured, as that never happens.
* src/data.c (fmod):
* src/doprnt.c (DBL_MAX_10_EXP):
* src/print.c (DBL_DIG):
Remove.  C89 or later always defines these.
* src/floatfns.c (HAVE_MATHERR, FLOAT_CHECK_ERRNO, FLOAT_CHECK_DOMAIN)
(in_float, float_error_arg, float_error_arg2, float_error_fn_name)
(arith_error, domain_error, domain_error2):
Remove all this pre-C89 cruft.  Do not include <errno.h> as that's
no longer needed -- we simply return what C returns.  All uses removed.
(IN_FLOAT, IN_FLOAT2): Remove.  All uses replaced with
the wrapped code.
(FLOAT_TO_INT, FLOAT_TO_INT2, range_error, range_error2):
Remove.  All uses expanded, as these macros are no longer used
more than once and are now more trouble than they're worth.
(Ftan): Use tan, not sin / cos.
(Flogb): Assume C89 frexp.
(fmod_float): Assume C89 fmod.
(matherr) [HAVE_MATHERR]: Remove; no longer needed.
(init_floatfns): Remove.  All uses removed.
parent 8ed43f15
2012-09-09 Paul Eggert <eggert@cs.ucla.edu>
Assume C89 or later for math functions (Bug#12381).
* configure.ac (frexp, fmod): Remove checks for these functions,
as we now assume them.
(FLOAT_CHECK_DOMAIN, HAVE_INVERSE_HYPERBOLIC, NO_MATHERR)
(HAVE_EXCEPTION):
Remove; no longer needed.
2012-09-07 Paul Eggert <eggert@cs.ucla.edu> 2012-09-07 Paul Eggert <eggert@cs.ucla.edu>
More signal-handler cleanup (Bug#12327). More signal-handler cleanup (Bug#12327).
......
...@@ -107,7 +107,6 @@ EMACS_CONFIGURATION ...@@ -107,7 +107,6 @@ EMACS_CONFIGURATION
EMACS_CONFIG_OPTIONS EMACS_CONFIG_OPTIONS
EMACS_INT EMACS_INT
EMACS_UINT EMACS_UINT
FLOAT_CHECK_DOMAIN
GC_MARK_SECONDARY_STACK GC_MARK_SECONDARY_STACK
GC_MARK_STACK GC_MARK_STACK
GC_SETJMP_WORKS GC_SETJMP_WORKS
...@@ -158,12 +157,10 @@ HAVE_ENDPWENT ...@@ -158,12 +157,10 @@ HAVE_ENDPWENT
HAVE_ENVIRON_DECL HAVE_ENVIRON_DECL
HAVE_EUIDACCESS HAVE_EUIDACCESS
HAVE_FCNTL_H HAVE_FCNTL_H
HAVE_FMOD
HAVE_FORK HAVE_FORK
HAVE_FPATHCONF HAVE_FPATHCONF
HAVE_FREEIFADDRS HAVE_FREEIFADDRS
HAVE_FREETYPE HAVE_FREETYPE
HAVE_FREXP
HAVE_FSEEKO HAVE_FSEEKO
HAVE_FSYNC HAVE_FSYNC
HAVE_FUTIMENS HAVE_FUTIMENS
...@@ -217,7 +214,6 @@ HAVE_IFADDRS_H ...@@ -217,7 +214,6 @@ HAVE_IFADDRS_H
HAVE_IMAGEMAGICK HAVE_IMAGEMAGICK
HAVE_INET_SOCKETS HAVE_INET_SOCKETS
HAVE_INTTYPES_H HAVE_INTTYPES_H
HAVE_INVERSE_HYPERBOLIC
HAVE_JPEG HAVE_JPEG
HAVE_KERBEROSIV_DES_H HAVE_KERBEROSIV_DES_H
HAVE_KERBEROSIV_KRB_H HAVE_KERBEROSIV_KRB_H
...@@ -429,7 +425,6 @@ MAIL_USE_SYSTEM_LOCK ...@@ -429,7 +425,6 @@ MAIL_USE_SYSTEM_LOCK
MAXPATHLEN MAXPATHLEN
NLIST_STRUCT NLIST_STRUCT
NO_EDITRES NO_EDITRES
NO_MATHERR
NO_TERMIO NO_TERMIO
NSIG NSIG
NSIG_MINIMUM NSIG_MINIMUM
......
2012-09-09 Paul Eggert <eggert@cs.ucla.edu>
Assume C89 or later for math functions (Bug#12381).
* CPP-DEFINES (HAVE_FMOD, HAVE_FREXP, FLOAT_CHECK_DOMAIN)
(HAVE_INVERSE_HYPERBOLIC, NO_MATHERR): Remove.
2012-09-04 Paul Eggert <eggert@cs.ucla.edu> 2012-09-04 Paul Eggert <eggert@cs.ucla.edu>
Simplify redefinition of 'abort' (Bug#12316). Simplify redefinition of 'abort' (Bug#12316).
......
...@@ -1302,17 +1302,6 @@ if test $emacs_cv_speed_t = yes; then ...@@ -1302,17 +1302,6 @@ if test $emacs_cv_speed_t = yes; then
[Define to 1 if `speed_t' is declared by <termios.h>.]) [Define to 1 if `speed_t' is declared by <termios.h>.])
fi fi
AC_CACHE_CHECK(for struct exception, emacs_cv_struct_exception,
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <math.h>]],
[[static struct exception x; x.arg1 = x.arg2 = x.retval; x.name = ""; x.type = 1;]])],
emacs_cv_struct_exception=yes, emacs_cv_struct_exception=no))
HAVE_EXCEPTION=$emacs_cv_struct_exception
dnl Define on Darwin so emacs symbols will not conflict with those
dnl in the System framework. Otherwise -prebind will not work.
if test $emacs_cv_struct_exception != yes || test $opsys = darwin; then
AC_DEFINE(NO_MATHERR, 1, [Define to 1 if you don't have struct exception in math.h.])
fi
AC_CHECK_HEADERS_ONCE(sys/socket.h) AC_CHECK_HEADERS_ONCE(sys/socket.h)
AC_CHECK_HEADERS(net/if.h, , , [AC_INCLUDES_DEFAULT AC_CHECK_HEADERS(net/if.h, , , [AC_INCLUDES_DEFAULT
#if HAVE_SYS_SOCKET_H #if HAVE_SYS_SOCKET_H
...@@ -2781,7 +2770,7 @@ AC_SUBST(BLESSMAIL_TARGET) ...@@ -2781,7 +2770,7 @@ AC_SUBST(BLESSMAIL_TARGET)
AC_CHECK_FUNCS(gethostname \ AC_CHECK_FUNCS(gethostname \
closedir getrusage get_current_dir_name \ closedir getrusage get_current_dir_name \
lrand48 logb frexp fmod cbrt setsid \ lrand48 logb cbrt setsid \
fpathconf select euidaccess getpagesize setlocale \ fpathconf select euidaccess getpagesize setlocale \
utimes getrlimit setrlimit setpgid getcwd shutdown getaddrinfo \ utimes getrlimit setrlimit setpgid getcwd shutdown getaddrinfo \
__fpending strsignal setitimer \ __fpending strsignal setitimer \
...@@ -3211,12 +3200,6 @@ AC_DEFINE(CLASH_DETECTION, 1, [Define if you want lock files to be written, ...@@ -3211,12 +3200,6 @@ AC_DEFINE(CLASH_DETECTION, 1, [Define if you want lock files to be written,
so that Emacs can tell instantly when you try to modify a file that so that Emacs can tell instantly when you try to modify a file that
someone else has modified in his/her Emacs.]) someone else has modified in his/her Emacs.])
AH_TEMPLATE(FLOAT_CHECK_DOMAIN, [Define if the float library doesn't
handle errors by either setting errno, or signaling SIGFPE.])
AH_TEMPLATE(HAVE_INVERSE_HYPERBOLIC, [Define if you have the functions
acosh, asinh, and atanh.])
dnl Everybody supports this, except MS. dnl Everybody supports this, except MS.
dnl Seems like the kind of thing we should be testing for, though. dnl Seems like the kind of thing we should be testing for, though.
## Note: PTYs are broken on darwin <6. Use at your own risk. ## Note: PTYs are broken on darwin <6. Use at your own risk.
......
2012-09-09 Paul Eggert <eggert@cs.ucla.edu>
Assume C89 or later for math functions (Bug#12381).
This simplifies the code, and makes it a bit smaller and faster,
and (most important) makes it easier to clean up signal handling
since we can stop worring about floating-point exceptions in
library code. That was a problem before C89, but the problem
went away many years ago on all practical Emacs targets.
* data.c, image.c, lread.c, print.c:
Don't include <math.h>; no longer needed.
* data.c, floatfns.c (IEEE_FLOATING_POINT): Don't worry that it
might be autoconfigured, as that never happens.
* data.c (fmod):
* doprnt.c (DBL_MAX_10_EXP):
* print.c (DBL_DIG):
Remove. C89 or later always defines these.
* floatfns.c (HAVE_MATHERR, FLOAT_CHECK_ERRNO, FLOAT_CHECK_DOMAIN)
(in_float, float_error_arg, float_error_arg2, float_error_fn_name)
(arith_error, domain_error, domain_error2):
Remove all this pre-C89 cruft. Do not include <errno.h> as that's
no longer needed -- we simply return what C returns. All uses removed.
(IN_FLOAT, IN_FLOAT2): Remove. All uses replaced with
the wrapped code.
(FLOAT_TO_INT, FLOAT_TO_INT2, range_error, range_error2):
Remove. All uses expanded, as these macros are no longer used
more than once and are now more trouble than they're worth.
(Ftan): Use tan, not sin / cos.
(Flogb): Assume C89 frexp.
(fmod_float): Assume C89 fmod.
(matherr) [HAVE_MATHERR]: Remove; no longer needed.
(init_floatfns): Remove. All uses removed.
2012-09-08 Jan Djärv <jan.h.d@swipnet.se> 2012-09-08 Jan Djärv <jan.h.d@swipnet.se>
* nsterm.m (ns_draw_fringe_bitmap, ns_dumpglyphs_image): Take back * nsterm.m (ns_draw_fringe_bitmap, ns_dumpglyphs_image): Take back
......
...@@ -36,17 +36,12 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ ...@@ -36,17 +36,12 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "keymap.h" #include "keymap.h"
#include <float.h> #include <float.h>
/* If IEEE_FLOATING_POINT isn't defined, default it from FLT_*. */
#ifndef IEEE_FLOATING_POINT
#if (FLT_RADIX == 2 && FLT_MANT_DIG == 24 \ #if (FLT_RADIX == 2 && FLT_MANT_DIG == 24 \
&& FLT_MIN_EXP == -125 && FLT_MAX_EXP == 128) && FLT_MIN_EXP == -125 && FLT_MAX_EXP == 128)
#define IEEE_FLOATING_POINT 1 #define IEEE_FLOATING_POINT 1
#else #else
#define IEEE_FLOATING_POINT 0 #define IEEE_FLOATING_POINT 0
#endif #endif
#endif
#include <math.h>
Lisp_Object Qnil, Qt, Qquote, Qlambda, Qunbound; Lisp_Object Qnil, Qt, Qquote, Qlambda, Qunbound;
static Lisp_Object Qsubr; static Lisp_Object Qsubr;
...@@ -2737,28 +2732,6 @@ Both must be integers or markers. */) ...@@ -2737,28 +2732,6 @@ Both must be integers or markers. */)
return val; return val;
} }
#ifndef HAVE_FMOD
double
fmod (double f1, double f2)
{
double r = f1;
if (f2 < 0.0)
f2 = -f2;
/* If the magnitude of the result exceeds that of the divisor, or
the sign of the result does not agree with that of the dividend,
iterate with the reduced value. This does not yield a
particularly accurate result, but at least it will be in the
range promised by fmod. */
do
r -= f2 * floor (r / f2);
while (f2 <= (r < 0 ? -r : r) || ((r < 0) != (f1 < 0) && ! isnan (r)));
return r;
}
#endif /* ! HAVE_FMOD */
DEFUN ("mod", Fmod, Smod, 2, 2, 0, DEFUN ("mod", Fmod, Smod, 2, 2, 0,
doc: /* Return X modulo Y. doc: /* Return X modulo Y.
The result falls between zero (inclusive) and Y (exclusive). The result falls between zero (inclusive) and Y (exclusive).
......
...@@ -114,10 +114,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ ...@@ -114,10 +114,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
another macro. */ another macro. */
#include "character.h" #include "character.h"
#ifndef DBL_MAX_10_EXP
#define DBL_MAX_10_EXP 308 /* IEEE double */
#endif
/* Generate output from a format-spec FORMAT, /* Generate output from a format-spec FORMAT,
terminated at position FORMAT_END. terminated at position FORMAT_END.
(*FORMAT_END is not part of the format, but must exist and be readable.) (*FORMAT_END is not part of the format, but must exist and be readable.)
......
...@@ -1587,7 +1587,6 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem ...@@ -1587,7 +1587,6 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
init_fringe (); init_fringe ();
#endif /* HAVE_WINDOW_SYSTEM */ #endif /* HAVE_WINDOW_SYSTEM */
init_macros (); init_macros ();
init_floatfns ();
init_window (); init_window ();
init_font (); init_font ();
......
...@@ -22,26 +22,9 @@ You should have received a copy of the GNU General Public License ...@@ -22,26 +22,9 @@ You should have received a copy of the GNU General Public License
along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
/* ANSI C requires only these float functions: /* C89 requires only these math.h functions:
acos, asin, atan, atan2, ceil, cos, cosh, exp, fabs, floor, fmod, 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, modf, pow, sin, sinh, sqrt, tan, tanh.
Define HAVE_INVERSE_HYPERBOLIC if you have acosh, asinh, and atanh.
Define HAVE_CBRT if you have cbrt.
Define HAVE_RINT if you have a working rint.
If you don't define these, then the appropriate routines will be simulated.
Define HAVE_MATHERR if on a system supporting the SysV matherr callback.
(This should happen automatically.)
Define FLOAT_CHECK_ERRNO if the float library routines set errno.
This has no effect if HAVE_MATHERR is defined.
Define FLOAT_CHECK_DOMAIN if the float library doesn't handle errors by
either setting errno, or signaling SIGFPE. Otherwise, domain and
range checking will happen before calling the float routines. This has
no effect if HAVE_MATHERR is defined (since matherr will be called when
a domain error occurs.)
*/ */
#include <config.h> #include <config.h>
...@@ -50,15 +33,12 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ ...@@ -50,15 +33,12 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "syssignal.h" #include "syssignal.h"
#include <float.h> #include <float.h>
/* If IEEE_FLOATING_POINT isn't defined, default it from FLT_*. */
#ifndef IEEE_FLOATING_POINT
#if (FLT_RADIX == 2 && FLT_MANT_DIG == 24 \ #if (FLT_RADIX == 2 && FLT_MANT_DIG == 24 \
&& FLT_MIN_EXP == -125 && FLT_MAX_EXP == 128) && FLT_MIN_EXP == -125 && FLT_MAX_EXP == 128)
#define IEEE_FLOATING_POINT 1 #define IEEE_FLOATING_POINT 1
#else #else
#define IEEE_FLOATING_POINT 0 #define IEEE_FLOATING_POINT 0
#endif #endif
#endif
#include <math.h> #include <math.h>
...@@ -67,120 +47,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ ...@@ -67,120 +47,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
extern double logb (double); extern double logb (double);
#endif /* not HPUX and HAVE_LOGB and no logb macro */ #endif /* not HPUX and HAVE_LOGB and no logb macro */
#if defined (DOMAIN) && defined (SING) && defined (OVERFLOW)
/* If those are defined, then this is probably a `matherr' machine. */
# ifndef HAVE_MATHERR
# define HAVE_MATHERR
# endif
#endif
#ifdef NO_MATHERR
#undef HAVE_MATHERR
#endif
#ifdef HAVE_MATHERR
# ifdef FLOAT_CHECK_ERRNO
# undef FLOAT_CHECK_ERRNO
# endif
# ifdef FLOAT_CHECK_DOMAIN
# undef FLOAT_CHECK_DOMAIN
# endif
#endif
#ifndef NO_FLOAT_CHECK_ERRNO
#define FLOAT_CHECK_ERRNO
#endif
#ifdef FLOAT_CHECK_ERRNO
# include <errno.h>
#endif
/* True while executing in floating point.
This tells float_error what to do. */
static bool in_float;
/* If an argument is out of range for a mathematical function,
here is the actual argument value to use in the error message.
These variables are used only across the floating point library call
so there is no need to staticpro them. */
static Lisp_Object float_error_arg, float_error_arg2;
static const char *float_error_fn_name;
/* Evaluate the floating point expression D, recording NUM
as the original argument for error messages.
D is normally an assignment expression.
Handle errors which may result in signals or may set errno.
Note that float_error may be declared to return void, so you can't
just cast the zero after the colon to (void) to make the types
check properly. */
#ifdef FLOAT_CHECK_ERRNO
#define IN_FLOAT(d, name, num) \
do { \
float_error_arg = num; \
float_error_fn_name = name; \
in_float = 1; errno = 0; (d); in_float = 0; \
switch (errno) { \
case 0: break; \
case EDOM: domain_error (float_error_fn_name, float_error_arg); \
case ERANGE: range_error (float_error_fn_name, float_error_arg); \
default: arith_error (float_error_fn_name, float_error_arg); \
} \
} while (0)
#define IN_FLOAT2(d, name, num, num2) \
do { \
float_error_arg = num; \
float_error_arg2 = num2; \
float_error_fn_name = name; \
in_float = 1; errno = 0; (d); in_float = 0; \
switch (errno) { \
case 0: break; \
case EDOM: domain_error (float_error_fn_name, float_error_arg); \
case ERANGE: range_error (float_error_fn_name, float_error_arg); \
default: arith_error (float_error_fn_name, float_error_arg); \
} \
} while (0)
#else
#define IN_FLOAT(d, name, num) (in_float = 1, (d), in_float = 0)
#define IN_FLOAT2(d, name, num, num2) (in_float = 1, (d), in_float = 0)
#endif
/* Convert float to Lisp_Int if it fits, else signal a range error
using the given arguments. */
#define FLOAT_TO_INT(x, i, name, num) \
do \
{ \
if (FIXNUM_OVERFLOW_P (x)) \
range_error (name, num); \
XSETINT (i, (EMACS_INT)(x)); \
} \
while (0)
#define FLOAT_TO_INT2(x, i, name, num1, num2) \
do \
{ \
if (FIXNUM_OVERFLOW_P (x)) \
range_error2 (name, num1, num2); \
XSETINT (i, (EMACS_INT)(x)); \
} \
while (0)
#define arith_error(op,arg) \
xsignal2 (Qarith_error, build_string ((op)), (arg))
#define range_error(op,arg) \
xsignal2 (Qrange_error, build_string ((op)), (arg))
#define range_error2(op,a1,a2) \
xsignal3 (Qrange_error, build_string ((op)), (a1), (a2))
#define domain_error(op,arg) \
xsignal2 (Qdomain_error, build_string ((op)), (arg))
#ifdef FLOAT_CHECK_DOMAIN
#define domain_error2(op,a1,a2) \
xsignal3 (Qdomain_error, build_string ((op)), (a1), (a2))
#endif
/* Extract a Lisp number as a `double', or signal an error. */ /* Extract a Lisp number as a `double', or signal an error. */
double double
...@@ -197,27 +63,19 @@ extract_float (Lisp_Object num) ...@@ -197,27 +63,19 @@ extract_float (Lisp_Object num)
DEFUN ("acos", Facos, Sacos, 1, 1, 0, DEFUN ("acos", Facos, Sacos, 1, 1, 0,
doc: /* Return the inverse cosine of ARG. */) doc: /* Return the inverse cosine of ARG. */)
(register Lisp_Object arg) (Lisp_Object arg)
{ {
double d = extract_float (arg); double d = extract_float (arg);
#ifdef FLOAT_CHECK_DOMAIN d = acos (d);
if (d > 1.0 || d < -1.0)
domain_error ("acos", arg);
#endif
IN_FLOAT (d = acos (d), "acos", arg);
return make_float (d); return make_float (d);
} }
DEFUN ("asin", Fasin, Sasin, 1, 1, 0, DEFUN ("asin", Fasin, Sasin, 1, 1, 0,
doc: /* Return the inverse sine of ARG. */) doc: /* Return the inverse sine of ARG. */)
(register Lisp_Object arg) (Lisp_Object arg)
{ {
double d = extract_float (arg); double d = extract_float (arg);
#ifdef FLOAT_CHECK_DOMAIN d = asin (d);
if (d > 1.0 || d < -1.0)
domain_error ("asin", arg);
#endif
IN_FLOAT (d = asin (d), "asin", arg);
return make_float (d); return make_float (d);
} }
...@@ -227,50 +85,44 @@ If only one argument Y is given, return the inverse tangent of Y. ...@@ -227,50 +85,44 @@ If only one argument Y is given, return the inverse tangent of Y.
If two arguments Y and X are given, return the inverse tangent of Y If two arguments Y and X are given, return the inverse tangent of Y
divided by X, i.e. the angle in radians between the vector (X, Y) divided by X, i.e. the angle in radians between the vector (X, Y)
and the x-axis. */) and the x-axis. */)
(register Lisp_Object y, Lisp_Object x) (Lisp_Object y, Lisp_Object x)
{ {
double d = extract_float (y); double d = extract_float (y);
if (NILP (x)) if (NILP (x))
IN_FLOAT (d = atan (d), "atan", y); d = atan (d);
else else
{ {
double d2 = extract_float (x); double d2 = extract_float (x);
d = atan2 (d, d2);
IN_FLOAT2 (d = atan2 (d, d2), "atan", y, x);
} }
return make_float (d); return make_float (d);
} }
DEFUN ("cos", Fcos, Scos, 1, 1, 0, DEFUN ("cos", Fcos, Scos, 1, 1, 0,
doc: /* Return the cosine of ARG. */) doc: /* Return the cosine of ARG. */)
(register Lisp_Object arg) (Lisp_Object arg)
{ {
double d = extract_float (arg); double d = extract_float (arg);
IN_FLOAT (d = cos (d), "cos", arg); d = cos (d);
return make_float (d); return make_float (d);
} }
DEFUN ("sin", Fsin, Ssin, 1, 1, 0, DEFUN ("sin", Fsin, Ssin, 1, 1, 0,
doc: /* Return the sine of ARG. */) doc: /* Return the sine of ARG. */)
(register Lisp_Object arg) (Lisp_Object arg)
{ {
double d = extract_float (arg); double d = extract_float (arg);
IN_FLOAT (d = sin (d), "sin", arg); d = sin (d);
return make_float (d); return make_float (d);
} }
DEFUN ("tan", Ftan, Stan, 1, 1, 0, DEFUN ("tan", Ftan, Stan, 1, 1, 0,
doc: /* Return the tangent of ARG. */) doc: /* Return the tangent of ARG. */)
(register Lisp_Object arg) (Lisp_Object arg)
{ {
double d = extract_float (arg); double d = extract_float (arg);
#ifdef FLOAT_CHECK_DOMAIN d = tan (d);
double c = cos (d);
if (c == 0.0)
domain_error ("tan", arg);
#endif
IN_FLOAT (d = tan (d), "tan", arg);
return make_float (d); return make_float (d);
} }
...@@ -341,61 +193,61 @@ Returns the floating point value resulting from multiplying SGNFCAND ...@@ -341,61 +193,61 @@ Returns the floating point value resulting from multiplying SGNFCAND
DEFUN ("bessel-j0", Fbessel_j0, Sbessel_j0, 1, 1, 0, DEFUN ("bessel-j0", Fbessel_j0, Sbessel_j0, 1, 1, 0,
doc: /* Return the bessel function j0 of ARG. */) doc: /* Return the bessel function j0 of ARG. */)
(register Lisp_Object arg) (Lisp_Object arg)
{ {
double d = extract_float (arg); double d = extract_float (arg);
IN_FLOAT (d = j0 (d), "bessel-j0", arg); d = j0 (d);
return make_float (d); return make_float (d);
} }
DEFUN ("bessel-j1", Fbessel_j1, Sbessel_j1, 1, 1, 0, DEFUN ("bessel-j1", Fbessel_j1, Sbessel_j1, 1, 1, 0,
doc: /* Return the bessel function j1 of ARG. */) doc: /* Return the bessel function j1 of ARG. */)
(register Lisp_Object arg) (Lisp_Object arg)
{ {
double d = extract_float (arg); double d = extract_float (arg);
IN_FLOAT (d = j1 (d), "bessel-j1", arg); d = j1 (d);
return make_float (d); return make_float (d);
} }
DEFUN ("bessel-jn", Fbessel_jn, Sbessel_jn, 2, 2, 0, DEFUN ("bessel-jn", Fbessel_jn, Sbessel_jn, 2, 2, 0,
doc: /* Return the order N bessel function output jn of ARG. doc: /* Return the order N bessel function output jn of ARG.
The first arg (the order) is truncated to an integer. */) The first arg (the order) is truncated to an integer. */)
(register Lisp_Object n, Lisp_Object arg) (Lisp_Object n, Lisp_Object arg)
{ {
int i1 = extract_float (n); int i1 = extract_float (n);
double f2 = extract_float (arg); double f2 = extract_float (arg);
IN_FLOAT (f2 = jn (i1, f2), "bessel-jn", n); f2 = jn (i1, f2);
return make_float (f2); return make_float (f2);
} }
DEFUN ("bessel-y0", Fbessel_y0, Sbessel_y0, 1, 1, 0, DEFUN ("bessel-y0", Fbessel_y0, Sbessel_y0, 1, 1, 0,
doc: /* Return the bessel function y0 of ARG. */) doc: /* Return the bessel function y0 of ARG. */)
(register Lisp_Object arg) (Lisp_Object arg)
{ {
double d = extract_float (arg); double d = extract_float (arg);