Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: s/float/double/g; all functions here take double

...

Function

Bounds-checking

acos( x ), asin( x )

-1 <= x && x <= 1

atan2( y, x )

x != 0 || y != 0

log( x ), log10( x )

x >= 0

pow( x, y )

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

sqrt( x )

x >= 0

The calling function should take alternative action if these bounds are violated.

...

Wiki Markup
This code may produce a domain error if the argument is not in the range \[-1, \+1\].

Code Block
bgColor#FFcccc
floatdouble x, result;

result = acos(x);

...

This code uses bounds checking to ensure that there is not a domain error.

Code Block
bgColor#ccccff
floatdouble x, result;

if ( islessequal(x,-1) || isgreaterequal(x, 1) ){
     /* handle domain error */
}

result = acos(x);

...

This code may produce a domain error if both x and y are zero.

Code Block
bgColor#FFcccc
floatdouble x, y, result;

result = atan2(y, x);

...

This code tests the arguments to ensure that there is not a domain error.

Code Block
bgColor#ccccff
floatdouble x, y, result;

if ( (x == 0.f) && (y == 0.f) ) {
     /* handle domain error */
}

result = atan2(y, x);

...

This code may produce a domain error if x is negative and a range error if x is zero.

Code Block
bgColorFFcccc
floatdouble result, x;

result = log(x);

...

This code tests the suspect arguments to ensure that no domain or range errors are raised.

Code Block
bgColor#ccccff
floatdouble result, x;

if (islessequal(x, 0)) {
  /* handle domain and range errors */
}

result = log(x);

...

This code may produce a domain error if x is zero and y less than or equal to zero. A range error may also occur if x is zero and y is negative.

Code Block
bgColor#FFcccc
floatdouble x, y, result;

result = pow(x, y);

...

This code tests x and y to ensure that there will be no range or domain errors.

Code Block
bgColor#ccccff
floatdouble x, y, result;

if ( ((x == 0.f) && islessequal(y, 0)) ||
    (isless(x, 0) && !isInteger(y))) {
  /* handle domain error condition */
}

result = pow(x, y);

...

This code may produce a domain error if x is negative.

Code Block
bgColor#FFcccc
floatdouble x, result;

result = sqrt(x);

...

This code tests the suspect argument to ensure that no domain error is raised.

Code Block
bgColor#ccccff
floatdouble x, result;

if (isless(x, 0)){
  /* handle domain error */
}

result = sqrt(x);

...

The macro

Code Block
HUGE_VAL

expands to a positive double constant expression, not necessarily representable as a
float. The macros

Code Block
HUGE_VALF
HUGE_VALL

are respectively float and long double analogs of HUGE_VAL.

...

Code Block
bgColor#ccccff
if (/* arguments will cause a domain or range error */) {
  /* handle the error */
}
else {
  /* perform computation */
}

For functions where argument validation is difficult, including pow(), erfc(), lgamma(), and tgamma(), one can employ the following approach.

Code Block
bgColor#ccccff

#include <math.h>
#if defined(math_errhandling) && (math_errhandling & MATH_ERREXCEPT)
#include <fenv.h>
#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 error */
}
#endif
#if defined(math_errhandling) && (math_errhandling & MATH_ERREXCEPT)
if (fetestexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW) != 0) {
  /* handle error */
}
#endif

Implementation Details

System V Interface Definition, Third Edition

...