Graphics Reference
In-Depth Information
Inserting the values into the expressions gives
(a+b)+c=(9876543.0f + -9876547.0f) + 3.45f = -4.0f + 3.45f = -0.55f
a + (b + c) = 9876543.0f + (-9876547.0f + 3.45f) = 9876543.0f + -9876544.0f = -1.0f
illustrating the difference between the two expressions.
As a corollary, note that a compiler will not (or should not) turn x + 2.0f + 0.5f
into x + 2.5f , as this could give a completely different result. The compiler will be
able to fold floating-point constants only from the left for left-associative operators
(which most operators are). That is, turning 2.0f + 0.5f + x into 2.5f + x at com-
pile time is sound. A good coding rule is to place floating-point constants to the left of
any variables (that is, unless something else specific is intended with the operation).
Repeated rounding errors cause numbers slowly to erode from the right, from the
least significant digits. This leads to loss of precision, which can be a serious problem.
Even worse is the problem of cancellation, which can lead to significant digits being
lost at the front (left) of a number. This loss is usually the result of a single operation:
the subtraction of two subexpressions nearly equal in value (or, equivalently, the
addition of two numbers of near equal magnitude but of opposite sign).
As an example, consider computing the discriminator b 2
4 ac of a quadratic
=
=
=
·
10 6 ,
equation for b
3.456, a
1.727, and c
1.729. The exact answer is 4
but single-precision evaluation gives the result as 4.82387
10 6 , of which only the
first single digit is correct! When, as here, errors become significant due to cancella-
tion, the cancellation is referred to as catastrophic . Cancellation does not have to be
catastrophic, however. For example, consider the subtraction 1.875
·
1.625
=
0.25.
Expressed in binary it reads 1.111
0.010. Although significant digits have
been lost in the subtraction, this time it is not a problem because all three quantities
are exactly representable. In this case, the cancellation is benign .
In all, extreme care must be taken when working with floating-point arithmetic.
Even something as seemingly simple as selecting between the two expressions a ( b
1.101
=
c )
and ab
ac is deceptively difficult. If b and c are close in magnitude, the first expres-
sion exhibits a cancellation problem. The second expression also has a cancellation
problem when ab and ac are near equal. When
1, the difference between ab and
ac increases more (compared to that between b and c ) and the cancellation problem
of the second expression is reduced. However, when
|
a
| >
1 the terms ab and ac
become smaller, amplifying the cancellation error, while at the same time the can-
cellation error in the first expression is scaled down. Selecting the best expression is
therefore contingent on knowledge about the values taken by the involved variables.
(Other factors should also be considered, such as overflow and underflow errors.)
In many cases rewriting an expression can help avoid a cancellation error.
For example, the function
|
a
| <
f ( x )
=
1
cos( x )
 
Search WWH ::




Custom Search