Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Minor edits; reviewed

...

... a domain error occurs if an input argument is outside the domain over which the mathematical function is defined.

Paragraph 3 states:

... a pole error (also known as a singularity or infinitary) occurs if the mathematical function has an exact infinite result as the finite input argument(s) are approached in the limit.

...

Function

Domain

Range

Pole 

acos(x)

-1 <= x && x <= 1

No

No
asin(x)-1 <= x && x <= 1 YesYesNo
atan(x)NoneYesNo

atan2(y, x)

x != 0 && y != 0

No

No

acosh(x)

x >= 1

Yes

No
asin(x)NoneYesNo

atanh(x)

-1 < x && x < 1

Yes

Yes

cosh(x), sinh(x)

None

Yes

No

exp(x), exp2(x), expm1(x)

None

Yes

No

ldexp(x, exp)

None

Yes

No

log(x), log10(x), log2(x)

x >= 0

No

Yes

log1p(x)

x > -1

No

Yes

ilogb(x)

x != 0 && !isinf(x) && !isnan(x)

Yes

No
logb(x)x != 0Yes Yes

scalbn(x, n), scalbln(x, n)

None

Yes

No

hypot(x, y)

None

Yes

No

pow(x,y)

x > 0 || (x == 0 && y > 0) ||
(x < 0 && y is an integer)

Yes

Yes

sqrt(x)

x >= 0

No

No
erf(x)NoneYesNo

erfc(x)

None

Yes

No

lgamma(x), tgamma(x)

x != 0 &&
!(x < 0 && x is an integer)

Yes

Yes

lrint(x), lround(x)

None

Yes

No

fmod(x, y), remainder(x, y),
remquo(x, y, quo)

y != 0

Yes

No

nextafter(x, y),
nexttoward(x, y)

None

Yes

No

fdim(x,y)

None

Yes

No 

fma(x,y,z)

None

Yes

No

...

See FLP03-C. Detect and handle floating-point errors for more details on how to detect floating-point errors.anchorSqrtSqrt

Denormal Arguments

Certain functions may produce range errors specifically when applied with a denormal argument. These functions are:

...

asin(

...

)

...

, asinh(

...

)

...

, atan(

...

)

...

, atanh(

...

)

...

, and erf(

...

 These functions when evaluated ). When evaluated with a denormal argument can , these functions can produce an inexact, denormal value, which is an underflow error. Subclause 7.12.1, paragraph 6, of the C Standard [ISO/IEC 9899:2011] defines the following behavior for floating-point underflow:

...

Specifically, for implementations that support Annex F but do not support denormalized numbers, the following functions and arguments will cause range errors.

FunctionArguments
fmod()((min+denorm),min)
remainder()((min+denorm),min)
remquo()((min+denorm),min,quo)

If denormal results are supported, the returned value is exact and there will not be a range error. When dealing with fmod(), Subclause subclause F.10.7.1, paragraph 2, of the C Standard [ISO/IEC 9899:2011] states:

...

Subclause F.10.7.2, paragraph 2, and Subclause subclause F.10.7.3, paragraph 2 of the C Standard [ISO/IEC 9899:2011] covers cover remainder() and and remquo() for when denormal results are supported.

...

Code Block
bgColor#ccccff
langc
#include <math.h>
 
void func(double x) {
  double result;

  if (isless(x, 0.0)) {
    /* Handle domain error */
  }

  result = sqrt(x);
}

...

Noncompliant Code Example (sinh(), Range Errors)

...

Code Block
bgColor#ccccff
langc
#include <errno.h>
#include <math.h>

#if defined(math_errhandling) \
  && (math_errhandling & MATH_ERREXCEPT)
#include <fenv.h>

#pragma STD FENV_ACCESS ON
#endif

void func(double x) { 
  double result;
  errno = 0;
  result = sinh(x);
 
  #if defined(math_errhandling) \
    && (math_errhandling & MATH_ERREXCEPT)
    feclearexcept(FE_ALL_EXCEPT);
  #endif
 
  #if !defined(math_errhandling) \
    || (math_errhandling & MATH_ERRNO)
  if (errno != 0) {
    /* Handle range error */
  }
  #endif
  #if defined(math_errhandling) \
    && (math_errhandling & MATH_ERREXCEPT)
  if (fetestexcept(FE_INVALID
                 | FE_DIVBYZERO
                 | FE_OVERFLOW
                 | FE_UNDERFLOW) != 0) {
    /* Handle range error */
  }
  #endif
}

...

...

Noncompliant Code Example (pow())

...

Code Block
bgColor#ccccff
langc
#include <errno.h>
#include <math.h>
#if defined(math_errhandling) \
  && (math_errhandling & MATH_ERREXCEPT)
#include <fenv.h>

#pragma STDC FENV_ACCESS ON
#endif

void func(double x, double y) {
  #if defined(math_errhandling) \
    && (math_errhandling & MATH_ERREXCEPT)
    feclearexcept(FE_ALL_EXCEPT);
  #endif
  errno = 0;

  double result;

  if (((x == 0.0f) && islessequal(y, 0.0)) || isless(x, 0.0)) {
    /* Handle domain or pole error */
  }

  result = pow(x, y);

  #if !defined(math_errhandling) \
    || (math_errhandling & MATH_ERRNO)
  if (errno != 0) {
    /* Handle range error */
  }
  #endif
  #if defined(math_errhandling) \
    && (math_errhandling & MATH_ERREXCEPT)
  if (fetestexcept(FE_INVALID
                 | FE_DIVBYZERO
                 | FE_OVERFLOW
                 | FE_UNDERFLOW) != 0) {
    /* Handle range error */
  }
  #endif
}

Noncompliant Code Example (asin(),

...

Denormal Argument)

This noncompliant code example determines the arcsin of x:

Code Block
bgColor#FFcccc
langc
#include <math.h>
 
void func(float x) {
  float result;
  result = asin(x);
  /* ... */
}

Compliant Soluction (asin(),

...

Denormal Argument)

Because this function has no domain errors but may have range errors, the programmer must detect a range error and act accordingly:

Code Block
bgColor#ccccff
langc
#include <errno.h>
#include <math.h>

#if defined(math_errhandling) \
  && (math_errhandling & MATH_ERREXCEPT)
#include <fenv.h>

#pragma STDC FENV_ACCESS ON
#endif

void func(float x) { 
  float result;
  errno = 0;
  result = asin(x);
 
  #if defined(math_errhandling) \
    && (math_errhandling & MATH_ERREXCEPT)
    feclearexcept(FE_ALL_EXCEPT);
  #endif
 
  #if !defined(math_errhandling) \
    || (math_errhandling & MATH_ERRNO)
  if (errno != 0) {
    /* Handle range error */
  }
  #endif
  #if defined(math_errhandling) \
    && (math_errhandling & MATH_ERREXCEPT)
  if (fetestexcept(FE_INVALID
                 | FE_DIVBYZERO
                 | FE_OVERFLOW
                 | FE_UNDERFLOW) != 0) {
    /* Handle range error */
  }
  #endif
}

...

Risk Assessment

Failure to prevent or detect domain and range errors in math functions may cause unexpected results.

...

Bibliography

[ISO/IEC 9899:2011]

Subclause 7.3.2, "Conventions"
Subclause 7.12.1, "Treatment of Error Conditions"
Subclause F.10.7, "Remainder Functions" 

[Plum 1985]Rule 2-2
[Plum 1989]Topic 2.10, "conv—Conversions and Overflow"
[UNIX 1992]System V Interface Definition (SVID3)

 

...