=pod

=head1 NAME

   Math::GMPq - perl interface to the GMP library's rational (mpq) functions.

=head1 DEPENDENCIES

   This module needs the GMP C library - available from:
   L<https://gmplib.org>.

=head1 DESCRIPTION

   A bigrational module utilising the Gnu MP (GMP) library.
   Basically this module simply wraps all of the 'mpq'
   (rational number) functions provided by that library.
   The documentation below extensively plagiarises the GMP
   documentation (which can be found at L<https://gmplib.org>).
   See also the Math::GMPq test suite for examples of usage.

=head1 SYNOPSIS

   use Math::GMPq qw(:mpq);

   my $str = '123542/4'; # numerator = 123542
                         # denominator = 4
   my $base = 10;

   # Create the Math::GMPq object
   my $bn1 = Rmpq_init(); # Value set to 0/1

   # Assign a value.
   Rmpq_set_str($bn1, $str, $base);

   # Remove any factors common to both numerator and
   # denominator so that gcd(numerator, denominator) == 1.
   Rmpq_canonicalize($bn1);

   # or just use the new() function:
   my $rational = Math::GMPq->new('1234/1179');

   # Perform some operations, either by using function calls
   # or by utilising operator overloading ... see 'FUNCTIONS'
   # below.

   .
   .

   # print out the value held by $bn1 (in octal):
   print Rmpq_get_str($bn1, 8), "\n"; # prints '170513/2'

   # print out the value held by $bn1 (in decimal) with:
   print Rmpq_get_str($bn1, 10), "\n"; # prints '61771/2'.
   # or, courtesy of operator loading, simply with:
   print $bn1, "\n"; # again prints '61771/2'.

   # print out the value held by $bn1 (in base 29)
   # using the (alternative) Rmpq_out_str()
   # function. (This function doesn't print a newline.)
   Rmpq_out_str($bn1, 29);

=head1 MEMORY MANAGEMENT

   Objects created with Rmpq_create_init() have been
   blessed into package Math::GMPq. They will
   therefore be automatically cleaned up by the
   DESTROY() function whenever they go out of scope.

   If you wish, you can create unblessed objects
   with Rmpq_init_nobless().
   It will then be up to you to clean up the memory
   associated with these objects by calling
   Rmpq_clear($op), for each object.
   Alternatively the objects will be cleaned up
   when the script ends.
   I don't know why you would want to create unblessed
   objects - the point is you can if you want to :-)

