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