Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: added a section on *gamma()

...

Many math errors can be prevented by carefully bounds checking the arguments before calling functions, and taking alternative action if the bounds are violated. In particular, the following functions should be bounds checked as follows:

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

However, for some functions it is not practical to use bounds checking to prevent all errors.  In the above pow example, the bounds check does not prevent the pow(10., 1e6) range error. In these cases detection must be used, either in addition to bounds checking or instead of bounds checking.

...

lgammma(x)

(x == 0) || (x < 0 && x is an integer) || (x is too large)

tgammma(x)

(x == 0) || (x < 0 && x is an integer) || (x is too large) || (x is too small)

However, for some functions it is not practical to use bounds checking to prevent all errors.  In the above pow example, the bounds check does not prevent the pow(10., 1e6) range error. In these cases detection must be used, either in addition to bounds checking or instead of bounds checking.

Anchor
ArcTrig
ArcTrig

acos(x), asin(x)

Noncompliant Code Example

The following noncompliant code computes the arc cosine of the variable x

Code Block
bgColor#FFcccc

...

acos(x), asin(x)

Noncompliant Code Example

The following noncompliant code computes the arc cosine of the variable x

Code Block
bgColor#FFcccc

double x;
double result;

/* Set the value for x */

result = acos(x);

Wiki Markup
However, this code may produce a _domain error_ if {{x}} is not in the range \[-1, \+1\].

Compliant Solution

The following compliant solution uses bounds checking to ensure that there is not a domain error.

Code Block
bgColor#ccccff
double x;
double result;

/* Set the value for x */

ifresult (= isnanacos(x) || isless(x,-1) || isgreater(x, 1) ){
     /* handle domain error */
}

result = acos(x);

...

;

Wiki Markup
However, this code may produce a _domain error_ if {{x}} is not in the range \[-1, \+1\].

Compliant Solution

The following compliant solution uses bounds checking to ensure that there is not a domain error

...

atan2(y, x)

Noncompliant Code Example

The following noncompliant code computes the arc tangent of the two variables x and y.

Code Block
bgColor#FFcccc#ccccff
double x;
double y;
double result;

/* Set the value for x and y */

resultif =( atan2(y, x);

However, this code may produce a domain error if both x and y are zero.

Compliant Solution

isnan(x) || isless(x,-1) || isgreater(x, 1) ){
     /* handle domain error */
}

result = acos(x);

Anchor
ArcTan
ArcTan

atan2(y, x)

Noncompliant Code Example

The following noncompliant code computes the arc tangent of the two variables x and yThe following compliant solution tests the arguments to ensure that there is not a domain error.

Code Block
bgColor#ccccff#FFcccc
double x;
double y;
double result;

/* Set the value for x and y */

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

result = atan2(y, x);

...

);

However, this code may produce a domain error if both x and y are zero.

Compliant Solution

The following compliant solution tests the arguments to ensure that there is not a domain error

...

log(x), log10(x)

Noncompliant Code Example

The following noncompliant code determines the natural logarithm of x.

Code Block
bgColorFFcccc#ccccff
double x;
double y;
double result;

/* Set the value for x and y */

resultif ( (x = log(x);

However, this code may produce a domain error if x is negative and a range error if x is zero.

Compliant Solution

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

result = atan2(y, x);

Anchor
Log
Log

log(x), log10(x)

Noncompliant Code Example

The following noncompliant code determines the natural logarithm of xThe following compliant solution tests the suspect arguments to ensure that no domain errors or range errors are raised.

Code Block
bgColor#ccccffFFcccc
double x;
double result;

/* Set the value for x */

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

result = log(x);

...

result = log(x);

However, this code may produce a domain error if x is negative and a range error if x is zero.

Compliant Solution

The following compliant solution tests the suspect arguments to ensure that no domain errors or range errors are raised

...

pow(x, y)

Noncompliant Code Example

The following noncompliant code raises x to the power of y.

Code Block
bgColor#FFcccc#ccccff
double x;
double yresult;
double result;

result = pow
/* Set the value for x */

if (isnan(x) || islessequal(x, y0));

...

 {
  /* handle domain and range errors */
}

result = log(x);

Anchor
Power
Power

pow(x, y)

Noncompliant Code Example

This code only performs bounds checking on x and y. It prevents domain errors and some range errors, but does not prevent range errors where the result cannot be represented as a double (see the Error Checking and Detection section below regarding ways to mitigate the effects of a range error)The following noncompliant code raises x to the power of y.

Code Block
bgColor#ffcccc#FFcccc
double x;
double y;
double result;

ifresult = pow(((x == 0.f) && islessequal(y, 0)) ||
    (isless(x, 0))) {
  /* handle domain and range errors */
}

result = pow(x, y);

...

, y);

However, this code may produce a domain error if x is negative and y is not an integer, or if x is zero and y is zero. A domain error or range error may occur if x is zero and y is negative, and a range error may occur if the result cannot be represented as a double.

Noncompliant Code Example

This code only performs bounds checking on x and y. It prevents domain errors and some range errors, but does not prevent range errors where the result cannot be represented as a double (see the Error Checking and Detection section below regarding ways to mitigate the effects of a range error).

Code Block
bgColor#ffcccc

...

sqrt(x)

Noncompliant Code Example

The following noncompliant code determines the square root of x

Code Block
bgColor#FFcccc
double x;
double y;
double result;

result = sqrt(x);

However, this code may produce a domain error if x is negative.

Compliant Solution

if (((x == 0.f) && islessequal(y, 0)) ||
    (isless(x, 0))) {
  /* handle domain and range errors */
}

result = pow(x, y);

Anchor
Sqrt
Sqrt

sqrt(x)

Noncompliant Code Example

The following noncompliant code determines the square root of xThe following compliant solution tests the suspect argument to ensure that no domain error is raised.

Code Block
bgColor#ccccff#FFcccc

double x;
double result;

result = sqrt(x);

However, this code may produce a domain error if x is negative.

Compliant Solution

The following compliant solution tests the suspect argument to ensure that no domain error is raised.

Code Block
bgColor#ccccff

double x;
double result;

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

result = sqrt(x);

Anchor
Gamma
Gamma

lgamma(x), tgamma(x)

The "too large" and "too small" conditions for a range error in the gamma functions are vague enough to make it very difficult to catch all possible range errors simply by looking at the input.

Noncompliant Code Example

The following noncompliant code example attempts to prevent domain and range errors, but a range error occurs nonetheless.

Code Block
bgColor#ffcccc

float x = -90.5;

if ((x == 0) || (x < 0 && x == nearbyint(x))) {
  /* Handle Error */
}

float f = tgamma(x);

Compliant Solution

This compliant solution detects the underflow by using the methods described below in the Error Checking and Detection section.

Code Block
bgColor#ccccff

float x = -90.5;

if ((x == 0) || (x < 0 && x == nearbyint(x))) {
  /* Handle Error */
}

feclearexcept(FE_ALL_EXCEPT);

float f = tgamma(x)
double x;
double result;

if (isless(x,fetestexcept(FE_UNDERFLOW) != 0)) {
  /* handle domain error */
}

result = sqrt(x);printf("Underflow detected\n");
}

Anchor
Error Checking and Detection
Error Checking and Detection

Error Checking and Detection

Wiki Markup
The exact treatment of error conditions from math functions is quite complicated.  C99 Section 7.12.1 defines the following behavior for floating point overflow \[[ISO/IEC 9899:1999|AA. C References#ISO/IEC 9899-1999]\]

...