gawk: Getting Accuracy
1
1 15.4.2 Getting the Accuracy You Need
1 ------------------------------------
1
1 Can arbitrary-precision arithmetic give exact results? There are no
1 easy answers. The standard rules of algebra often do not apply when
1 using floating-point arithmetic. Among other things, the distributive
1 and associative laws do not hold completely, and order of operation may
1 be important for your computation. Rounding error, cumulative precision
1 loss, and underflow are often troublesome.
1
1 When 'gawk' tests the expressions '0.1 + 12.2' and '12.3' for
1 equality using the machine double-precision arithmetic, it decides that
1 they are not equal! (⇒Comparing FP Values.) You can get the
1 result you want by increasing the precision; 56 bits in this case does
1 the job:
1
1 $ gawk -M -v PREC=56 'BEGIN { print (0.1 + 12.2 == 12.3) }'
1 -| 1
1
1 If adding more bits is good, perhaps adding even more bits of
1 precision is better? Here is what happens if we use an even larger
1 value of 'PREC':
1
1 $ gawk -M -v PREC=201 'BEGIN { print (0.1 + 12.2 == 12.3) }'
1 -| 0
1
1 This is not a bug in 'gawk' or in the MPFR library. It is easy to
1 forget that the finite number of bits used to store the value is often
1 just an approximation after proper rounding. The test for equality
1 succeeds if and only if _all_ bits in the two operands are exactly the
1 same. Because this is not necessarily true after floating-point
1 computations with a particular precision and effective rounding mode, a
1 straight test for equality may not work. Instead, compare the two
1 numbers to see if they are within the desirable delta of each other.
1
1 In applications where 15 or fewer decimal places suffice, hardware
1 double-precision arithmetic can be adequate, and is usually much faster.
1 But you need to keep in mind that every floating-point operation can
1 suffer a new rounding error with catastrophic consequences, as
1 illustrated by our earlier attempt to compute the value of pi. Extra
1 precision can greatly enhance the stability and the accuracy of your
1 computation in such cases.
1
1 Additionally, you should understand that repeated addition is not
1 necessarily equivalent to multiplication in floating-point arithmetic.
1 In the example in ⇒Errors accumulate:
1
1 $ gawk 'BEGIN {
1 > for (d = 1.1; d <= 1.5; d += 0.1) # loop five times (?)
1 > i++
1 > print i
1 > }'
1 -| 4
1
1 you may or may not succeed in getting the correct result by choosing an
1 arbitrarily large value for 'PREC'. Reformulation of the problem at
1 hand is often the correct approach in such situations.
1