I just ran across the long discussion of remainder() and fmod() in
the archives of this list.  I note that 19.3 is designed to use
drem(), remainder(), or fmod() depending on which is available, with
fmod() being least favored.  This is a bug; fmod() is always the
right choice.

Briefly, fmod(x,y) gives the remainder based on a quotient which
rounds *down* to the next lower integer, but remainder(x,y) on
the Sun gives the remainder for a quotient rounded to the *nearest*
integer.  The C standard doesn't say what x%y ought to do for negative
arguments, but for positive arguments, at least, the standard requires
fmod-like behavior.  Therefore, to be consistent, lemacs ought to use
fmod(x,y) for float arguments if it is using x%y for integer arguments.

Also, fmod() is a required part of the C standard; remainder(), as
we've all found out the hard way, is defined only on Suns.  As for
drem(), I don't know how it works but it's not defined on Suns.
Anyway, fmod() is the obvious right choice on all machines.

Here's a test program that shows what I mean.

-------- foo.c:
#include <math.h>

int main()
{
  double a = 1234.0;
  double b = 5678.0;
  double c = 100.0;
  printf("%g vs. %g vs. %d\n", fmod(a, c), remainder(a, c), (int)a % (int)c);
  printf("%g vs. %g vs. %d\n", fmod(b, c), remainder(b, c), (int)b % (int)c);
}
-------- foo.out:
34 vs. 34 vs. 34
78 vs. -22 vs. 78
--------

As you can see, remainder(5678,100) rounds the quotient up to 57,
giving a remainder of -22.  This is not a very useful sort of
remainder in most cases, but the IEEE standard provides it anyhow.


In a similar vein, there have been a lot of problems with missing
asinh() along with few other library functions.  The ANSI standard
requires only these functions (from page 251 of K&R II):

   sin, cos, tan, asin, acos, atan, atan2, sinh, cosh, tanh,
   exp, log, log10, pow, sqrt, ceil, floor, fabs, fmod,
   ldexp, frexp, modf

Lucid Emacs also refers to asinh, acosh, atanh, j0, j1, jn, y0, y1,
yn, cbrt, erf, erfc, expm1, log1p, logb, lgamma, and rint, which are
available on Suns but are not standard.  I'd strongly recommend
either taking them out, or #ifdef'ing them out on everything but
Suns.  With the possible exception of rint, no one is likely to
miss any of these functions, and rint(x) can be simulated by
floor(x+0.5) (not exactly IEEE rounding but close enough to
match the doc string).  All the other functions are available
in Emacs Calc; the next version of Calc will make it easy to
apply these functions to Lucid Emacs floats.

It's too bad ANSI C provides inverse and hyperbolic trig
functions without providing the inverse-hyperbolic ones as well.
If this seems too asymmetrical, I'd recommend either dropping the
hyperbolics from Lisp, or defining them in terms of logs rather
than expecting them to be in the library.

On the other hand, atan2, floor, and ceil are not available from
Emacs Lisp.  The current floor and ceiling functions return integers,
not floats, so they don't work for arguments larger than 2^23.
Common Lisp provides ffloor, fceiling, fround, and ftruncate
alternatives which return integer-valued floats, and it also
provides an atan which accepts an optional second argument.
I remember seeing a version of floatfns.c from long ago which
included ffloor, etc.---I wonder how they managed to get dropped
from the version Lucid Emacs uses.

(The ldexp, frexp, and modf functions are probably too arcane
to worry about for Lisp.)

								-- Dave