gawk: Arbitrary Precision Integers

1 
1 15.5 Arbitrary-Precision Integer Arithmetic with 'gawk'
1 =======================================================
1 
1 When given the '-M' option, 'gawk' performs all integer arithmetic using
1 GMP arbitrary-precision integers.  Any number that looks like an integer
1 in a source or data file is stored as an arbitrary-precision integer.
1 The size of the integer is limited only by the available memory.  For
1 example, the following computes 5^4^3^2, the result of which is beyond
1 the limits of ordinary hardware double-precision floating-point values:
1 
1      $ gawk -M 'BEGIN {
1      >   x = 5^4^3^2
1      >   print "number of digits =", length(x)
1      >   print substr(x, 1, 20), "...", substr(x, length(x) - 19, 20)
1      > }'
1      -| number of digits = 183231
1      -| 62060698786608744707 ... 92256259918212890625
1 
1    If instead you were to compute the same value using
1 arbitrary-precision floating-point values, the precision needed for
1 correct output (using the formula 'prec = 3.322 * dps') would be 3.322 x
1 183231, or 608693.
1 
1    The result from an arithmetic operation with an integer and a
1 floating-point value is a floating-point value with a precision equal to
1 the working precision.  The following program calculates the eighth term
1 in Sylvester's sequence(1) using a recurrence:
1 
1      $ gawk -M 'BEGIN {
1      >   s = 2.0
1      >   for (i = 1; i <= 7; i++)
1      >       s = s * (s - 1) + 1
1      >   print s
1      > }'
1      -| 113423713055421845118910464
1 
1    The output differs from the actual number,
1 113,423,713,055,421,844,361,000,443, because the default precision of 53
1 bits is not enough to represent the floating-point results exactly.  You
1 can either increase the precision (100 bits is enough in this case), or
1 replace the floating-point constant '2.0' with an integer, to perform
1 all computations using integer arithmetic to get the correct output.
1 
1    Sometimes 'gawk' must implicitly convert an arbitrary-precision
1 integer into an arbitrary-precision floating-point value.  This is
1 primarily because the MPFR library does not always provide the relevant
1 interface to process arbitrary-precision integers or mixed-mode numbers
1 as needed by an operation or function.  In such a case, the precision is
1 set to the minimum value necessary for exact conversion, and the working
1 precision is not used for this purpose.  If this is not what you need or
1 want, you can employ a subterfuge and convert the integer to floating
1 point first, like this:
1 
1      gawk -M 'BEGIN { n = 13; print (n + 0.0) % 2.0 }'
1 
1    You can avoid this issue altogether by specifying the number as a
1 floating-point value to begin with:
1 
1      gawk -M 'BEGIN { n = 13.0; print n % 2.0 }'
1 
1    Note that for this particular example, it is likely best to just use
1 the following:
1 
1      gawk -M 'BEGIN { n = 13; print n % 2 }'
1 
1    When dividing two arbitrary precision integers with either '/' or
1 '%', the result is typically an arbitrary precision floating point value
1 (unless the denominator evenly divides into the numerator).
1 
1    ---------- Footnotes ----------
1 
1    (1) Weisstein, Eric W. 'Sylvester's Sequence'.  From MathWorld--A
1 Wolfram Web Resource
1 (<http://mathworld.wolfram.com/SylvestersSequence.html>).
1