math_error(7)

okay bestie, buckle up ๐Ÿ’– this is math_error(7), from the Miscellaneous Information Manual, section 7. it's the page that tells you how the math girlies signal that something went wrong. no cap, you need this. ๐ŸŒธ

๐Ÿ’– NAME ๐Ÿ’–

math_error โ€” detecting errors from mathematical functions ๐Ÿšจ


๐Ÿฆ‹ SYNOPSIS ๐Ÿฆ‹

#include <math.h>
#include <errno.h>
#include <fenv.h>

โœจ DESCRIPTION โœจ

so here's the tea ๐Ÿซ– โ€” when an error happens, most library functions just tell you by returning a special value (like -1 or NULL, iconic behaviour honestly). but the mathematical functions declared in <math.h> can't really do that, because they're out here returning floating-point numbers. so they use other mechanisms to spill the bad news.

there are two error-reporting mechanisms:

  • the older one sets errno ๐Ÿ‘ต
  • the newer one uses the floating-point exception mechanism (the use of feclearexcept(3) and fetestexcept(3), as outlined below) described in fenv(3) โœจ

if you want a portable program that actually checks for errors from a mathematical function, do this: set errno to zero, and make this call

feclearexcept(FE_ALL_EXCEPT);

before you call the mathematical function. yes, before. don't skip this step, it's giving pre-game ritual. ๐Ÿ’…

then, once the mathematical function returns, if errno is nonzero, or the following call (see fenv(3)) returns nonzero

fetestexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW |
             FE_UNDERFLOW);

then bestieโ€ฆ an error occurred in the mathematical function. ๐Ÿ˜ญ

the error conditions that can occur are described below. let's get into it.


๐ŸŒ€ Domain error

a domain error happens when a mathematical function gets an argument whose value falls outside the domain for which the function is defined (e.g., giving a negative argument to log(3) โ€” rude, honestly).

when a domain error occurs:

  • math functions commonly return a NaN (though some functions return a different value in this case, so don't @ me)
  • errno is set to EDOM
  • an "invalid" (FE_INVALID) floating-point exception is raised ๐Ÿšซ

โšก Pole error

a pole error happens when the mathematical result of a function is an exact infinity (e.g., the logarithm of 0 is negative infinity โ€” the math really said "no โค๏ธ").

when a pole error occurs:

  • the function returns the (signed) value HUGE_VAL, HUGE_VALF, or HUGE_VALL, depending on whether the function result type is double, float, or long double
  • the sign of the result is that which is mathematically correct for the function โœจ
  • errno is set to ERANGE
  • a "divide-by-zero" (FE_DIVBYZERO) floating-point exception is raised โž—

๐ŸŒŠ Range error

a range error happens when the magnitude of the function result means it literally cannot be represented in the result type of the function. and the return value depends on whether it was an overflow or an underflow โ€” two very different girls. ๐Ÿ’…

overflow: a floating result overflows if the result is finite, but is too large to be represented in the result type. when an overflow occurs:

  • the function returns the value HUGE_VAL, HUGE_VALF, or HUGE_VALL, depending on whether the function result type is double, float, or long double
  • errno is set to ERANGE
  • an "overflow" (FE_OVERFLOW) floating-point exception is raised ๐Ÿ”ฅ

underflow: a floating result 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" (yes that's a direct quote, she's verbose but she's right)
  • errno may be set to ERANGE
  • an "underflow" (FE_UNDERFLOW) floating-point exception may be raised ๐Ÿซง

also some functions deliver a range error if the supplied argument value, or the correct function result, would be subnormal. a subnormal value is one that is nonzero, but with a magnitude so small it can't be represented 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. tiny. microscopic. a little baby number. ๐Ÿฃ


๐Ÿ“ NOTES ๐Ÿ“

okay this is the messy part and honestly the way that glibc handles this is stressful. ๐Ÿ˜ญ

the math_errhandling identifier specified by C99 and POSIX.1 is not supported by glibc. this identifier is supposed to indicate which of the two error-notification mechanisms (errno, exceptions retrievable via fetestexcept(3)) is in use. the standards require that at least one be in use, but permit both to be available.

the current (glibc 2.8) situation under glibc isโ€ฆ messy. ๐Ÿ’€

  • most (but not all) functions raise exceptions on errors
  • some also set errno
  • a few functions set errno, but don't raise an exception
  • a very few functions do neither ๐Ÿ™ˆ

see the individual manual pages for details. iykyk.


so, to avoid the complexities of using errno and fetestexcept(3) for error checking, it is often advised that you should instead just check for bad argument values before each call. so valid of them, honestly. for example, the following code ensures that log(3)'s argument is not a NaN and is not zero (a pole error) or less than zero (a domain error):

double x, r;

if (isnan(x) || islessequal(x, 0)) {
    /* Deal with NaN / pole error / domain error */
}

r = log(x);

gorgeous. protective. main character energy. ๐Ÿ‘‘

heads up bestie: the discussion on this page does not apply to the complex mathematical functions (i.e., those declared by <complex.h>), which in general are not required to return errors by C99 and POSIX.1.

also!! the gcc(1) -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 errno on error. (the gcc(1) -ffast-math option also enables -fno-math-errno.) but don't worry โ€” an error can still be tested for using fetestexcept(3). ๐Ÿซถ


๐Ÿ‘€ SEE ALSO ๐Ÿ‘€

info libc

and that's the whole page, bestie ๐Ÿ’– you're officially fluent in floating-point feelings. this was brought to you by Linux man-pages 6.20, dated 2025-05-17 โ€” so yeah, that's the version, that's the date, slay. ๐ŸŒˆโœจ๐ŸŽ€

๐Ÿ“ฆ where this page comes from
  • arch rolling: man-pages 6.20-1 ยท BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
  • nixpkgs unstable: man-pages 6.20
  • ๐Ÿ“œ the page's license: Linux-man-pages-copyleft
  • ๐Ÿ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms