This math library is capable of being operated in several different compatibility modes. These options deal solely with how errors are handled.
There are 4 compatibility modes: ANSI/POSIX 1003.1; IEEE-754; X/Open Portability Guide issue 3 (XPG3); and System V Interface Definition Edition 3.
In IEEE mode, the matherr() function (see below) is never called, no warning messages are printed on the stderr output stream, and errno is never set.
In ANSI/POSIX mode, errno is set correctly, but matherr() is never called and no warning messages are printed on the stderr output stream.
In X/Open mode, errno is set correctly, matherr() is called, but no warning messages are printed on the stderr output stream.
In SVID mode, functions which overflow return a value HUGE (defined in math.h), which is the maximum single precision floating point value (as opposed to HUGE_VAL which is meant to stand for infinity). errno is set correctly and matherr() is called. If matherr() returns 0, warning messages are printed on the stderr output stream for some errors.
The mode can be compiled-in as IEEE-only, or any one of the above methods settable at run-time.
Note: This math library assumes that the hardware (or software floating point emulation) supports IEEE-754 style arithmetic, 32-bit 2's complement integer arithmetic, doubles are in 64-bit IEEE-754 format.
As mentioned above, in X/Open or SVID modes, the user can supply a function matherr() of the form:
int matherr( struct exception *e ) |
where struct exception is defined as:
struct exception { int type; char *name; double arg1, arg2, retval; }; |
type is the exception type and is one of:
argument domain exception
argument singularity
overflow range exception
underflow range exception
total loss of significance
partial loss of significance
name is a string containing the name of the function
arg1 and arg2 are the arguments passed to the function
retval is the default value that will be returned by the function, and can be changed by matherr()
Note: matherr must have “C” linkage, not “C++” linkage.
If matherr returns zero, or the user doesn't supply their own matherr, then the following usually happens in SVID mode:
Table 13-1. Behavior of math exception handling
Type | Behavior |
---|---|
DOMAIN | 0.0 returned, errno=EDOM, and a message printed on stderr |
SING | HUGE of appropriate sign is returned, errno=EDOM, and a message is printed on stderr |
OVERFLOW | HUGE of appropriate sign is returned, and errno=ERANGE |
UNDERFLOW | 0.0 is returned and errno=ERANGE |
TLOSS | 0.0 is returned, errno=ERANGE, and a message is printed on stderr |
PLOSS | The current implementation doesn't return this type |
X/Open mode is similar except that the message is not printed on stderr and HUGE_VAL is used in place of HUGE
With the appropriate configuration options set below, the math library is fully thread-safe if:
Depending on the compatibility mode, the setting of the errno variable from the C library is thread-safe
Depending on the compatibility mode, sending error messages to the stderr output stream using the C library fputs() function is thread-safe
Depending on the compatibility mode, the user-supplied matherr() function and anything it depends on are thread-safe
In addition, with the exception of the gamma*() and lgamma*() functions, the math library is reentrant (and thus safe to use from interrupt handlers) if the Math library is always in IEEE mode.