Commit c990426a authored by Paul Eggert's avatar Paul Eggert

Simplify, document, and port floating-point.

The porting part of this patch fixes bugs on non-IEEE platforms
with frexp, ldexp, logb.
* admin/CPP-DEFINES (HAVE_CBRT, HAVE_LOGB, logb): Remove.
* configure.ac (logb, cbrt): Do not check for these functions,
as they are not being used.
* doc/lispref/numbers.texi (Float Basics, Arithmetic Operations, Math Functions):
Document that / and mod (with floating point arguments), along
with asin, acos, log, log10, expt and sqrt, return special values
instead of signaling exceptions.
(Float Basics): Document that logb operates on the absolute value
of its argument.
(Math Functions): Document that (log ARG BASE) also returns NaN if
BASE is negative.  Document that (expt X Y) returns NaN if X is a
finite negative number and Y a finite non-integer.
* etc/NEWS: Document NaNs versus signaling-error change.
* src/data.c, src/lisp.h (Qdomain_error, Qsingularity_error, Qunderflow_error):
Now static.
* src/floatfns.c: Simplify discussion of functions that Emacs doesn't
support, by removing commented-out code and briefly listing the
C89 functions excluded.  The commented-out stuff was confusing
maintenance, e.g., we thought we needed cbrt but it was commented out.
(logb): Remove decl; no longer needed.
(isfinite): New macro, if not already supplied.
(isnan): Don't replace any existing macro.
(Ffrexp, Fldexp): Define even if !HAVE_COPYSIGN, as frexp and ldexp
are present on all C89 platforms.
(Ffrexp): Do not special-case zero, as frexp does the right thing
for that case.
(Flogb): Do not use logb, as it doesn't have the desired meaning
on hosts that use non-base-2 floating point.  Instead, stick with
frexp, which is C89 anyway.  Do not pass an infinity or a NaN to
frexp, to avoid getting an unspecified result.
parent 6fda35f2
2012-09-11 Paul Eggert <eggert@cs.ucla.edu>
Simplify, document, and port floating-point (Bug#12381).
* configure.ac (logb, cbrt): Do not check for these functions,
as they are not being used.
2012-09-10 Paul Eggert <eggert@cs.ucla.edu> 2012-09-10 Paul Eggert <eggert@cs.ucla.edu>
Improve robustness of 'make bootstrap' (Bug#12376). Improve robustness of 'make bootstrap' (Bug#12376).
......
...@@ -120,7 +120,6 @@ HAVE_ATTRIBUTE_ALIGNED ...@@ -120,7 +120,6 @@ HAVE_ATTRIBUTE_ALIGNED
HAVE_BDFFONT HAVE_BDFFONT
HAVE_BOXES HAVE_BOXES
HAVE_C99_STRTOLD HAVE_C99_STRTOLD
HAVE_CBRT
HAVE_CFMAKERAW HAVE_CFMAKERAW
HAVE_CFSETSPEED HAVE_CFSETSPEED
HAVE_CLOCK_GETTIME HAVE_CLOCK_GETTIME
...@@ -251,7 +250,6 @@ HAVE_LIBXMU ...@@ -251,7 +250,6 @@ HAVE_LIBXMU
HAVE_LINUX_VERSION_H HAVE_LINUX_VERSION_H
HAVE_LOCALTIME_R HAVE_LOCALTIME_R
HAVE_LOCAL_SOCKETS HAVE_LOCAL_SOCKETS
HAVE_LOGB
HAVE_LONG_FILE_NAMES HAVE_LONG_FILE_NAMES
HAVE_LONG_LONG_INT HAVE_LONG_LONG_INT
HAVE_LRAND48 HAVE_LRAND48
...@@ -574,7 +572,6 @@ getpid ...@@ -574,7 +572,6 @@ getpid
isatty isatty
kill kill
link link
logb
lseek lseek
mkdir mkdir
mktemp mktemp
...@@ -616,7 +613,6 @@ fopen ...@@ -616,7 +613,6 @@ fopen
getpid getpid
index index
isatty isatty
logb
lseek lseek
mkdir mkdir
mktemp mktemp
......
2012-09-11 Paul Eggert <eggert@cs.ucla.edu>
Simplify, document, and port floating-point (Bug#12381).
* CPP-DEFINES (HAVE_CBRT, HAVE_LOGB, logb): Remove.
2012-09-09 Paul Eggert <eggert@cs.ucla.edu> 2012-09-09 Paul Eggert <eggert@cs.ucla.edu>
Assume C89 or later for math functions (Bug#12381). Assume C89 or later for math functions (Bug#12381).
......
...@@ -2689,8 +2689,8 @@ if test $emacs_cv_netdb_declares_h_errno = yes; then ...@@ -2689,8 +2689,8 @@ if test $emacs_cv_netdb_declares_h_errno = yes; then
AC_DEFINE(HAVE_H_ERRNO, 1, [Define to 1 if netdb.h declares h_errno.]) AC_DEFINE(HAVE_H_ERRNO, 1, [Define to 1 if netdb.h declares h_errno.])
fi fi
# fmod, logb, and frexp are found in -lm on most systems. # sqrt and other floating-point functions such as fmod and frexp
# On HPUX 9.01, -lm does not contain logb, so check for sqrt. # are found in -lm on most systems.
AC_CHECK_LIB(m, sqrt) AC_CHECK_LIB(m, sqrt)
# Check for mail-locking functions in a "mail" library. Probably this should # Check for mail-locking functions in a "mail" library. Probably this should
...@@ -2770,7 +2770,7 @@ AC_SUBST(BLESSMAIL_TARGET) ...@@ -2770,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 cbrt setsid \ lrand48 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 \
......
2012-09-11 Paul Eggert <eggert@cs.ucla.edu>
Simplify, document, and port floating-point (Bug#12381).
* numbers.texi (Float Basics, Arithmetic Operations, Math Functions):
Document that / and mod (with floating point arguments), along
with asin, acos, log, log10, expt and sqrt, return special values
instead of signaling exceptions.
(Float Basics): Document that logb operates on the absolute value
of its argument.
(Math Functions): Document that (log ARG BASE) also returns NaN if
BASE is negative. Document that (expt X Y) returns NaN if X is a
finite negative number and Y a finite non-integer.
2012-09-09 Chong Yidong <cyd@gnu.org> 2012-09-09 Chong Yidong <cyd@gnu.org>
* lists.texi (Sets And Lists): Explain that the return value for * lists.texi (Sets And Lists): Explain that the return value for
......
...@@ -196,6 +196,14 @@ numerical functions return such values in cases where there is no ...@@ -196,6 +196,14 @@ numerical functions return such values in cases where there is no
correct answer. For example, @code{(/ 0.0 0.0)} returns a NaN. (NaN correct answer. For example, @code{(/ 0.0 0.0)} returns a NaN. (NaN
values can also carry a sign, but for practical purposes there's no values can also carry a sign, but for practical purposes there's no
significant difference between different NaN values in Emacs Lisp.) significant difference between different NaN values in Emacs Lisp.)
When a function is documented to return a NaN, it returns an
implementation-defined value when Emacs is running on one of the
now-rare platforms that do not use @acronym{IEEE} floating point. For
example, @code{(log -1.0)} typically returns a NaN, but on
non-@acronym{IEEE} platforms it returns an implementation-defined
value.
Here are the read syntaxes for these special floating point values: Here are the read syntaxes for these special floating point values:
@table @asis @table @asis
...@@ -241,7 +249,7 @@ numbers. ...@@ -241,7 +249,7 @@ numbers.
@defun logb number @defun logb number
This function returns the binary exponent of @var{number}. More This function returns the binary exponent of @var{number}. More
precisely, the value is the logarithm of @var{number} base 2, rounded precisely, the value is the logarithm of |@var{number}| base 2, rounded
down to an integer. down to an integer.
@example @example
...@@ -694,7 +702,8 @@ arguments. It also permits floating point arguments; it rounds the ...@@ -694,7 +702,8 @@ arguments. It also permits floating point arguments; it rounds the
quotient downward (towards minus infinity) to an integer, and uses that quotient downward (towards minus infinity) to an integer, and uses that
quotient to compute the remainder. quotient to compute the remainder.
An @code{arith-error} results if @var{divisor} is 0. If @var{divisor} is zero, @code{mod} signals an @code{arith-error}
error if both arguments are integers, and returns a NaN otherwise.
@example @example
@group @group
...@@ -1096,8 +1105,8 @@ pi/2 ...@@ -1096,8 +1105,8 @@ pi/2
@tex @tex
@math{\pi/2} @math{\pi/2}
@end tex @end tex
(inclusive) whose sine is @var{arg}; if, however, @var{arg} is out of (inclusive) whose sine is @var{arg}. If @var{arg} is out of range
range (outside [@minus{}1, 1]), it signals a @code{domain-error} error. (outside [@minus{}1, 1]), @code{asin} returns a NaN.
@end defun @end defun
@defun acos arg @defun acos arg
...@@ -1108,8 +1117,8 @@ pi ...@@ -1108,8 +1117,8 @@ pi
@tex @tex
@math{\pi} @math{\pi}
@end tex @end tex
(inclusive) whose cosine is @var{arg}; if, however, @var{arg} is out (inclusive) whose cosine is @var{arg}. If @var{arg} is out of range
of range (outside [@minus{}1, 1]), it signals a @code{domain-error} error. (outside [@minus{}1, 1]), @code{acos} returns a NaN.
@end defun @end defun
@defun atan y &optional x @defun atan y &optional x
...@@ -1141,8 +1150,8 @@ This is the exponential function; it returns @math{e} to the power ...@@ -1141,8 +1150,8 @@ This is the exponential function; it returns @math{e} to the power
@defun log arg &optional base @defun log arg &optional base
This function returns the logarithm of @var{arg}, with base This function returns the logarithm of @var{arg}, with base
@var{base}. If you don't specify @var{base}, the natural base @var{base}. If you don't specify @var{base}, the natural base
@math{e} is used. If @var{arg} is negative, it signals a @math{e} is used. If @var{arg} or @var{base} is negative, @code{log}
@code{domain-error} error. returns a NaN.
@end defun @end defun
@ignore @ignore
...@@ -1160,21 +1169,21 @@ lose accuracy. ...@@ -1160,21 +1169,21 @@ lose accuracy.
@end ignore @end ignore
@defun log10 arg @defun log10 arg
This function returns the logarithm of @var{arg}, with base 10. If This function returns the logarithm of @var{arg}, with base 10:
@var{arg} is negative, it signals a @code{domain-error} error. @code{(log10 @var{x})} @equiv{} @code{(log @var{x} 10)}.
@code{(log10 @var{x})} @equiv{} @code{(log @var{x} 10)}, at least
approximately.
@end defun @end defun
@defun expt x y @defun expt x y
This function returns @var{x} raised to power @var{y}. If both This function returns @var{x} raised to power @var{y}. If both
arguments are integers and @var{y} is positive, the result is an arguments are integers and @var{y} is positive, the result is an
integer; in this case, overflow causes truncation, so watch out. integer; in this case, overflow causes truncation, so watch out.
If @var{x} is a finite negative number and @var{y} is a finite
non-integer, @code{expt} returns a NaN.
@end defun @end defun
@defun sqrt arg @defun sqrt arg
This returns the square root of @var{arg}. If @var{arg} is negative, This returns the square root of @var{arg}. If @var{arg} is negative,
it signals a @code{domain-error} error. @code{sqrt} returns a NaN.
@end defun @end defun
In addition, Emacs defines the following common mathematical In addition, Emacs defines the following common mathematical
......
2012-09-11 Paul Eggert <eggert@cs.ucla.edu>
Simplify, document, and port floating-point (Bug#12381).
* NEWS: Document NaNs versus signaling-error change.
2012-09-04 Paul Eggert <eggert@cs.ucla.edu> 2012-09-04 Paul Eggert <eggert@cs.ucla.edu>
Give more-useful info on a fatal error (Bug#12328). Give more-useful info on a fatal error (Bug#12328).
......
...@@ -729,6 +729,14 @@ table, but with a different prefix. ...@@ -729,6 +729,14 @@ table, but with a different prefix.
must be in the range 1000..9999. It now works with any year supported must be in the range 1000..9999. It now works with any year supported
by the underlying C implementation. by the underlying C implementation.
** Floating point
*** When floating point functions such as `log' are given invalid
arguments, e.g., (log -1.0), they now uniformly return special values
such as NaNs instead of signaling errors. Previously, these functions
returned NaNs on some platforms but signaled errors on others. The affected
functions are acos, asin, tan, exp, expt, log, log10, sqrt, and mod.
** New function file-name-base. ** New function file-name-base.
** New function `tty-top-frame' returns the topmost frame of a text terminal. ** New function `tty-top-frame' returns the topmost frame of a text terminal.
......
2012-09-11 Paul Eggert <eggert@cs.ucla.edu> 2012-09-11 Paul Eggert <eggert@cs.ucla.edu>
Simplify, document, and port floating-point (Bug#12381).
The porting part of this patch fixes bugs on non-IEEE platforms
with frexp, ldexp, logb.
* data.c, lisp.h (Qdomain_error, Qsingularity_error, Qunderflow_error):
Now static.
* floatfns.c: Simplify discussion of functions that Emacs doesn't
support, by removing commented-out code and briefly listing the
C89 functions excluded. The commented-out stuff was confusing
maintenance, e.g., we thought we needed cbrt but it was commented out.
(logb): Remove decl; no longer needed.
(isfinite): New macro, if not already supplied.
(isnan): Don't replace any existing macro.
(Ffrexp, Fldexp): Define even if !HAVE_COPYSIGN, as frexp and ldexp
are present on all C89 platforms.
(Ffrexp): Do not special-case zero, as frexp does the right thing
for that case.
(Flogb): Do not use logb, as it doesn't have the desired meaning
on hosts that use non-base-2 floating point. Instead, stick with
frexp, which is C89 anyway. Do not pass an infinity or a NaN to
frexp, to avoid getting an unspecified result.
* xdisp.c (Qinhibit_debug_on_message): Now static. * xdisp.c (Qinhibit_debug_on_message): Now static.
2012-09-10 Jan Djärv <jan.h.d@swipnet.se> 2012-09-10 Jan Djärv <jan.h.d@swipnet.se>
......
...@@ -71,8 +71,8 @@ Lisp_Object Qchar_table_p, Qvector_or_char_table_p; ...@@ -71,8 +71,8 @@ Lisp_Object Qchar_table_p, Qvector_or_char_table_p;
Lisp_Object Qcdr; Lisp_Object Qcdr;
static Lisp_Object Qad_advice_info, Qad_activate_internal; static Lisp_Object Qad_advice_info, Qad_activate_internal;
Lisp_Object Qrange_error, Qdomain_error, Qsingularity_error; static Lisp_Object Qdomain_error, Qsingularity_error, Qunderflow_error;
Lisp_Object Qoverflow_error, Qunderflow_error; Lisp_Object Qrange_error, Qoverflow_error;
Lisp_Object Qfloatp; Lisp_Object Qfloatp;
Lisp_Object Qnumberp, Qnumber_or_marker_p; Lisp_Object Qnumberp, Qnumber_or_marker_p;
......
...@@ -22,9 +22,10 @@ You should have received a copy of the GNU General Public License ...@@ -22,9 +22,10 @@ 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/>. */
/* C89 requires only these math.h functions: /* C89 requires only the following math.h functions, and Emacs omits
acos, asin, atan, atan2, ceil, cos, cosh, exp, fabs, floor, fmod, the starred functions since we haven't found a use for them:
frexp, ldexp, log, log10, modf, pow, sin, sinh, sqrt, tan, tanh. acos, asin, atan, atan2, ceil, cos, *cosh, exp, fabs, floor, fmod,
frexp, ldexp, log, log10, *modf, pow, sin, *sinh, sqrt, tan, *tanh.
*/ */
#include <config.h> #include <config.h>
...@@ -42,10 +43,12 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ ...@@ -42,10 +43,12 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <math.h> #include <math.h>
/* This declaration is omitted on some systems, like Ultrix. */ #ifndef isfinite
#if !defined (HPUX) && defined (HAVE_LOGB) && !defined (logb) # define isfinite(x) ((x) - (x) == 0)
extern double logb (double); #endif
#endif /* not HPUX and HAVE_LOGB and no logb macro */ #ifndef isnan
# define isnan(x) ((x) != (x))
#endif
/* Extract a Lisp number as a `double', or signal an error. */ /* Extract a Lisp number as a `double', or signal an error. */
...@@ -126,9 +129,6 @@ DEFUN ("tan", Ftan, Stan, 1, 1, 0, ...@@ -126,9 +129,6 @@ DEFUN ("tan", Ftan, Stan, 1, 1, 0,
return make_float (d); return make_float (d);
} }
#undef isnan
#define isnan(x) ((x) != (x))
DEFUN ("isnan", Fisnan, Sisnan, 1, 1, 0, DEFUN ("isnan", Fisnan, Sisnan, 1, 1, 0,
doc: /* Return non nil iff argument X is a NaN. */) doc: /* Return non nil iff argument X is a NaN. */)
(Lisp_Object x) (Lisp_Object x)
...@@ -153,6 +153,7 @@ Cause an error if X1 or X2 is not a float. */) ...@@ -153,6 +153,7 @@ Cause an error if X1 or X2 is not a float. */)
return make_float (copysign (f1, f2)); return make_float (copysign (f1, f2));
} }
#endif
DEFUN ("frexp", Ffrexp, Sfrexp, 1, 1, 0, DEFUN ("frexp", Ffrexp, Sfrexp, 1, 1, 0,
doc: /* Get significand and exponent of a floating point number. doc: /* Get significand and exponent of a floating point number.
...@@ -167,15 +168,9 @@ If X is zero, both parts (SGNFCAND and EXP) are zero. */) ...@@ -167,15 +168,9 @@ If X is zero, both parts (SGNFCAND and EXP) are zero. */)
(Lisp_Object x) (Lisp_Object x)
{ {
double f = XFLOATINT (x); double f = XFLOATINT (x);
int exponent;
if (f == 0.0) double sgnfcand = frexp (f, &exponent);
return Fcons (make_float (0.0), make_number (0)); return Fcons (make_float (sgnfcand), make_number (exponent));
else
{
int exponent;
double sgnfcand = frexp (f, &exponent);
return Fcons (make_float (sgnfcand), make_number (exponent));
}
} }
DEFUN ("ldexp", Fldexp, Sldexp, 1, 2, 0, DEFUN ("ldexp", Fldexp, Sldexp, 1, 2, 0,
...@@ -187,118 +182,6 @@ Returns the floating point value resulting from multiplying SGNFCAND ...@@ -187,118 +182,6 @@ Returns the floating point value resulting from multiplying SGNFCAND
CHECK_NUMBER (exponent); CHECK_NUMBER (exponent);
return make_float (ldexp (XFLOATINT (sgnfcand), XINT (exponent))); return make_float (ldexp (XFLOATINT (sgnfcand), XINT (exponent)));
} }
#endif
#if 0 /* Leave these out unless we find there's a reason for them. */
DEFUN ("bessel-j0", Fbessel_j0, Sbessel_j0, 1, 1, 0,
doc: /* Return the bessel function j0 of ARG. */)
(Lisp_Object arg)
{
double d = extract_float (arg);
d = j0 (d);
return make_float (d);
}
DEFUN ("bessel-j1", Fbessel_j1, Sbessel_j1, 1, 1, 0,
doc: /* Return the bessel function j1 of ARG. */)
(Lisp_Object arg)
{
double d = extract_float (arg);
d = j1 (d);
return make_float (d);
}
DEFUN ("bessel-jn", Fbessel_jn, Sbessel_jn, 2, 2, 0,
doc: /* Return the order N bessel function output jn of ARG.
The first arg (the order) is truncated to an integer. */)
(Lisp_Object n, Lisp_Object arg)
{
int i1 = extract_float (n);
double f2 = extract_float (arg);
f2 = jn (i1, f2);
return make_float (f2);
}
DEFUN ("bessel-y0", Fbessel_y0, Sbessel_y0, 1, 1, 0,
doc: /* Return the bessel function y0 of ARG. */)
(Lisp_Object arg)
{
double d = extract_float (arg);
d = y0 (d);
return make_float (d);
}
DEFUN ("bessel-y1", Fbessel_y1, Sbessel_y1, 1, 1, 0,
doc: /* Return the bessel function y1 of ARG. */)
(Lisp_Object arg)
{
double d = extract_float (arg);
d = y1 (d);
return make_float (d);
}
DEFUN ("bessel-yn", Fbessel_yn, Sbessel_yn, 2, 2, 0,
doc: /* Return the order N bessel function output yn of ARG.
The first arg (the order) is truncated to an integer. */)
(Lisp_Object n, Lisp_Object arg)
{
int i1 = extract_float (n);
double f2 = extract_float (arg);
f2 = yn (i1, f2);
return make_float (f2);
}
#endif
#if 0 /* Leave these out unless we see they are worth having. */
DEFUN ("erf", Ferf, Serf, 1, 1, 0,
doc: /* Return the mathematical error function of ARG. */)
(Lisp_Object arg)
{
double d = extract_float (arg);
d = erf (d);
return make_float (d);
}
DEFUN ("erfc", Ferfc, Serfc, 1, 1, 0,
doc: /* Return the complementary error function of ARG. */)
(Lisp_Object arg)
{
double d = extract_float (arg);
d = erfc (d);
return make_float (d);
}
DEFUN ("log-gamma", Flog_gamma, Slog_gamma, 1, 1, 0,
doc: /* Return the log gamma of ARG. */)
(Lisp_Object arg)
{
double d = extract_float (arg);
d = lgamma (d);
return make_float (d);
}
DEFUN ("cube-root", Fcube_root, Scube_root, 1, 1, 0,
doc: /* Return the cube root of ARG. */)
(Lisp_Object arg)
{
double d = extract_float (arg);
#ifdef HAVE_CBRT
d = cbrt (d);
#else
if (d >= 0.0)
d = pow (d, 1.0/3.0);
else
d = -pow (-d, 1.0/3.0);
#endif
return make_float (d);
}
#endif
DEFUN ("exp", Fexp, Sexp, 1, 1, 0, DEFUN ("exp", Fexp, Sexp, 1, 1, 0,
doc: /* Return the exponential base e of ARG. */) doc: /* Return the exponential base e of ARG. */)
...@@ -383,63 +266,6 @@ DEFUN ("sqrt", Fsqrt, Ssqrt, 1, 1, 0, ...@@ -383,63 +266,6 @@ DEFUN ("sqrt", Fsqrt, Ssqrt, 1, 1, 0,
return make_float (d); return make_float (d);
} }
#if 0 /* Not clearly worth adding. */
DEFUN ("acosh", Facosh, Sacosh, 1, 1, 0,
doc: /* Return the inverse hyperbolic cosine of ARG. */)
(Lisp_Object arg)
{
double d = extract_float (arg);
d = acosh (d);
return make_float (d);
}
DEFUN ("asinh", Fasinh, Sasinh, 1, 1, 0,
doc: /* Return the inverse hyperbolic sine of ARG. */)
(Lisp_Object arg)
{
double d = extract_float (arg);
d = asinh (d);
return make_float (d);
}
DEFUN ("atanh", Fatanh, Satanh, 1, 1, 0,
doc: /* Return the inverse hyperbolic tangent of ARG. */)
(Lisp_Object arg)
{
double d = extract_float (arg);
d = atanh (d);
return make_float (d);
}
DEFUN ("cosh", Fcosh, Scosh, 1, 1, 0,
doc: /* Return the hyperbolic cosine of ARG. */)
(Lisp_Object arg)
{
double d = extract_float (arg);
d = cosh (d);
return make_float (d);
}
DEFUN ("sinh", Fsinh, Ssinh, 1, 1, 0,
doc: /* Return the hyperbolic sine of ARG. */)
(Lisp_Object arg)
{
double d = extract_float (arg);
d = sinh (d);
return make_float (d);
}
DEFUN ("tanh", Ftanh, Stanh, 1, 1, 0,
doc: /* Return the hyperbolic tangent of ARG. */)
(Lisp_Object arg)
{
double d = extract_float (arg);
d = tanh (d);
return make_float (d);
}
#endif
DEFUN ("abs", Fabs, Sabs, 1, 1, 0, DEFUN ("abs", Fabs, Sabs, 1, 1, 0,
doc: /* Return the absolute value of ARG. */) doc: /* Return the absolute value of ARG. */)
(register Lisp_Object arg) (register Lisp_Object arg)
...@@ -477,16 +303,15 @@ This is the same as the exponent of a float. */) ...@@ -477,16 +303,15 @@ This is the same as the exponent of a float. */)
if (f == 0.0) if (f == 0.0)
value = MOST_NEGATIVE_FIXNUM; value = MOST_NEGATIVE_FIXNUM;
else else if (isfinite (f))
{ {
#ifdef HAVE_LOGB
value = logb (f);
#else
int ivalue; int ivalue;
frexp (f, &ivalue); frexp (f, &ivalue);
value = ivalue - 1; value = ivalue - 1;
#endif
} }
else
value = MOST_POSITIVE_FIXNUM;
XSETINT (val, value); XSETINT (val, value);
return val; return val;
} }
...@@ -719,27 +544,9 @@ syms_of_floatfns (void) ...@@ -719,27 +544,9 @@ syms_of_floatfns (void)
defsubr (&Sisnan); defsubr (&Sisnan);
#ifdef HAVE_COPYSIGN #ifdef HAVE_COPYSIGN
defsubr (&Scopysign); defsubr (&Scopysign);
#endif
defsubr (&Sfrexp); defsubr (&Sfrexp);
defsubr (&Sldexp); defsubr (&Sldexp);
#endif
#if 0
defsubr (&Sacosh);
defsubr (&Sasinh);
defsubr (&Satanh);
defsubr (&Scosh);
defsubr (&Ssinh);
defsubr (&Stanh);
defsubr (&Sbessel_y0);
defsubr (&Sbessel_y1);
defsubr (&Sbessel_yn);
defsubr (&Sbessel_j0);
defsubr (&Sbessel_j1);
defsubr (&Sbessel_jn);
defsubr (&Serf);
defsubr (&Serfc);
defsubr (&Slog_gamma);
defsubr (&Scube_root);
#endif
defsubr (&Sfceiling); defsubr (&Sfceiling);
defsubr (&Sffloor); defsubr (&Sffloor);
defsubr (&Sfround); defsubr (&Sfround);
......