Node:Mathematical errors, Next:Introduction to GDB, Previous:Run-time errors, Up:Debugging
Mathematical errors are a special kind of run-time error. They may
not necessarily cause your program to crash, but they are likely to
produce all sorts of strange results if you are doing some complex
calculations in your program. Consider the following line of code:
root = sqrt (-1.0);
Readers with a smattering of mathematics will recognise that this code
cannot give a sensible answer. The square root of -1 is a complex
number called i. The number i is a so-called imaginary
number, and cannot be represented by a floating-point value, which is
what the sqrt
function returns.
What happens in such a case? Two things:
NAN
(which means "not a number") or INFINITY
.
There are several kinds of floating-point exception:
FE_INVALID
: The "Invalid Operation" exception.
Raised if the operands are invalid for the given operation, for
example, if you are trying to take the square root of a negative
number, as above.
FE_DIVBYZERO
: The "Division by Zero" exception.
Raised when a finite, nonzero number is divided by zero.
FE_OVERFLOW
: The "Overflow" exception. Raised
when the result cannot be expressed as a finite value, for example
when a finite, nonzero number is divided by zero. Whenever this exception
is raised, the FE_INEXACT
exception is also raised.
FE_UNDERFLOW
: The "Underflow" exception. Raised
when an intermediate result is too small to be calculated accurately,
or when an operation's rounded result is too small to be normalized.
Normalisation, roughly speaking, is the process of converting a number to
scientific notation, such as converting 235 to 2.35e2,
where the mantissa, or number to the left of the e
, must not be zero.
See Floating point variables, for more information on scientific notation.)
FE_INEXACT
: The "Inexact" exception.
Raised if a rounded result is not exact, for example when calculating
an irrational number such as the square root of 2.
You can test for these exceptions with the fetestexcept
function, which takes one parameter, a bitwise OR'd list of the
exception flags from the list above for which you are testing, and
returns a nonzero value containing a bitwise OR'd list of the flags
you passed it for the exceptions that actually occurred. You can also
clear selected flags with the feclearexcept
function, which
accepts a bitwise-OR'd list of exception flags to clear, and returns
zero if it was successful. (You can pass either of these function the
macro FE_ALL_EXCEPT
, which contains all of the floating-point
exception flags OR'd together.)
In case this explanation is unclear, let's look at a practical example.