From 88fb350113d15592f0f316c2bcf7098ff4d0ef18 Mon Sep 17 00:00:00 2001 From: Michael Kerrisk Date: Wed, 23 Jul 2008 14:05:42 +0000 Subject: [PATCH] A description of how math functions report errors. See http://thread.gmane.org/gmane.linux.man/249. --- man7/math_error.7 | 261 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 261 insertions(+) create mode 100644 man7/math_error.7 diff --git a/man7/math_error.7 b/man7/math_error.7 new file mode 100644 index 000000000..0e7620e18 --- /dev/null +++ b/man7/math_error.7 @@ -0,0 +1,261 @@ +.\" Copyright (c) 2008, Linux Foundation, written by Michael Kerrisk +.\" +.\" +.\" Permission is granted to make and distribute verbatim copies of this +.\" manual provided the copyright notice and this permission notice are +.\" preserved on all copies. +.\" +.\" Permission is granted to copy and distribute modified versions of this +.\" manual under the conditions for verbatim copying, provided that the +.\" entire resulting derived work is distributed under the terms of a +.\" permission notice identical to this one. +.\" +.\" Since the Linux kernel and libraries are constantly changing, this +.\" manual page may be incorrect or out-of-date. The author(s) assume no +.\" responsibility for errors or omissions, or for damages resulting from +.\" the use of the information contained herein. The author(s) may not +.\" have taken the same level of care in the production of this manual, +.\" which is licensed free of charge, as they might when working +.\" professionally. +.\" +.\" Formatted or processed versions of this manual, if unaccompanied by +.\" the source, must acknowledge the copyright and authors of this work. +.\" +.TH MATH_ERROR 7 2008-07-21 "Linux" "Linux Programmer's Manual" +.SH SYNOPSIS +.nf +.B #include +.B #include +.B #include +.fi +.SH NAME +math_error \- detecting errors from mathematical functions +.SH DESCRIPTION +On error, many of the mathematical functions declared in +.IR +return a NaN (not a number). +However, rather than looking at the return value +(which is not always possible) +one can also check whether an error was signaled. +There are two signaling mechanisms: +the older one sets +.IR errno ; +the newer one uses the floating-point exception mechanism (the use of +.BR feclearexcept (3) +and +.BR fetestexcept (3), +as outlined below) +described in +.BR fenv (3). + +C99 and POSIX.1-2001 specify a +.I math_errhandling +identifier, +which is supposed to indicate which of these two mechanisms is in use; +the standards require that at least one be in use, +but permit both to be available. +Although glibc does not support this identifier, +in practice it supports both mechanisms. +.\" I've tested glibc 2.3.3 and glibc 2.8, and both seem to support +.\" both mechanisms. A quick look at the glibc source code suggests +.\" that support goes back to glibc 2.1 at least. -- mtk, Jul 08 + +A portable program that needs to check for an error from a mathematical +function should set +.I errno +to zero, and make the following call +.in +4n +.nf + +feclearexcept(FE_ALL_EXCEPT); + +.fi +.in +before calling a mathematical function. + +Upon return from the mathematical function, if +.I errno +is non-zero, or the following call (see +.BR fenv (3)) +returns non-zero +.in +4n +.nf + +fetestexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | + FE_UNDERFLOW); + +.fi +.in +.\" enum +.\" { +.\" FE_INVALID = 0x01, +.\" __FE_DENORM = 0x02, +.\" FE_DIVBYZERO = 0x04, +.\" FE_OVERFLOW = 0x08, +.\" FE_UNDERFLOW = 0x10, +.\" FE_INEXACT = 0x20 +.\" }; +then an error occurred in the mathematical function. + +The error conditions that can occur for mathematical functions +are described below. +.SS Domain Error +A +.I domain error +occurs when a mathematical function is supplied with an argument whose +value falls outside the domain for which the function +is defined (e.g., giving a negative argument to +.BR log (3)). +When a domain error occurs, +.I errno +is set to +.BR EDOM , +and an "invalid" +.RB ( FE_INVALID ) +floating-point exception is raised. +.SS Pole Error +A +.I pole error +occurs when the mathematical result of a function is an exact infinity +(e.g., the logarithm of 0 is negative infinity). +When a pole error occurs, +the function returns the (signed) value +.BR HUGE_VAL , +.BR HUGE_VALF , +or +.BR HUGE_VALL , +depending on whether the function result type is +.IR double , +.IR float , +or +.IR "long double" . +The sign of the result is that which is mathematically correct for +the function. +.I errno +is set to +.BR ERANGE , +and a "divide-by-zero" +.RB ( FE_DIVBYZERO ) +floating-point exception is raised. +.SS Range Error +A +.I range error +occurs when the magnitude of the function result means that it +cannot be represented in the result type of the function. +The return value of the function depends on whether the range error +was an overflow or an underflow. + +A floating result +.I overflows +if the result is finite, +but is too large to represented in the result type. +When an overflow occurs, +the function returns the value +.BR HUGE_VAL , +.BR HUGE_VALF , +or +.BR HUGE_VALL , +depending on whether the function result type is +.IR double , +.IR float , +or +.IR "long double" . +.I errno +is set to +.BR ERANGE , +and an "overflow" +.RB ( FE_OVERFLOW ) +floating-point exception is raised. + +A floating result +.I underflows +if the result is too small to be represented in the result type. +If an underflow occurs, +a mathematical function typically returns 0.0 +(C99 says a function shall return "an implementation-defined value +whose magnitude is no greater than the smallest normalized +positive number in the specified type"). +.\" FIXME(mtk) POSIX.1 says "may" for the following two cases; need to +.\" investigate this further for specific functions. +.I errno +may be set to +.BR ERANGE , +and an "overflow" +.RB ( FE_UNDERFLOW ) +floating-point exception may be raised. + +Some functions deliver a range error if the supplied argument value, +or the correct function result, would be +.IR subnormal . +A subnormal value is one that is non-zero, +but with a magnitude that is so small that +it can't be presented in normalized form +(i.e., with a 1 in the most significant bit of the significand). +The representation of a subnormal number will contain one +or more leading zeros in the significand. +.SH NOTES +The +.I math_errhandling +identifier specified by C99 and POSIX.1-2001 is not supported. +.\" See CONFORMANCE in the glibc 2.8 (and earlier) source. + +To avoid the complexities of using +.I errno +and +.BR fetestexcept (3) +for error checking, +it is often advised that one should instead check for bad argument +values before each call. +.\" http://www.securecoding.cert.org/confluence/display/seccode/FLP32-C.+Prevent+or+detect+domain+and+range+errors+in+math+functions +For example, the following code ensures that +.BR log (3)'s +argument is not a NaN and is not zero (a pole error) or +less than zero (a domain error): +.in +4n +.nf + +double x, r; + +if (isnan(x) || islessequal(x, 0)) { + /* Deal with NaN / pole error / domain error */ +} + +r = log(x); + +.fi +.in +The discussion on this page does not apply to the complex +mathematical functions (i.e., those declared by +.IR ), +which in general are not required to return errors by C99 +and POSIX.1-2001. + +The +.BR gcc (1) +.I "-fno-math-errno" +option causes the executable to employ implementations of some +mathematical functions that are faster than the standard +implementations, but do not set +.I errno +on error. +(The +.BR gcc (1) +.I "-ffast-math" +option also enables +.IR "-fno-math-errno" .) +An error can still be tested for using +.BR fetestexcept (3). +.fi +.in +.SH SEE ALSO +.BR gcc (1), +.BR errno (3), +.BR fenv (3), +.BR fpclassify (3), +.BR INFINITY (3), +.BR isgreater (3), +.BR matherr (3), +.BR nan (3) +.br +.I "info libc" +.\" FIXME(mtk) add SEE ALSO in fenv.3, fpclassify.3, nan.3, INFINITY.3