=head1 FUNCTIONS

   See the GMP documentation at http://gmplib.org.

   These next 3 functions are demonstrated above:
   $rop   = Rmpq_init();
   Rmpq_set_strl($rop, $str, $base); # 1 < $base < 63
   $str = Rmpq_get_str($op, $base); # 1 < $base < 37

   The following functions are simply wrappers around a GMP
   function of the same name. eg. Rmpq_swap() is a wrapper around
   mpq_swap() which is fully documented in the GMP manual at
   http://gmplib.org.

   "$rop", "$op1", "$op2", etc. are simply  Math::GMPq objects -
   the return value of Rmpq_init or Rmpq_init_nobless
   functions. They are in fact references to GMP structures.
   The "$rop" argument(s) contain the result(s) of the calculation
   being done, the "$op" argument(s) being the input(s) into that
   calculation.
   Generally, $rop, $op1, $op2, etc. can be the same perl variable,
   though often they will be distinct perl variables referencing
   distinct GMP structures.
   Eg. something like Rmpq_add($r1, $r1, $r1),
   where $r1 *is* the same reference to the same GMP structure,
   would add $r1 to itself and store the result in $r1. Think of it
   as $r1 += $r1. Otoh, Rmpq_add($r1, $r2, $r3), where each of the
   arguments is a different reference to a different GMP structure
   would add $r2 to $r3 and store the result in $r1. Think of it as
   $r1 = $r2 + $r3. Mostly, the first argument is the argument that
   stores the result and subsequent arguments provide the input values.
   Exceptions to this can be found in some of the functions that
   actually return a value.
   Like I say, see the GMP manual for details. I hope it's
   intuitively obvious or quickly becomes so. Also see the test
   suite that comes with the distro for some examples of usage.

   "$ui" means any integer that will fit into a C 'unsigned long int.

   "$si" means any integer that will fit into a C 'signed long int'.

   "$double" means any number (not necessarily integer) that will fit
   into a C 'double'.

   "$NV" is perl's floating point type (run "perl -V:nvtype")

   "$bool" means a value (usually a 'signed long int') in which
   the only interest is whether it evaluates as true or false.

   "$str" simply means a string of symbols that represent a number,
   eg "1234567890987654321234567/7".
   Valid bases for GMP numbers are 2 to 62 (inclusive).

   ############

   CANONICALIZE

   Rmpq_canonicalize($op);
    Remove any factors that are common to the numerator and
    denominator of $op, and make the denominator positive.

   ##########

   INITIALIZE

   Normally, a variable should be initialized once only or at least be
   cleared, using `Rmpq_clear', between initializations.
   'DESTROY' (which calls 'Rmpq_clear') is automatically called on
   blessed objects whenever they go out of scope.

   See the section 'MEMORY MANAGEMENT' (above).

   $rop = Math::GMPq::new();
   $rop = Math::GMPq->new();
   $rop = new Math::GMPq();
   $rop = Rmpq_init();
   $rop = Rmpq_init_nobless();
    Initialize $rop and set it to 0/1.

   ####################

   ASSIGNMENT FUNCTIONS

   Rmpq_set($rop, $op);
   Rmpq_set_z($rop, $z); # $z is a Math::GMPz object
    Set $rop to value contained in 2nd arg.

   Rmpq_set_ui($rop, $ui1 , $ui2);
   Rmpq_set_si($rop, $si ,  $ui );
   Rmpq_set_IV($rop, $iv1 , $iv2);
    Set $rop to 2nd arg / 3rd arg.
    The 3rd arg should be an unsigned value. That is, the value -2/3
    should be assigned as 2nd arg is -2, 3rd arg is 3 ... not 2nd
    arg is 2, third arg is -3.
    With Rmpq_set_IV, $iv1 and $iv2 must both have their IOK flag set,
    or the function will croak. Best to first check IOK_flag($iv), which
    will return a non-zero value if and only if the IOK flag is set.

   Rmpq_set_d ($rop, $double);
   Rmpq_set_f ($rop, $f); # $f is a Math::GMPf object
   Rmpq_set_d ($rop, $op);
   Rmpq_set_NV($rop, $nv);
   $rop = mpfr2mpq($fr); # $fr is a Math::MPFR object
    Set $rop to the value of the 2nd arg, without rounding.
    Assigning an Inf or NaN is a fatal error.
    With Rmpq_set_NV, $nv must have its NOK flag set, or the function
    will croak. Best to first check NOK_flag($nv), which will return a
    non-zero value if and only if the NOK flag is set.



   Rmpq_set_str($rop, $str, $base);
    Set $rop from $str in the given base $base.
    Allowed strings, and their interpretations, are specified below
    in the COMBINED INITIALIZATION AND ASSIGNMENT section.

   Rmpq_swap($rop1, $rop2);
    Swap the values.

   ####################

   COMBINED INITIALIZATION AND ASSIGNMENT

   NOTE: Do NOT use these functions if $rop has already
   been initialised. Instead use the Rmpq_set* functions
   in 'Assignment Functions' (above)

   First read the section 'MEMORY MANAGEMENT' (above).

   $rop = Math::GMPq->new($arg);
   $rop = Math::GMPq::new($arg);
   $rop = new Math::GMPq($arg);
    Returns a Math::GMPq object with the value of $arg.
    $arg can be either an integer (signed integer, unsigned
    integer) or an NV or a string that represents a numeric value, or
    a Math::GMPz object, or a Math::GMP object, or a Math::GMPq object,
    or a Math::MPFR object.
    If $arg is a string, an optional additional argument that specifies
    the base of the number can be supplied to new(). If base is 0 (or not
    supplied) then the leading characters of the string are used: 0x or
    0X for hex, 0b or 0B for binary, 0 for octal, or decimal otherwise.
    Note that this is done separately for the numerator and denominator,
    so, for instance 0xEF/100 is 239/100, whereas 0xEF/0x100 is 239/256.
    Legal values for the base are 0 and 2..62.

    Beginning with version 0.65, the new() and Rmpq_set_str()
    functions, and the operator-overloading functions all
    handle certain strings that GMP's mpq_set_set_str() deems illegal.
    For these additional strings, if base is '0' (or not provided) then
    octal strings are signified with either the '0o' or '0O' prefix.
    The plain '0' prefix is interpreted here as simply a leading 0.
    A prefix should NOT be included if a base other than 0 is provided
    as an argument.
    Eg. we handle the following, though GMP's mpq_set_str() does not:
     new('0.1', $base);  # 1/$base (or 1/10 if $base is 0). This is always
                         # different from the value assigned by new(0.1).
     new('0.9e-2');      # 9/1000
     new('9@-3');        # 9/1000
     new('9@-3', 16);    # 9/4096
     new('0x1.7p-1');    # 23/32
     new('0x1.7p-1', 16) # invalid as non hex characters are included
     new('0o1.34p-1);    # 23/32 but '01.34p-1' is invalid
     new('0b1.0111p-1'); # 23/32
     new('F@10', 16);    # same as '0xFp+64' (276701161105643274240);
                         # the exponent is read as 0x10 (== 16), as
                         # base is positive.
     new('F@16', -16);   # same as '0xFp+64' (276701161105643274240);
                         # the exponent is read as the decimal 16, as
                         # base is negative.
     new('12@4', 61);    # 872287983
     new('+1.2@4, 61);   # 14299803 (== 872287983 divided by 61)
     new('-12@-5', 61)   # -63/844596301
     new('1.2@-5', 61)   #  63/51520374361 ( == previous / 61)
     And the same applies to Rmpq_set_str.
     Note: When using the "mantissa@exponent" notation, the "mantissa"
     portion is allowed to contain a radix point (but not an exponent),
     and the "exponent" portion must be an integer value.  Specifying a
     negative value for the base indicates that the "exponent" portion
     is to be read as a decimal value.

    And similarly for overloaded operations, except that they make no
    provision for specifying the base of the given string. Allowable
    bases are therefore limited to 16 (via 0x or 0X prefix), 8 (via 0o
    or 0O prefix), 2 (via 0b or 0B prefix) and 10 (no prefix).
    If a positive or negative value is specified, then the '+' or '-'
    symbol must be placed at the very beginning of the value. For
    example : '+0b11011/-0xabc'.

   ####################

   RATIONAL CONVERSIONS

   $NV = Rmpq_get_d($op);
    Convert $op to a its double-precision value.

   $NV = Rmpq_get_NV($op);
    Convert $op to an NV using the full precision available to the NV.
    If nvtype is 'double', then this is the same as Rmpq_get_d($op).

   $str = Rmpq_get_str($op, $base);
    Convert $op to a string of digits in base $base. The base may
    vary from 2 to 36.  The string will be of the form `num/den',
    or if the denominator is 1 then just `num'.

   ###################

   RATIONAL ARITHMETIC

   Rmpq_add  ($rop, $op1, $op2);
   Rmpq_add_z($rop, $op1, $z); # $z is a Math::GMPz object
    1st arg = 2nd arg + 3rd arg.
    (The gmp library doesn't provide an mpq_add_z function.)

   Rmpq_sub  ($rop, $op1, $op2);
   Rmpq_sub_z($rop, $op1, $z); # $z is a Math::GMPz object
   Rmpq_z_sub($rop, $z, $op1); # $z is a Math::GMPz object
    1st arg = 2nd arg - 3rd arg.
    (The gmp library doesn't provide an mpq_sub_z function or
     an mpq_z_sub function.)

   Rmpq_mul  ($rop, $op1, $op2);
   Rmpq_mul_z($rop, $op1, $z); # $z is a Math::GMPz object
    1st arg = 2nd arg * 3rd arg.
    (The gmp library doesn't provide an mpq_mul_z function.)

   Rmpq_mul_2exp($rop, $op, $ui);
    $rop = $op * (2 ** $ui).

   Rmpq_div  ($rop, $op1, $op2);
   Rmpq_div_z($rop, $op1, $z); # $z is a Math::GMPz object
   Rmpq_z_div($rop, $z, $op1); # $z is a Math::GMPz object
    1st arg  = 2nd arg / 3rd arg.
    (The gmp library doesn't provide an mpq_div_z function or
     an mpq_z_div function.)

   Rmpq_div_2exp($rop, $op, $ui);
    $rop = $op / (2 ** $ui).

   Rmpq_neg($rop, $op);
    $rop = -$op.

   Rmpq_abs($rop, $op);
    $rop = abs($op).

   Rmpq_inv($rop, $op);
    $rop = 1 / $op.

   ##########################

   APPLYING INTEGER FUNCTIONS

   Rmpq_numref($z, $op); # $z is a Math::GMPz object
   Rmpq_denref($z, $op); # $z is a Math::GMPz object
    Set $rop to the numerator and denominator of $op, respectively.

   Rmpq_get_num($z, $op); # $z is a Math::GMPz oblect
   Rmpq_get_den($z, $op); # $z is a Math::GMPz oblect
   Rmpq_set_num($rop, $z); # $z is a Math::GMPz oblect
   Rmpq_set_den($rop, $z); # $z is a Math::GMPz oblect
    Get or set the numerator or denominator of a rational
    Direct use of `Rmpq_numref' or `Rmpq_denref' is
    recommended instead of these functions.

   ###################

   COMPARING RATIONALS

   $si = Rmpq_cmp  ($op1, $op2);
   $si = Rmpq_cmp_z($op1, $z); # $z is a Math::GMPz object
    Compare $op1 and $op2.  Return a positive value if 1st arg
    is greater than 2nd arg, zero if 1st arg == 2nd arg, and a
    negative value if 1st arg < 2nd arg.
    To determine if two rationals are equal, `Rmpq_equal' is
    faster than `Rmpq_cmp'.
    (The gmp library provides mpq_cmp_z only for gmp-6.1.0 and
     later but Rmpq_cmp_z is available for all builds of Math::GMPz,
     irrespective of the underlying version of gmp.)

   $si = Rmpq_cmp_ui($op, $ui1 , $ui2);
   $si = Rmpq_cmp_si($op, $si2 , $ui );
   $si = Rmpq_cmp_IV($op, $iv1 , $iv2); # $iv1, $iv2, are IVs.
    Compare $op1 and 2nd arg/3rd arg.  Return a positive value if
    $op1 > 2nd arg/3rd arg, zero if $op1 = 2nd arg/3rd arg,
    and a negative value if $op1 < 2nd arg/3rd arg.
    2nd and 3rd args are allowed to have common factors.
    Note that the 3rd (NOT 2nd) arg is unsigned. If you want
    to compare $op with 2/-3, make sure that 2nd arg is
    '-2' and 3rd arg is '3'.

    NOTE:
         Rmpq_cmp_IV() requires that the 2nd and 3rd arguments both
         have their IOK flag set - otherwise it croaks.
         Suggestion: first check the status of the flag of both of
         those arguments using IOK_flag($iv),which returns a non-zero
         value if and only if the flag in question is set.

   $si = Rmpq_cmp_NV($op, $nv);
    Return 0  if $op == $nv.
    Return 1  if $op >  $nv.
    Return -1 if $op <  $nv
    It's a fatal error if $nv is a NaN.

    NOTE:
         Rmpq_cmp_NV() requires that the 2nd argument
         has its NOK flag set - otherwise it croaks.
         Suggestion: first check the status of the flag of the
         second argument using NOK_flag($nv),which returns a
         non-zero value if and only if the flag in question is set.

   $si = Rmpq_sgn($op);
    Return 1 if $op>0, 0 if $op=0, and -1 if $op < 0.

   $bool = Rmpq_equal($op1, $op2); # faster than Rmpq_cmp()
    Return non-zero if $op1 and $op2 are equal, zero if they
    are non-equal.  Although `Rmpq_cmp' can be used for the
    same purpose, this function is much faster.

   $si = Rmpq_cmp_z($op, $z);# $z is Math::GMPz or Math::GMP object
    Return a positive value if $op > $z.
    Return zero if $op == $z.
    Return a negative value if $op < $z.

   ################

   I/O of RATIONALS

   $bytes_written = Rmpq_out_str([$prefix,] $op, $base [, $suffix]);
    BEST TO USE TRmpq_out_str INSTEAD.
    Output $op to STDOUT, as a string of digits in base $base.
    The base may vary from 2 to 36. Output is in the form `num/den'
    or if the denominator is 1 then just `num'. Return the number
    of bytes written, or if an error occurred, return 0.
    The optional first and last arguments ($prefix and $suffix) are
    strings that will be prepended/appended to the mpq_out_str
    output.  $bytes_written does not include the bytes contained in
    $prefix and $suffix.

   $bytes_written = TRmpq_out_str([$prefix,] $stream, $base, $op, [, $suffix]);
    As for Rmpq_out_str, except that there's the capability to print
    to somewhere other than STDOUT. Note that the order of the args
    is different (to match the order of the mpq_out_str args).
    To print to STDERR:
       TRmpq_out_str(*stderr, $base, $digits, $op);
    To print to an open filehandle (let's call it $fh):
       TRmpq_out_str(\*$fh, $base, $digits, $op);

   $bytes_read = Rmpq_inp_str($rop, $base);
    BEST TO USE TRmpq_inp_str INSTEAD.
    Read a string of digits from STDIN and convert them to a rational
    in $rop.  Any initial white-space characters are read and
    discarded.  Return the number of characters read (including white
    space), or 0 if a rational could not be read.
    The input can be a fraction like `17/63' or just an integer like
    `123'.  Reading stops at the first character not in this form, and
    white space is not permitted within the string.  If the input
    might not be in canonical form, then `mpq_canonicalize' must be
    called. $base can be between 2 and 36, or can be 0 in which case the
    leading characters of the string determine the base, `0x' or `0X'
    for hexadecimal, `0' for octal, or decimal otherwise.  The leading
    characters are examined separately for the numerator and
    denominator of a fraction, so for instance `0x10/11' is 16/11,
    whereas `0x10/0x11' is 16/17.

   $bytes_read = TRmpq_inp_str($rop, $stream, $base);
    As for Rmpq_inp_str, except that there's the capability to read
    from somewhere other than STDIN.
    To read from STDIN:
       TRmpq_inp_str($rop, *stdin, $base);
    To read from an open filehandle (let's call it $fh):
       TRmpq_inp_str($rop, \*$fh, $base);

   #######################

   RANDOM NUMBER FUNCTIONS

   $state = qgmp_randinit_default();
    This is the Math::GMPq interface to the gmp library function
   'gmp_randinit_default'.
    $state is blessed into package Math::GMPq::Random and will be
    automatically cleaned up when it goes out of scope.
    Initialize $state with a default algorithm. This will be a
    compromise between speed and randomness, and is recommended for
    applications with no special requirements. Currently this is
    the gmp_randinit_mt function (Mersenne Twister algorithm).

   $state = qgmp_randinit_mt();
    This is the Math::GMPq interface to the gmp library function
   'gmp_randinit_mt'.
    Currently identical to fgmp_randinit_default().

   $state = qgmp_randinit_lc_2exp($mpz, $ui, $m2exp);
    This is the Math::GMPq interface to the gmp library function
    'gmp_randinit_lc_2exp'. $mpz is a Math::GMP or Math::GMPz object,
    so one of those modules is required in order to make use of this
    function.
    $state is blessed into package Math::GMPq::Random and will be
    automatically cleaned up when it goes out of scope.
    Initialize $state with a linear congruential algorithm
    X = ($mpz*X + $ui) mod (2 ** $m2exp). The low bits of X in this
    algorithm are not very random. The least significant bit will have a
    period no more than 2, and the second bit no more than 4, etc. For
    this reason only the high half of each X is actually used.
    When a random number of more than m2exp/2 bits is to be generated,
    multiple iterations of the recurrence are used and the results
    concatenated.

   $state = qgmp_randinit_lc_2exp_size($ui);
    This is the Math::GMPq interface to the gmp library function
   'gmp_randinit_lc_2exp_size'.
    $state is blessed into package Math::GMPf::Random and will be
    automatically cleaned up when it goes out of scope.
    Initialize state for a linear congruential algorithm as per
    gmp_randinit_lc_2exp. a, c and m2exp are selected from a table,
    chosen so that $ui bits (or more) of each X will be used,
    ie. m2exp/2 >= $ui.
    If $ui is bigger than the table data provides then the function fails
    and dies with an appropriate error message. The maximum value for $ui
    currently supported is 128.

   $state2 = qgmp_randinit_set($state1);
    This is the Math::GMPq interface to the gmp library function
   'gmp_randinit_set'.
    $state2 is blessed into package Math::GMPf::Random and will be
    automatically cleaned up when it goes out of scope.
    Initialize $state2 with a copy of the algorithm and state from
    $state1.

   $state = qgmp_randinit_default_nobless();
   $state = qgmp_randinit_mt_nobless();
   $state = qgmp_randinit_lc_2exp_nobless($mpz, $ui, $m2exp);
   $state2 = qgmp_randinit_set_nobless($state1);
    As for the above comparable function, but $state is not blessed into
    any package. (Generally not useful - but they're available if you
    want them.)

   qgmp_randseed($state, $mpz); # $mpz is a Math::GMPz or Math::GMP object
   qgmp_randseed_ui($state, $ui);
    These are the Math::GMPz interfaces to the gmp library functions
    'gmp_randseed' and 'gmp_randseed_ui'.
    Seed an initialised (but not yet seeded) $state with $mpz/$ui.
    Either Math::GMP or Math::GMPz is required for 'gmp_randseed'.

   $ui = qgmp_urandomb_ui($state, $bits);
    This is the Math::GMPq interface to the gmp library function
    'gmp_urandomb_ui'.
    Return a uniformly distributed random number of $bits bits, ie. in
    the range 0 to 2 ** ($bits - 1) inclusive. $bits must be less than or
    equal to the number of bits in an unsigned long.

   $ui2 = qgmp_urandomm_ui($state, $ui1);
    This is the Math::GMPq interface to the gmp library function
    'gmp_urandomm_ui'.
    Return a uniformly distributed random number in the range 0 to
    $ui1 - 1, inclusive.

   qgmp_randclear($state);
    Destroys $state, as also does Math::GMPq::Random::DESTROY - two
    identical functions.
    Use only if $state is an unblessed object - ie if it was initialised
    using one of the qgmp_randinit*_nobless functions.

   ####################

   OPERATOR OVERLOADING

   Overloading occurs with IVs, strings (bases 2, 8,10 & 16 only), NVs,
   Math::GMPq(v0.68) objects, Math::GMPz(v0.69) objects, Math::GMP(v2.11)
   objects and Math::MPFR (v4.19) objects.
   Strings are first converted to Math::GMPq objects, then canonicalized.
   The following operators are overloaded:

    + - * / ** %        # '%'  is fmod.
    += -= *= /= %= **=  # '%=' is fmod.
    ++ --
    == != !
    < <= > >= <=>
    "" abs 0+ int
    &, |, ^, ~, >> <<
    =

    Let $LHS' and '$RHS' denote a variable that is any one of those data
    types just specified; let '$MPQ' denote a Math::GMPq object; let 'OP'
    denote any one of the '+', '-', '*', '/' and '%' arithmetic operators.
    Then, so long as one (or both) of $LHS and $RHS is a Math::GMPq
    object we can do the following:

      $RET = $LHS OP $RHS;

      If $LHS is a Math::MPFR object, then so too is $RET. otherwise
      $RET is a Math::GMPq object.
      NOTE: If $LHS is a Math::GMP object then our code needs to also:
            use Math::GMP_OLOAD;

    Let 'OP=' denote any one of the '+=', '-=', '*=', '/=' and '%='
    operators. Then we can do:

      $MPQ OP= $RHS;

      Again, if $RHS is a Math::MPFR object, then a Math::MPFR object
      is returned - with $MPQ changing to a Math::MPFR object.

    And similarly for the '**' and '**=' operators - except that,
    unless $LHS is a Math::MPFR object, $RHS must be neither a
    Math::GMPq object nor an NV, and must hold a non-negative integer
    value that fits into an unsigned int.

    Let 'CMP' denote  any one of the overloaded '==', '!=', '<', '<=',
    '>', '>=', '<=>' comparison operators. We can test the condition:

      ($LHS CMP $RHS)

      with the only caveat being that, if $LHS is a Math::GMP object,
      we need to:
         use Math::GMP_OLOAD;

    NOTE: Making use of the '=' overloading is not recommended unless
          you understand its caveats. See 'perldoc overload' and
          read it thoroughly, including the documentation regarding
          'copy constructors'.

    Atempting to use the overloaded operators with objects that
    have been blessed into some package other than 'Math::GMPq',
    Math::MPFR', 'Math::GMPz', or 'Math::GMP' will throw an error.

    When the 'OP' operations return a Math::MPFR object, the precision
    of that Math::MPFR object will be the same as the Math::MPFR object
    that was provided as an argument.
    For the 'OP=' operations, the returned Math::MPFR object will have
    current Math::MPFR default precision.
    When the '%', '%=', '**' and '**=' operations will return a Math::MPFR
    object, the  value of the Math::GMPq argument is first set to a
    Math::MPFR object using the current Math::MPFR default precision and
    default rounding mode.

    Comparisons between Math::GMPq and Math::GMPz objects can be performed
    using either the Math::GMPz/Math::GMP or Math::GMPq overloading.
    For example, ($mpq > $mpz) is equivalent to ($mpz < $mpq).

    Let 'BITWISE' denote any one of the overloaded '&', '|' and '^'
    operations, introduced for compatibility with Math::BigRat. We can do:

      $RET = $GMP BITWISE $RHS; # $RHS excludes Math::MPFR here.

      which will firstly convert $RHS to a Math::GMPq object (if it's not
      already a Math::GMPq object). $RET is a Math::GMPq object.
      The converse operation of:

      $RET = $LHS BITWISE $GMP;

      will likely (not tested) fail.

    Let 'SHIFT' denote either of '<<' or '>>', also introduced for
    compatibility with Math::BigRat:

      $RET = $MPQ SHIFT $perlnumber; # $RET is a Math::GMPq object.

    The first argument recieved by the Math::GMPq overloading subroutines
    is always the Math::GMPq object. To determine the type of the second
    argument, these subroutines work through the following steps, using
    the first value it finds, or croaking if it gets to step 6:

    1. If the variable is a UV then that value is used. The variable
       is considered to be a UV if the IOK and IsUV flags are set.

    2. If the variable is an IV (IOK but not IsUIV), then the IV value
       is used.

    3. If the variable is a string (ie the POK flag is set) then the
       value of that string is used. Octal strings should begin with
       '0o' or '0O' (though '0' will work in some cases), hex strings
       must begin with either '0x' or '0X', base 2 strings must begin
       with '0b' or '0B', - otherwise the string is assumed to be
       decimal. If the POK flag is set, but the string is not a valid
       base 2, 8, 10, or 16 number, the subroutine croaks with a
       message that the string passed to Rmpfr_set_str() is not a
       valid number. If the string is of the form 'numerator/denominator',
       then the bases of the numerator and the denominator are
       assessed individually. ie '0xa123/ff' is not a valid number
       (because 'ff' is not a valid base 10 number). That needs to
       be rewritten as '0xa123/0xff'.

    4. If the variable is an NV, then that value is used. The
       variable is considered to be a NV if the NOK flag is set.
       NOTE: Providing an NV to the overloaded '**' and '**='
             subroutines currently generates an error.

    5. If the variable is a Math::GMPq object (or, for operators
       specified above, a Math::MPFR/Math::GMP/Math::GMPz object)
       then the value of that object is used.

    6. If none of the above is true, then the second variable is
       deemed to be of an invalid type. The subroutine croaks with
       an appropriate error message.

   ##############

   MISCELLANEOUS

   $bool = Rmpq_integer_p($op);
    Returns true if $op is an integer (ie denominator of $op is 1).
    Else returns false.
    The mpq_integer_p function is not implemented in gmp.

   $bool = Rmpq_fits_uint_p($op);
    Returns true if $op >= 0 && $op holds an integer value that
    fits into an unsigned int. Else returns false.
    The mpq_fits_uint_p function is not implemented in gmp.

   Rmpq_pow_ui($rop, $op, $ui);
    Sets $rop top the value of $op ** $ui.
    The mpq_pow_ui function is not implemented in gmp.

   $si = IOK_flag($sv); # $sv is a perl scalar variable.
   $si = NOK_flag($sv);
   $si = POK_flag($sv);

   Return 0 if $sv's IOK/NOK/POK flag is unset.
   Else return 1.
   If the IsUV flag is set, then IOK_flag() returns 2, thereby indicating
   that both the IOK and IsUV flags are set (and that the integer value
   held by $sv should therefore be treated as unsigned).

   #####

   OTHER

   $GMP_version = Math::GMPq::gmp_v;
    Returns the version of the GMP library (eg 4.1.3) being used by
    Math::GMPq. The function is not exportable.

   $GMP_cc = Math::GMPq::__GMP_CC;
   $GMP_cflags = Math::GMPq::__GMP_CFLAGS;
    If Math::GMPq has been built against gmp-4.2.3 or later,
    returns respectively the CC and CFLAGS settings that were used
    to compile the gmp library against which Math::GMPq was built.
    (Values are as specified in the gmp.h that was used to build
    Math::GMPq.)
    Returns undef if Math::GMPq has been built against an earlier
    version of the gmp library.
    (These functions are in @EXPORT_OK and are therefore exportable
    by request. They are not listed under the ":mpq" tag.)

   $major = Math::GMPq::__GNU_MP_VERSION;
   $minor = Math::GMPq::__GNU_MP_VERSION_MINOR;
   $patchlevel = Math::GMPq::__GNU_MP_VERSION_PATCHLEVEL;
    Returns respectively the major, minor, and patchlevel numbers
    for the GMP library version used to build Math::GMPq. Values are
    as specified in the gmp.h that was used to build Math::GMPq.
    (These functions are in @EXPORT_OK and are therefore exportable
    by request. They are not listed under the ":mpq" tag.)

   ################

   FORMATTED OUTPUT

   NOTE: The format specification can be found at:
   http://gmplib.org/manual/Formatted-Output-Strings.html#Formatted-Output-Strings
   However, the use of '*' to take an extra variable for width and
   precision is not allowed in this implementation. Instead, it is
   necessary to interpolate the variable into the format string - ie,
   instead of:
     Rmpq_printf("%*Zd\n", $width, $mpz);
   we need:
     Rmpq_printf("%${width}Zd\n", $mpz);

   $si = Rmpq_printf($format_string, $var);

    This function changed with the release of Math-GMPq-0.27.
    Now (unlike the GMP counterpart), it is limited to taking 2
    arguments - the format string, and the variable to be formatted.
    That is, you can format only one variable at a time.
    If there is no variable to be formatted, then the final arg
    can be omitted - a suitable dummy arg will be passed to the XS
    code for you. ie the following will work:
     Rmpq_printf("hello world\n");
    Returns the number of characters written, or -1 if an error
    occurred.

   $si = Rmpq_fprintf($fh, $format_string, $var);

    This function (unlike the GMP counterpart) is limited to taking
    3 arguments - the filehandle, the format string, the variable
    to be formatted. That is, you can format only one variable at a time.
    If there is no variable to be formatted, then the final arg
    can be omitted - a suitable dummy arg will be passed to the XS
    code for you. ie the following will work:
     Rmpq_fprintf($fh, "hello world\n");
    Other than that, the rules outlined above wrt Rmpq_printf apply.
    Returns the number of characters written, or -1 if an error
    occurred.

   $si = Rmpq_sprintf($buffer, $format_string, $var, $buflen);

    This function (unlike the GMP counterpart) is limited to taking
    4 arguments - the buffer, the format string,  the variable to be
    formatted and the size of the buffer. If there is no variable to
    be formatted, then the third arg can be omitted - a suitable
    dummy arg will be passed to the XS code for you. ie the following
    will work:
     Rmpf_sprintf($buffer, "hello world", 12);
    $buffer must be large enough to accommodate the formatted string.
    The formatted string is placed in $buffer.
    Returns the number of characters written, or -1 if an error
    occurred.

   $si = Rmpq_snprintf($buffer, $bytes, $format_string, $var, $buflen);

    Form a null-terminated string in $buffer. No more than $bytes
    bytes will be written. To get the full output, $bytes must be
    enough for the string and null-terminator. $buffer must be large
    enough to accommodate the string and null-terminator, and is
    truncated to the length of that string (and null-terminator).
    The return value is the total number of characters which ought
    to have been produced, excluding the terminating null.
    If $si >= $bytes then the actual output has been truncated to
    the first $bytes-1 characters, and a null appended.
    This function (unlike the GMP counterpart) is limited to taking
    5 arguments - the buffer, the maximum number of bytes to be
    returned, the format string, the variable to be formatted and
    the size of the buffer.
    If there is no variable to be formatted, then the 4th arg can
    be omitted - a suitable dummy arg will be passed to the XS code
    for you. ie the following will work:
     Rmpf_snprintf($buffer, 6, "hello world", 12);

   ################
   ################

=head1 BUGS

    You can get segfaults if you pass the wrong type of
    argument to the functions - so if you get a segfault, the
    first thing to do is to check that the argument types
    you have supplied are appropriate.

=head1 LICENSE

    This program is free software; you may redistribute it and/or
    modify it under the same terms as Perl itself.
    Copyright 2006-2011, 2013-26, Sisyphus

=head1 AUTHOR

    Sisyphus <sisyphus at(@) cpan dot (.) org>


=cut
