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