www.delorie.com/djgpp/doc/libc/libc_530.html | search |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
#include <libm/math.h> enum fdversion {fdlibm_ieee = -1, fdlibm_svid, fdlibm_xopen, fdlibm_posix}; #define _LIB_VERSION_TYPE enum fdversion #define _LIB_VERSION _fdlib_version extern _LIB_VERSION_TYPE _LIB_VERSION; #define _IEEE_ fdlibm_ieee #define _SVID_ fdlibm_svid #define _XOPEN_ fdlibm_xopen #define _POSIX_ fdlibm_posix _LIB_VERSION_TYPE _LIB_VERSION = _IEEE_; |
The alternate math library, `libm.a', originally written by
Cygnus support, provides versions of mathematical functions which
comply to several different standards of behavior in abnormal cases, and
are sometimes more accurate than those included in the default
`libc.a' library, in particular when elaborate argument reduction
is required to avoid precision loss. Functions in `libm.a' allow
to create programs with well-defined and standard-compliant behavior
when numerical errors occur, and provide the application with a means to
control their behavior in abnormal cases via the matherr
callback. They almost never rely on the features specific to the x87
FPU, and are thus slower and sometimes slightly less accurate than the
functions from `libc.a'.
In contrast, the functions in the default `libc.a' library are
written for maximum speed and exploitation of the x87 FPU features, do
not call matherr
, and are therefore much faster and sometimes
more accurate (due to the extended 80-bit precision with which the x87
FPU carries its calculations).
Another aspect of differences between functions in `libc.a' and in
`libm.a' is the value returned when the result overflows a
double
. The functions from `libc.a' always return a
suitably signed infinity, Inf
, whereas for functions from
`libm.a' an application can arrange for a large but finite value to
be returned. Getting finite return values might be important in certain
kinds of mathematical computations where the special rules defined for
infinities (e.g., Inf + a = Inf) might be inappropriate.
Refer to section `Mathematical Functions' in The Cygnus C Math Library, for detailed documentation of the individual functions from `libm.a'. This section explains the general setup of using those functions from DJGPP programs.
To use the alternate math library with your program, you need to do the following:
<libm/math.h>
. Alternatively, you can include
<math.h>
as usual and compile with `-D_USE_LIBM_MATH_H'
option to gcc
, which will cause it to use `libm/math.h'
instead of the default `math.h'. (The second possibility leaves
the source ANSI-compliant.)
_fdlib_version
to a value other than the
default _IEEE_
. The possible values are listed and explained
below.
main
function, set the FPU to a
predictable state by calling _clear87
(see section _clear87) and
_fpreset
(see section _fpreset) library functions. (Another
possibility is to make these calls in a function declared with
__attribute__((constructor))
, so it will be called before
main
.)
The functions in `libm.a' can emulate different standards. You can
select to which standard your program will comply by setting the global
variable _fdlib_version
(or the macro _LIB_VERSION
which
evaluates to it) to one of the values below. This will only affect the
behavior of the math functions when an error is signaled by the FPU.
_IEEE_
errno
. If the result
overflows, an Inf
is returned. This version gives the fastest
code.
_POSIX_
errno
to the
appropriate value (EDOM
or ERANGE
) and return to the
caller, without calling the matherr
function (see section matherr).
If the result overflows, an Inf
is returned. This version should
be used for maximum POSIX- and ANSI-compliance.
_SVID_
matherr
function (see section matherr), which can be customized to
the specific application needs. If matherr
returns zero, a
message is printed to the standard error stream which states the name of
the function that generated the error and the error type, and
errno
is set. If matherr
returns non-zero, there will be
no message and errno
will be left unaltered. If the result
overflows, this version returns HUGE
, a large but finite value
defined by `libm/math.h'.
_XOPEN_
_SVID_
, but it never prints an error message, even if
matherr
returns zero, and Inf
us returned when a result
overflows.
ANSI/ISO C | No |
POSIX | No |
/* Testing errno == EDOM after sqrt(-1). !!! MUST compile with -lm !!! */ #include <assert.h> #include <errno.h> #include <stdio.h> #include <libm/math.h> /* or #define _USE_LIBM_MATH_H * and #include <math.h> */ #include <float.h> /* Setting _LIB_VERSION to anything but _IEEE_ will turn on * errno handling. */ _LIB_VERSION_TYPE _LIB_VERSION = _POSIX_; int main (void) { /* Reset the FPU (possible previous FP problems). */ _clear87 (); _fpreset (); /* Run the test. */ errno = 0; assert(errno == 0); sqrt(-1.0); assert(errno == EDOM); /* this line should NOT cause * the assertion to fail */ return(0); } |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
webmaster | delorie software privacy |
Copyright © 2004 by DJ Delorie | Updated Apr 2004 |