Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: added #pragma STDC FENV_ACCESS ON

...

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

#pragma STDC FENV_ACCESS ON
#endif

/* ... */

#if defined(math_errhandling) \
  && (math_errhandling & MATH_ERREXCEPT)
  feclearexcept(FE_ALL_EXCEPT);
#endif
errno = 0;

/* Call the function */

#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

...

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);
}

Anchor
HyperTrig
HyperTrig

Noncompliant Code Example

...

(

...

sinh(), Range Errors)

This noncompliant code example determines the hyperbolic cosine of x:

...

This code may produce a range error if x has a very large magnitude.

Compliant Solution

...

(

...

sinh(), Range Errors)

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 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
}

...

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
}

...

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
}

...