www.delorie.com/djgpp/doc/libc/libc_530.html   search  
libc.a reference

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]



#include <libm/math.h>

enum fdversion {fdlibm_ieee = -1, fdlibm_svid, fdlibm_xopen,

#define _LIB_VERSION_TYPE enum fdversion
#define _LIB_VERSION _fdlib_version  


#define _IEEE_  fdlibm_ieee
#define _SVID_  fdlibm_svid
#define _XOPEN_ fdlibm_xopen
#define _POSIX_ fdlibm_posix



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:

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.

The default value, specifies IEEE-compliant operation. In case of an error, this version will immediately return whatever result is computed by the FPU, and will not set errno. If the result overflows, an Inf is returned. This version gives the fastest code.

In case of an error, this version will set 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.

This version is compliant with the System V Interface Definition. This is the slowest version. In case of an error, it calls the 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'.

Complies to the X/Open specifications. It behaves exactly like _SVID_, but it never prints an error message, even if matherr returns zero, and Inf us returned when a result overflows.




/*  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. */

int main (void)
  /* Reset the FPU (possible previous FP problems).  */
  _clear87 ();
  _fpreset ();

  /* Run the test.  */
  errno = 0;
  assert(errno == 0);
  assert(errno == EDOM); /* this line should NOT cause
                          * the assertion to fail */


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

  webmaster   donations   bookstore     delorie software   privacy  
  Copyright 2004   by DJ Delorie     Updated Apr 2004