Floating point conditions

When programming, there are certain error condition that might arise from your code. If the compiler catches any compilation errors, it will stop compilation and tell you what and where the error is. The compiler also may issue a warning for certain constructs, which may or may not give you problems during runtime.

Here are some floating point conditions that you as a programmer should be aware of when doing floating point arithmetic (any of addition, subtraction, multiplication, and division), namely INF, IND, and NaN (QNAN and SNAN) conditions and errors.

#NaN value

C++ NaN stands for not a number. It is a value that depicts an undefined or unspecified value with floating point. The concept of NaN was introduced in 1985 by the IEEE 754 floating-point standard in which the concept of infinities was also given.

Here is an example of what NaN values can cause in a real video game: black dots.

#QNaN and #SNaN

There are two kinds of NaNs, quiet and signalling. Both are very similar, and in most instances they are identical. With MSVC, the signalling NaNs (sNaN) are by default quiet NaNs. They won’t raise any hardware exceptions (as all floating point exceptions are) and you won’t notice anything wrong until the printouts contain nothing but 1.#QNAN and the simulation fails miserably.

#INF value

C++ INF denotes “infinity”. Due to the finite nature of floating point numbers (32-bit for floats, 64-bit for doubles), infinite is represented by a finite value.

This type of error condition / value arises when the resultant number is overflowing or underflowing the capacity of the floating point number. In other words, the value is too large or too small to be represented as a floating point value.

Method 3 (MSVC): Control floating-point control word.

The use of _controlfp and _control87 family will alter the floating-point control word, essentially making the computer issue a hardware exception when a floating point exception occurs. The default with MSVC is to silence floating point exceptions, with the possibility to silently destroy simulations.

I personally recommend turning on all floating point exceptions, so all (or most) cases can be reviewed and the code made more robust.

The usage is a bit counter-intuitive, but after a while you’ll get used to it. Here is what works for me.

// According to the docs, always clear fp control word
auto state = _clearfp();
state = _control87(0,0);

This will reset, and get current floating point control word state.

With this, we can modify the floating point control word to our liking.