Mail Archives: djgpp-workers/2003/03/20/12:15:19
Esa A E Peuha wrote:
>I agree that libc.a should have all C99 math functions, but I think it might make sense to have different version of these functions in libm.a; that's the case for the functions that are currently in both libc.a and libm.a (in fact, that's the reason we still have libm.a IIRC).
>
Yes, the idea was that libm.a could be used for extreme situations like
sin(1.E200), but that libc was intended for ordinary use, with improved
speed. Unfortunately, I know from experience in writing the libc math
functions how much work would be involved in upgrading them to C99.
There are several areas of work I can think of:
1. "Float" versions of existing functions. expf() would be an example.
We could implement these rather easily by a series of macros like this
#define expf(x) ((float) exp((double) (x)))
but there are some subtle problems with this approach. For instance, I
set errno to ERANGE if x > 700 or so, since the result overflows. This
overflow limit would need to be changed for floats, since they overflow
at a much smaller output value. These problems may not be sufficiently
significant to preclude this approach, since under C90 casting was the
only easy way to use math functions with floats, and I certainly haven't
had much of a problem with it myself.
However, if we decide that new libc float routines should be written, I
think that it would be far easier to modify existing "double" routines
than it would be to start from scratch, since few, if any algorithms
would need to be changed. The output of most routines is left on the
FPU stack, so that wouldn't need to change. Other routines, such as
atanf(), would only need a slight change in the argument handling.
Porting libm.a float routines to libc.a would be undesirable, since
those float routines would actually be *slower* than the corresponding
double routines -- this unexpected behavior would not inspire a user's
confidence.
2. "Long double" versions of existing functions. The FPU performs
internal computations with a 64-bit mantissa, so for a few simple
functions like sqrtl(), a simple adaptation of existing routines could
be done, but others functions like expl() are sufficiently
ill-conditioned that such an approach would not be sufficiently
accurate. K. B. Williams was porting some long double functions, but I
don't know what the current status of that is. I wouldn't have any
objection to having the slower libm-like routines for long-double
functions in libc, since if one is using long doubles, one is probably
more interested in accuracy than speed.
3. New, easy functions, such as isnan(). I'd be willing to code these.
4. New, difficult functions such as clog(), gamma(), and (worst of all)
cpow(). I can see myself doing a few of these piecemeal, but I'm not
enthusiastic about doing all of them, especially all at once, like I did
for the double functions -- that's a very major project. This may be
another case where we port from libm.
5. Changes to existing functions to bring them in line with C99. Some
of these changes don't make mathematical sense, and I didn't get very
far with my public comments to the C99 committee. An example would be
that atan2(+0., +0.) is now required to return +0., rather than NaN, as
it now does. Making these changes would actually simplify some of the
routines, since they could silently return the FPU default results,
rather than testing and setting errno as they now do. However, IMHO the
functions would be more dangerous to use.
-Eric
- Raw text -