Home > Writings > Programming > Floating Point Essentials > Programming Guidelines

Floating Point Essentials

Programming Guidelines

Since floating point numbers are by nature inexact, and therefore often contain just close approximations of the intended value, programmers must design their code accordingly. A major pitfall is testing for equality when using floating point values. Programmers want occasionally to do things like this:

if MyVar=2.1 then DoThis else DoThat;

Where MyVar is a floating point, the DoThis branch might in fact never be executed, simply because the comparison value of 2.1 cannot be exactly represented in floating point format.

In case you have to compare two floating points, do not compare them for equality, but compare the difference against a threshold:

if Abs(MyVarOne-MyVarTwo)<0.0001 then DoEqual else DoDifferent

In addition, in many cases the final contents of MyVar will be the result of prior calculations. So, even if the intended value can be exactly represented in the binary Floating Point format, the calculation might involve other numbers that are approximations instead of exact representations, so that the final result would only be close to the desired value. Hence, the algorithm would fail. Possible techniques one could use to overcome this problem are to truncate or round the FPV to an integer, taking into account the range and precision provided:

if Round(MyVar)=2 then ...

It is possible to scale a variable prior to rounding if you need one or more digits after the decimal point, but beware of range and precision (never assume that the value is accurate to the last decimal place):

if Round(MyVar * 10)=21 then ...

Alternatively, it might be possible to use smaller than/greater than instead of comparing for equality:

if MyVar>2.1 then ...
|

For many applications, in particular when dealing with financial data, the better solution is to use (scaled) integers instead of floating point values. In Delphi, the Currency type is a scaled integer with four digits after the decimal separator. So, a stored value of 65481 designates the number 6.5481. When performing calculations on integers, the resulting integer will always be an exact integer number. Do note that the Currency type, although it is an integer, is not handled in the CPU but as an integer in the FPU.

Finally, beware that the ultimate precision of your calculated value depends not just on the result variable format, but is directly influenced by the precision of the other variables used in the calculation. For example, when mixing single and double precision variables, you should consider the final result to have no better than single precision.

Next: Further Reading

 

Floating Point Essentials

Science and Technology
News

Download

Printable version
(PDF Document)

Size: 75KB