gawk: Setting the rounding mode

1 
1 15.4.5 Setting the Rounding Mode
1 --------------------------------
1 
1 The 'ROUNDMODE' variable provides program-level control over the
1 rounding mode.  The correspondence between 'ROUNDMODE' and the IEEE
1 rounding modes is shown in ⇒Table 15.5 table-gawk-rounding-modes.
1 
1 Rounding mode                    IEEE name              'ROUNDMODE'
1 ---------------------------------------------------------------------------
1 Round to nearest, ties to even   'roundTiesToEven'      '"N"' or '"n"'
1 Round toward positive infinity   'roundTowardPositive'  '"U"' or '"u"'
1 Round toward negative infinity   'roundTowardNegative'  '"D"' or '"d"'
1 Round toward zero                'roundTowardZero'      '"Z"' or '"z"'
1 Round away from zero                                    '"A"' or '"a"'
1 
1 Table 15.5: 'gawk' rounding modes
1 
1    'ROUNDMODE' has the default value '"N"', which selects the IEEE 754
1111 rounding mode 'roundTiesToEven'.  In ⇒(gawk)setting 'ROUNDMODE' to '"A"' has no effect setting 'ROUNDMODE' to '"A"' has no effect.
1 
1    The default mode 'roundTiesToEven' is the most preferred, but the
1 least intuitive.  This method does the obvious thing for most values, by
1 rounding them up or down to the nearest digit.  For example, rounding
1 1.132 to two digits yields 1.13, and rounding 1.157 yields 1.16.
1 
1    However, when it comes to rounding a value that is exactly halfway
1 between, things do not work the way you probably learned in school.  In
1 this case, the number is rounded to the nearest even digit.  So rounding
1 0.125 to two digits rounds down to 0.12, but rounding 0.6875 to three
1 digits rounds up to 0.688.  You probably have already encountered this
1 rounding mode when using 'printf' to format floating-point numbers.  For
1 example:
1 
1      BEGIN {
1          x = -4.5
1          for (i = 1; i < 10; i++) {
1              x += 1.0
1              printf("%4.1f => %2.0f\n", x, x)
1          }
1      }
1 
1 produces the following output when run on the author's system:(1)
1 
1      -3.5 => -4
1      -2.5 => -2
1      -1.5 => -2
1      -0.5 => 0
1       0.5 => 0
1       1.5 => 2
1       2.5 => 2
1       3.5 => 4
1       4.5 => 4
1 
1    The theory behind 'roundTiesToEven' is that it more or less evenly
1 distributes upward and downward rounds of exact halves, which might
1 cause any accumulating round-off error to cancel itself out.  This is
1 the default rounding mode for IEEE 754 computing functions and
1 operators.
1 
1                      Rounding Modes and Conversion
1 
1    It's important to understand that, along with 'CONVFMT' and 'OFMT',
1 the rounding mode affects how numbers are converted to strings.  For
1 example, consider the following program:
1 
1      BEGIN {
1          pi = 3.1416
1          OFMT = "%.f"        # Print value as integer
1          print pi            # ROUNDMODE = "N" by default.
1          ROUNDMODE = "U"     # Now change ROUNDMODE
1          print pi
1      }
1 
1 Running this program produces this output:
1 
1      $ gawk -M -f roundmode.awk
1      -| 3
1      -| 4
1 
1    The other rounding modes are rarely used.  Rounding toward positive
1 infinity ('roundTowardPositive') and toward negative infinity
1 ('roundTowardNegative') are often used to implement interval arithmetic,
1 where you adjust the rounding mode to calculate upper and lower bounds
1 for the range of output.  The 'roundTowardZero' mode can be used for
1 converting floating-point numbers to integers.  When rounding away from
1 zero, the nearest number with magnitude greater than or equal to the
1 value is selected.
1 
1    Some numerical analysts will tell you that your choice of rounding
1 style has tremendous impact on the final outcome, and advise you to wait
1 until final output for any rounding.  Instead, you can often avoid
1 round-off error problems by setting the precision initially to some
1 value sufficiently larger than the final desired precision, so that the
1 accumulation of round-off error does not influence the outcome.  If you
1 suspect that results from your computation are sensitive to accumulation
1 of round-off error, look for a significant difference in output when you
1 change the rounding mode to be sure.
1 
1    ---------- Footnotes ----------
1 
1    (1) It is possible for the output to be completely different if the C
1 library in your system does not use the IEEE 754 even-rounding rule to
1 round halfway cases for 'printf'.
1