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 |
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 8-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.