Home | History | Annotate | Line # | Download | only in perl
      1      1.1  mrg /* GMP module external subroutines.
      2      1.1  mrg 
      3  1.1.1.2  mrg Copyright 2001-2003, 2015 Free Software Foundation, Inc.
      4      1.1  mrg 
      5      1.1  mrg This file is part of the GNU MP Library.
      6      1.1  mrg 
      7      1.1  mrg The GNU MP Library is free software; you can redistribute it and/or modify
      8  1.1.1.2  mrg it under the terms of either:
      9  1.1.1.2  mrg 
     10  1.1.1.2  mrg   * the GNU Lesser General Public License as published by the Free
     11  1.1.1.2  mrg     Software Foundation; either version 3 of the License, or (at your
     12  1.1.1.2  mrg     option) any later version.
     13  1.1.1.2  mrg 
     14  1.1.1.2  mrg or
     15  1.1.1.2  mrg 
     16  1.1.1.2  mrg   * the GNU General Public License as published by the Free Software
     17  1.1.1.2  mrg     Foundation; either version 2 of the License, or (at your option) any
     18  1.1.1.2  mrg     later version.
     19  1.1.1.2  mrg 
     20  1.1.1.2  mrg or both in parallel, as here.
     21      1.1  mrg 
     22      1.1  mrg The GNU MP Library is distributed in the hope that it will be useful, but
     23      1.1  mrg WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     24  1.1.1.2  mrg or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     25  1.1.1.2  mrg for more details.
     26      1.1  mrg 
     27  1.1.1.2  mrg You should have received copies of the GNU General Public License and the
     28  1.1.1.2  mrg GNU Lesser General Public License along with the GNU MP Library.  If not,
     29  1.1.1.2  mrg see https://www.gnu.org/licenses/.
     30      1.1  mrg 
     31      1.1  mrg 
     32      1.1  mrg /* Notes:
     33      1.1  mrg 
     34      1.1  mrg    Routines are grouped with the alias feature and a table of function
     35      1.1  mrg    pointers where possible, since each xsub routine ends up with quite a bit
     36      1.1  mrg    of code size.  Different combinations of arguments and return values have
     37      1.1  mrg    to be separate though.
     38      1.1  mrg 
     39      1.1  mrg    The "INTERFACE:" feature isn't available in perl 5.005 and so isn't used.
     40      1.1  mrg    "ALIAS:" requires a table lookup with CvXSUBANY(cv).any_i32 (which is
     41      1.1  mrg    "ix") whereas "INTERFACE:" would have CvXSUBANY(cv).any_dptr as the
     42      1.1  mrg    function pointer immediately.
     43      1.1  mrg 
     44      1.1  mrg    Mixed-type swapped-order assignments like "$a = 123; $a += mpz(456);"
     45      1.1  mrg    invoke the plain overloaded "+", not "+=", which makes life easier.
     46      1.1  mrg 
     47      1.1  mrg    mpz_assume etc types are used with the overloaded operators since such
     48      1.1  mrg    operators are always called with a class object as the first argument, we
     49      1.1  mrg    don't need an sv_derived_from() lookup to check.  There's assert()s in
     50      1.1  mrg    MPX_ASSUME() for this though.
     51      1.1  mrg 
     52      1.1  mrg    The overload_constant routines reached via overload::constant get 4
     53      1.1  mrg    arguments in perl 5.6, not the 3 as documented.  This is apparently a
     54      1.1  mrg    bug, using "..." lets us ignore the extra one.
     55      1.1  mrg 
     56      1.1  mrg    There's only a few "si" functions in gmp, so usually SvIV values get
     57      1.1  mrg    handled with an mpz_set_si into a temporary and then a full precision mpz
     58      1.1  mrg    routine.  This is reasonably efficient.
     59      1.1  mrg 
     60      1.1  mrg    Argument types are checked, with a view to preserving all bits in the
     61      1.1  mrg    operand.  Perl is a bit looser in its arithmetic, allowing rounding or
     62      1.1  mrg    truncation to an intended operand type (IV, UV or NV).
     63      1.1  mrg 
     64      1.1  mrg    Bugs:
     65      1.1  mrg 
     66      1.1  mrg    The memory leak detection attempted in GMP::END() doesn't work when mpz's
     67      1.1  mrg    are created as constants because END() is called before they're
     68      1.1  mrg    destroyed.  What's the right place to hook such a check?
     69      1.1  mrg 
     70      1.1  mrg    See the bugs section of GMP.pm too.  */
     71      1.1  mrg 
     72      1.1  mrg 
     73      1.1  mrg /* Comment this out to get assertion checking. */
     74      1.1  mrg #define NDEBUG
     75      1.1  mrg 
     76      1.1  mrg /* Change this to "#define TRACE(x) x" for some diagnostics. */
     77      1.1  mrg #define TRACE(x)
     78      1.1  mrg 
     79      1.1  mrg 
     80      1.1  mrg #include <assert.h>
     81      1.1  mrg #include <float.h>
     82      1.1  mrg 
     83      1.1  mrg #include "EXTERN.h"
     84      1.1  mrg #include "perl.h"
     85      1.1  mrg #include "XSUB.h"
     86      1.1  mrg #include "patchlevel.h"
     87      1.1  mrg 
     88      1.1  mrg #include "gmp.h"
     89      1.1  mrg 
     90      1.1  mrg 
     91      1.1  mrg /* Perl 5.005 doesn't have SvIsUV, only 5.6 and up.
     92      1.1  mrg    Perl 5.8 has SvUOK, but not 5.6, so we don't use that.  */
     93      1.1  mrg #ifndef SvIsUV
     94      1.1  mrg #define SvIsUV(sv)  0
     95      1.1  mrg #endif
     96      1.1  mrg #ifndef SvUVX
     97      1.1  mrg #define SvUVX(sv)  (croak("GMP: oops, shouldn't be using SvUVX"), 0)
     98      1.1  mrg #endif
     99      1.1  mrg 
    100      1.1  mrg 
    101      1.1  mrg /* Code which doesn't check anything itself, but exists to support other
    102      1.1  mrg    assert()s.  */
    103      1.1  mrg #ifdef NDEBUG
    104      1.1  mrg #define assert_support(x)
    105      1.1  mrg #else
    106      1.1  mrg #define assert_support(x) x
    107      1.1  mrg #endif
    108      1.1  mrg 
    109      1.1  mrg /* LONG_MAX + 1 and ULONG_MAX + 1, as a doubles */
    110      1.1  mrg #define LONG_MAX_P1_AS_DOUBLE   ((double) ((unsigned long) LONG_MAX + 1))
    111      1.1  mrg #define ULONG_MAX_P1_AS_DOUBLE  (2.0 * (double) ((unsigned long) ULONG_MAX/2 + 1))
    112      1.1  mrg 
    113      1.1  mrg /* Check for perl version "major.minor".
    114      1.1  mrg    Perl 5.004 doesn't have PERL_REVISION and PERL_VERSION, but that's ok,
    115      1.1  mrg    we're only interested in tests above that.  */
    116      1.1  mrg #if defined (PERL_REVISION) && defined (PERL_VERSION)
    117      1.1  mrg #define PERL_GE(major,minor)                                    \
    118      1.1  mrg     (PERL_REVISION > (major)                                    \
    119      1.1  mrg      || ((major) == PERL_REVISION && PERL_VERSION >= (minor)))
    120      1.1  mrg #else
    121      1.1  mrg #define PERL_GE(major,minor)  (0)
    122      1.1  mrg #endif
    123      1.1  mrg #define PERL_LT(major,minor)  (! PERL_GE(major,minor))
    124      1.1  mrg 
    125      1.1  mrg /* sv_derived_from etc in 5.005 took "char *" rather than "const char *".
    126      1.1  mrg    Avoid some compiler warnings by using const only where it works.  */
    127      1.1  mrg #if PERL_LT (5,6)
    128      1.1  mrg #define classconst
    129      1.1  mrg #else
    130      1.1  mrg #define classconst const
    131      1.1  mrg #endif
    132      1.1  mrg 
    133      1.1  mrg /* In a MINGW or Cygwin DLL build of gmp, the various gmp functions are
    134      1.1  mrg    given with dllimport directives, which prevents them being used as
    135      1.1  mrg    initializers for constant data.  We give function tables as
    136      1.1  mrg    "static_functable const ...", which is normally "static const", but for
    137      1.1  mrg    mingw expands to just "const" making the table an automatic with a
    138      1.1  mrg    run-time initializer.
    139      1.1  mrg 
    140      1.1  mrg    In gcc 3.3.1, the function tables initialized like this end up getting
    141      1.1  mrg    all the __imp__foo values fetched, even though just one or two will be
    142      1.1  mrg    used.  This is wasteful, but probably not too bad.  */
    143      1.1  mrg 
    144      1.1  mrg #if defined (__MINGW32__) || defined (__CYGWIN__)
    145      1.1  mrg #define static_functable
    146      1.1  mrg #else
    147      1.1  mrg #define static_functable  static
    148      1.1  mrg #endif
    149      1.1  mrg 
    150      1.1  mrg #define GMP_MALLOC_ID  42
    151      1.1  mrg 
    152      1.1  mrg static classconst char mpz_class[]  = "GMP::Mpz";
    153      1.1  mrg static classconst char mpq_class[]  = "GMP::Mpq";
    154      1.1  mrg static classconst char mpf_class[]  = "GMP::Mpf";
    155      1.1  mrg static classconst char rand_class[] = "GMP::Rand";
    156      1.1  mrg 
    157      1.1  mrg static HV *mpz_class_hv;
    158      1.1  mrg static HV *mpq_class_hv;
    159      1.1  mrg static HV *mpf_class_hv;
    160      1.1  mrg 
    161      1.1  mrg assert_support (static long mpz_count = 0;)
    162      1.1  mrg assert_support (static long mpq_count = 0;)
    163      1.1  mrg assert_support (static long mpf_count = 0;)
    164      1.1  mrg assert_support (static long rand_count = 0;)
    165      1.1  mrg 
    166      1.1  mrg #define TRACE_ACTIVE()                                                   \
    167      1.1  mrg   assert_support                                                         \
    168      1.1  mrg   (TRACE (printf ("  active %ld mpz, %ld mpq, %ld mpf, %ld randstate\n", \
    169      1.1  mrg                   mpz_count, mpq_count, mpf_count, rand_count)))
    170      1.1  mrg 
    171      1.1  mrg 
    172      1.1  mrg /* Each "struct mpz_elem" etc is an mpz_t with a link field tacked on the
    173      1.1  mrg    end so they can be held on a linked list.  */
    174      1.1  mrg 
    175      1.1  mrg #define CREATE_MPX(type)                                \
    176      1.1  mrg                                                         \
    177      1.1  mrg   /* must have mpz_t etc first, for sprintf below */    \
    178      1.1  mrg   struct type##_elem {                                  \
    179      1.1  mrg     type##_t            m;                              \
    180      1.1  mrg     struct type##_elem  *next;                          \
    181      1.1  mrg   };                                                    \
    182      1.1  mrg   typedef struct type##_elem  *type;                    \
    183      1.1  mrg   typedef struct type##_elem  *type##_assume;           \
    184      1.1  mrg   typedef type##_ptr          type##_coerce;            \
    185      1.1  mrg                                                         \
    186      1.1  mrg   static type type##_freelist = NULL;                   \
    187      1.1  mrg                                                         \
    188      1.1  mrg   static type                                           \
    189      1.1  mrg   new_##type (void)                                     \
    190      1.1  mrg   {                                                     \
    191      1.1  mrg     type p;                                             \
    192      1.1  mrg     TRACE (printf ("new %s\n", type##_class));          \
    193      1.1  mrg     if (type##_freelist != NULL)                        \
    194      1.1  mrg       {                                                 \
    195      1.1  mrg         p = type##_freelist;                            \
    196      1.1  mrg         type##_freelist = type##_freelist->next;        \
    197      1.1  mrg       }                                                 \
    198      1.1  mrg     else                                                \
    199      1.1  mrg       {                                                 \
    200      1.1  mrg         New (GMP_MALLOC_ID, p, 1, struct type##_elem);  \
    201      1.1  mrg         type##_init (p->m);                             \
    202      1.1  mrg       }                                                 \
    203      1.1  mrg     TRACE (printf ("  p=%p\n", p));                     \
    204      1.1  mrg     assert_support (type##_count++);                    \
    205      1.1  mrg     TRACE_ACTIVE ();                                    \
    206      1.1  mrg     return p;                                           \
    207      1.1  mrg   }                                                     \
    208      1.1  mrg 
    209      1.1  mrg CREATE_MPX (mpz)
    210      1.1  mrg CREATE_MPX (mpq)
    211      1.1  mrg 
    212      1.1  mrg typedef mpf_ptr  mpf;
    213      1.1  mrg typedef mpf_ptr  mpf_assume;
    214      1.1  mrg typedef mpf_ptr  mpf_coerce_st0;
    215      1.1  mrg typedef mpf_ptr  mpf_coerce_def;
    216      1.1  mrg 
    217      1.1  mrg 
    218      1.1  mrg static mpf
    219      1.1  mrg new_mpf (unsigned long prec)
    220      1.1  mrg {
    221      1.1  mrg   mpf p;
    222      1.1  mrg   New (GMP_MALLOC_ID, p, 1, __mpf_struct);
    223      1.1  mrg   mpf_init2 (p, prec);
    224      1.1  mrg   TRACE (printf ("  mpf p=%p\n", p));
    225      1.1  mrg   assert_support (mpf_count++);
    226      1.1  mrg   TRACE_ACTIVE ();
    227      1.1  mrg   return p;
    228      1.1  mrg }
    229      1.1  mrg 
    230      1.1  mrg 
    231      1.1  mrg /* tmp_mpf_t records an allocated precision with an mpf_t so changes of
    232      1.1  mrg    precision can be done with just an mpf_set_prec_raw.  */
    233      1.1  mrg 
    234      1.1  mrg struct tmp_mpf_struct {
    235      1.1  mrg   mpf_t          m;
    236      1.1  mrg   unsigned long  allocated_prec;
    237      1.1  mrg };
    238      1.1  mrg typedef const struct tmp_mpf_struct  *tmp_mpf_srcptr;
    239      1.1  mrg typedef struct tmp_mpf_struct        *tmp_mpf_ptr;
    240      1.1  mrg typedef struct tmp_mpf_struct        tmp_mpf_t[1];
    241      1.1  mrg 
    242      1.1  mrg #define tmp_mpf_init(f)                         \
    243      1.1  mrg   do {                                          \
    244      1.1  mrg     mpf_init (f->m);                            \
    245      1.1  mrg     f->allocated_prec = mpf_get_prec (f->m);    \
    246      1.1  mrg   } while (0)
    247      1.1  mrg 
    248      1.1  mrg static void
    249      1.1  mrg tmp_mpf_grow (tmp_mpf_ptr f, unsigned long prec)
    250      1.1  mrg {
    251      1.1  mrg   mpf_set_prec_raw (f->m, f->allocated_prec);
    252      1.1  mrg   mpf_set_prec (f->m, prec);
    253      1.1  mrg   f->allocated_prec = mpf_get_prec (f->m);
    254      1.1  mrg }
    255      1.1  mrg 
    256      1.1  mrg #define tmp_mpf_shrink(f)  tmp_mpf_grow (f, 1L)
    257      1.1  mrg 
    258      1.1  mrg #define tmp_mpf_set_prec(f,prec)        \
    259      1.1  mrg   do {                                  \
    260      1.1  mrg     if (prec > f->allocated_prec)       \
    261      1.1  mrg       tmp_mpf_grow (f, prec);           \
    262      1.1  mrg     else                                \
    263      1.1  mrg       mpf_set_prec_raw (f->m, prec);    \
    264      1.1  mrg   } while (0)
    265      1.1  mrg 
    266      1.1  mrg 
    267      1.1  mrg static mpz_t  tmp_mpz_0, tmp_mpz_1, tmp_mpz_2;
    268      1.1  mrg static mpq_t  tmp_mpq_0, tmp_mpq_1;
    269      1.1  mrg static tmp_mpf_t tmp_mpf_0, tmp_mpf_1;
    270      1.1  mrg 
    271      1.1  mrg /* for GMP::Mpz::export */
    272      1.1  mrg #define tmp_mpz_4  tmp_mpz_2
    273      1.1  mrg 
    274      1.1  mrg 
    275      1.1  mrg #define FREE_MPX_FREELIST(p,type)               \
    276      1.1  mrg   do {                                          \
    277      1.1  mrg     TRACE (printf ("free %s\n", type##_class)); \
    278      1.1  mrg     p->next = type##_freelist;                  \
    279      1.1  mrg     type##_freelist = p;                        \
    280      1.1  mrg     assert_support (type##_count--);            \
    281      1.1  mrg     TRACE_ACTIVE ();                            \
    282      1.1  mrg     assert (type##_count >= 0);                 \
    283      1.1  mrg   } while (0)
    284      1.1  mrg 
    285      1.1  mrg /* this version for comparison, if desired */
    286      1.1  mrg #define FREE_MPX_NOFREELIST(p,type)             \
    287      1.1  mrg   do {                                          \
    288      1.1  mrg     TRACE (printf ("free %s\n", type##_class)); \
    289      1.1  mrg     type##_clear (p->m);                        \
    290      1.1  mrg     Safefree (p);                               \
    291      1.1  mrg     assert_support (type##_count--);            \
    292      1.1  mrg     TRACE_ACTIVE ();                            \
    293      1.1  mrg     assert (type##_count >= 0);                 \
    294      1.1  mrg   } while (0)
    295      1.1  mrg 
    296      1.1  mrg #define free_mpz(z)    FREE_MPX_FREELIST (z, mpz)
    297      1.1  mrg #define free_mpq(q)    FREE_MPX_FREELIST (q, mpq)
    298      1.1  mrg 
    299      1.1  mrg 
    300      1.1  mrg /* Return a new mortal SV holding the given mpx_ptr pointer.
    301      1.1  mrg    class_hv should be one of mpz_class_hv etc.  */
    302      1.1  mrg #define MPX_NEWMORTAL(mpx_ptr, class_hv)                                \
    303      1.1  mrg     sv_bless (sv_setref_pv (sv_newmortal(), NULL, mpx_ptr), class_hv)
    304      1.1  mrg 
    305      1.1  mrg /* Aliases for use in typemaps */
    306      1.1  mrg typedef char           *malloced_string;
    307      1.1  mrg typedef const char     *const_string;
    308      1.1  mrg typedef const char     *const_string_assume;
    309      1.1  mrg typedef char           *string;
    310      1.1  mrg typedef SV             *order_noswap;
    311      1.1  mrg typedef SV             *dummy;
    312      1.1  mrg typedef SV             *SV_copy_0;
    313      1.1  mrg typedef unsigned long  ulong_coerce;
    314      1.1  mrg typedef __gmp_randstate_struct *randstate;
    315      1.1  mrg typedef UV             gmp_UV;
    316      1.1  mrg 
    317      1.1  mrg #define SvMPX(s,type)  ((type) SvIV((SV*) SvRV(s)))
    318      1.1  mrg #define SvMPZ(s)       SvMPX(s,mpz)
    319      1.1  mrg #define SvMPQ(s)       SvMPX(s,mpq)
    320      1.1  mrg #define SvMPF(s)       SvMPX(s,mpf)
    321      1.1  mrg #define SvRANDSTATE(s) SvMPX(s,randstate)
    322      1.1  mrg 
    323      1.1  mrg #define MPX_ASSUME(x,sv,type)                           \
    324      1.1  mrg   do {                                                  \
    325      1.1  mrg     assert (sv_derived_from (sv, type##_class));        \
    326      1.1  mrg     x = SvMPX(sv,type);                                 \
    327      1.1  mrg   } while (0)
    328      1.1  mrg 
    329      1.1  mrg #define MPZ_ASSUME(z,sv)    MPX_ASSUME(z,sv,mpz)
    330      1.1  mrg #define MPQ_ASSUME(q,sv)    MPX_ASSUME(q,sv,mpq)
    331      1.1  mrg #define MPF_ASSUME(f,sv)    MPX_ASSUME(f,sv,mpf)
    332      1.1  mrg 
    333      1.1  mrg #define numberof(x)  (sizeof (x) / sizeof ((x)[0]))
    334      1.1  mrg #define SGN(x)       ((x)<0 ? -1 : (x) != 0)
    335      1.1  mrg #define ABS(x)       ((x)>=0 ? (x) : -(x))
    336      1.1  mrg #define double_integer_p(d)  (floor (d) == (d))
    337      1.1  mrg 
    338      1.1  mrg #define x_mpq_integer_p(q) \
    339      1.1  mrg   (mpz_cmp_ui (mpq_denref(q), 1L) == 0)
    340      1.1  mrg 
    341      1.1  mrg #define assert_table(ix)  assert (ix >= 0 && ix < numberof (table))
    342      1.1  mrg 
    343      1.1  mrg #define SV_PTR_SWAP(x,y) \
    344      1.1  mrg   do { SV *__tmp = (x); (x) = (y); (y) = __tmp; } while (0)
    345      1.1  mrg #define MPF_PTR_SWAP(x,y) \
    346      1.1  mrg   do { mpf_ptr __tmp = (x); (x) = (y); (y) = __tmp; } while (0)
    347      1.1  mrg 
    348      1.1  mrg 
    349      1.1  mrg static void
    350      1.1  mrg class_or_croak (SV *sv, classconst char *cl)
    351      1.1  mrg {
    352      1.1  mrg   if (! sv_derived_from (sv, cl))
    353      1.1  mrg     croak("not type %s", cl);
    354      1.1  mrg }
    355      1.1  mrg 
    356      1.1  mrg 
    357      1.1  mrg /* These are macros, wrap them in functions. */
    358      1.1  mrg static int
    359      1.1  mrg x_mpz_odd_p (mpz_srcptr z)
    360      1.1  mrg {
    361      1.1  mrg   return mpz_odd_p (z);
    362      1.1  mrg }
    363      1.1  mrg static int
    364      1.1  mrg x_mpz_even_p (mpz_srcptr z)
    365      1.1  mrg {
    366      1.1  mrg   return mpz_even_p (z);
    367      1.1  mrg }
    368      1.1  mrg 
    369      1.1  mrg static void
    370      1.1  mrg x_mpq_pow_ui (mpq_ptr r, mpq_srcptr b, unsigned long e)
    371      1.1  mrg {
    372      1.1  mrg   mpz_pow_ui (mpq_numref(r), mpq_numref(b), e);
    373      1.1  mrg   mpz_pow_ui (mpq_denref(r), mpq_denref(b), e);
    374      1.1  mrg }
    375      1.1  mrg 
    376      1.1  mrg 
    377      1.1  mrg static void *
    378      1.1  mrg my_gmp_alloc (size_t n)
    379      1.1  mrg {
    380      1.1  mrg   void *p;
    381      1.1  mrg   TRACE (printf ("my_gmp_alloc %u\n", n));
    382      1.1  mrg   New (GMP_MALLOC_ID, p, n, char);
    383      1.1  mrg   TRACE (printf ("  p=%p\n", p));
    384      1.1  mrg   return p;
    385      1.1  mrg }
    386      1.1  mrg 
    387      1.1  mrg static void *
    388      1.1  mrg my_gmp_realloc (void *p, size_t oldsize, size_t newsize)
    389      1.1  mrg {
    390      1.1  mrg   TRACE (printf ("my_gmp_realloc %p, %u to %u\n", p, oldsize, newsize));
    391      1.1  mrg   Renew (p, newsize, char);
    392      1.1  mrg   TRACE (printf ("  p=%p\n", p));
    393      1.1  mrg   return p;
    394      1.1  mrg }
    395      1.1  mrg 
    396      1.1  mrg static void
    397      1.1  mrg my_gmp_free (void *p, size_t n)
    398      1.1  mrg {
    399      1.1  mrg   TRACE (printf ("my_gmp_free %p %u\n", p, n));
    400      1.1  mrg   Safefree (p);
    401      1.1  mrg }
    402      1.1  mrg 
    403      1.1  mrg 
    404      1.1  mrg #define my_mpx_set_svstr(type)                                  \
    405      1.1  mrg   static void                                                   \
    406      1.1  mrg   my_##type##_set_svstr (type##_ptr x, SV *sv)                  \
    407      1.1  mrg   {                                                             \
    408      1.1  mrg     const char  *str;                                           \
    409      1.1  mrg     STRLEN      len;                                            \
    410      1.1  mrg     TRACE (printf ("  my_" #type "_set_svstr\n"));              \
    411      1.1  mrg     assert (SvPOK(sv) || SvPOKp(sv));                           \
    412      1.1  mrg     str = SvPV (sv, len);                                       \
    413      1.1  mrg     TRACE (printf ("  str \"%s\"\n", str));                     \
    414      1.1  mrg     if (type##_set_str (x, str, 0) != 0)                        \
    415      1.1  mrg       croak ("%s: invalid string: %s", type##_class, str);      \
    416      1.1  mrg   }
    417      1.1  mrg 
    418      1.1  mrg my_mpx_set_svstr(mpz)
    419      1.1  mrg my_mpx_set_svstr(mpq)
    420      1.1  mrg my_mpx_set_svstr(mpf)
    421      1.1  mrg 
    422      1.1  mrg 
    423      1.1  mrg /* very slack */
    424      1.1  mrg static int
    425      1.1  mrg x_mpq_cmp_si (mpq_srcptr x, long yn, unsigned long yd)
    426      1.1  mrg {
    427      1.1  mrg   mpq  y;
    428      1.1  mrg   int  ret;
    429      1.1  mrg   y = new_mpq ();
    430      1.1  mrg   mpq_set_si (y->m, yn, yd);
    431      1.1  mrg   ret = mpq_cmp (x, y->m);
    432      1.1  mrg   free_mpq (y);
    433      1.1  mrg   return ret;
    434      1.1  mrg }
    435      1.1  mrg 
    436      1.1  mrg static int
    437      1.1  mrg x_mpq_fits_slong_p (mpq_srcptr q)
    438      1.1  mrg {
    439      1.1  mrg   return x_mpq_cmp_si (q, LONG_MIN, 1L) >= 0
    440      1.1  mrg     && mpq_cmp_ui (q, LONG_MAX, 1L) <= 0;
    441      1.1  mrg }
    442      1.1  mrg 
    443      1.1  mrg static int
    444      1.1  mrg x_mpz_cmp_q (mpz_ptr x, mpq_srcptr y)
    445      1.1  mrg {
    446      1.1  mrg   int  ret;
    447      1.1  mrg   mpz_set_ui (mpq_denref(tmp_mpq_0), 1L);
    448      1.1  mrg   mpz_swap (mpq_numref(tmp_mpq_0), x);
    449      1.1  mrg   ret = mpq_cmp (tmp_mpq_0, y);
    450      1.1  mrg   mpz_swap (mpq_numref(tmp_mpq_0), x);
    451      1.1  mrg   return ret;
    452      1.1  mrg }
    453      1.1  mrg 
    454      1.1  mrg static int
    455      1.1  mrg x_mpz_cmp_f (mpz_srcptr x, mpf_srcptr y)
    456      1.1  mrg {
    457      1.1  mrg   tmp_mpf_set_prec (tmp_mpf_0, mpz_sizeinbase (x, 2));
    458      1.1  mrg   mpf_set_z (tmp_mpf_0->m, x);
    459      1.1  mrg   return mpf_cmp (tmp_mpf_0->m, y);
    460      1.1  mrg }
    461      1.1  mrg 
    462      1.1  mrg 
    463      1.1  mrg #define USE_UNKNOWN  0
    464      1.1  mrg #define USE_IVX      1
    465      1.1  mrg #define USE_UVX      2
    466      1.1  mrg #define USE_NVX      3
    467      1.1  mrg #define USE_PVX      4
    468      1.1  mrg #define USE_MPZ      5
    469      1.1  mrg #define USE_MPQ      6
    470      1.1  mrg #define USE_MPF      7
    471      1.1  mrg 
    472      1.1  mrg /* mg_get is called every time we get a value, even if the private flags are
    473      1.1  mrg    still set from a previous such call.  This is the same as as SvIV and
    474      1.1  mrg    friends do.
    475      1.1  mrg 
    476      1.1  mrg    When POK, we use the PV, even if there's an IV or NV available.  This is
    477      1.1  mrg    because it's hard to be sure there wasn't any rounding in establishing
    478      1.1  mrg    the IV and/or NV.  Cases of overflow, where the PV should definitely be
    479      1.1  mrg    used, are easy enough to spot, but rounding is hard.  So although IV or
    480      1.1  mrg    NV would be more efficient, we must use the PV to be sure of getting all
    481      1.1  mrg    the data.  Applications should convert once to mpz, mpq or mpf when using
    482      1.1  mrg    a value repeatedly.
    483      1.1  mrg 
    484      1.1  mrg    Zany dual-type scalars like $! where the IV is an error code and the PV
    485      1.1  mrg    is an error description string won't work with this preference for PV,
    486      1.1  mrg    but that's too bad.  Such scalars should be rare, and unlikely to be used
    487      1.1  mrg    in bignum calculations.
    488      1.1  mrg 
    489      1.1  mrg    When IOK and NOK are both set, we would prefer to use the IV since it can
    490      1.1  mrg    be converted more efficiently, and because on a 64-bit system the NV may
    491      1.1  mrg    have less bits than the IV.  The following rules are applied,
    492      1.1  mrg 
    493      1.1  mrg    - If the NV is not an integer, then we must use that NV, since clearly
    494      1.1  mrg      the IV was merely established by rounding and is not the full value.
    495      1.1  mrg 
    496      1.1  mrg    - In perl prior to 5.8, an NV too big for an IV leaves an overflow value
    497      1.1  mrg      0xFFFFFFFF.  If the NV is too big to fit an IV then clearly it's the NV
    498      1.1  mrg      which is the true value and must be used.
    499      1.1  mrg 
    500      1.1  mrg    - In perl 5.8 and up, such an overflow doesn't set IOK, so that test is
    501      1.1  mrg      unnecessary.  However when coming from get-magic, IOKp _is_ set, and we
    502      1.1  mrg      must check for overflow the same as in older perl.
    503      1.1  mrg 
    504      1.1  mrg    FIXME:
    505      1.1  mrg 
    506      1.1  mrg    We'd like to call mg_get just once, but unfortunately sv_derived_from()
    507      1.1  mrg    will call it for each of our checks.  We could do a string compare like
    508      1.1  mrg    sv_isa ourselves, but that only tests the exact class, it doesn't
    509      1.1  mrg    recognise subclassing.  There doesn't seem to be a public interface to
    510      1.1  mrg    the subclassing tests (in the internal isa_lookup() function).  */
    511      1.1  mrg 
    512      1.1  mrg int
    513      1.1  mrg use_sv (SV *sv)
    514      1.1  mrg {
    515      1.1  mrg   double  d;
    516      1.1  mrg 
    517      1.1  mrg   if (SvGMAGICAL(sv))
    518      1.1  mrg     {
    519      1.1  mrg       mg_get(sv);
    520      1.1  mrg 
    521      1.1  mrg       if (SvPOKp(sv))
    522      1.1  mrg         return USE_PVX;
    523      1.1  mrg 
    524      1.1  mrg       if (SvIOKp(sv))
    525      1.1  mrg         {
    526      1.1  mrg           if (SvIsUV(sv))
    527      1.1  mrg             {
    528      1.1  mrg               if (SvNOKp(sv))
    529      1.1  mrg                 goto u_or_n;
    530      1.1  mrg               return USE_UVX;
    531      1.1  mrg             }
    532      1.1  mrg           else
    533      1.1  mrg             {
    534      1.1  mrg               if (SvNOKp(sv))
    535      1.1  mrg                 goto i_or_n;
    536      1.1  mrg               return USE_IVX;
    537      1.1  mrg             }
    538      1.1  mrg         }
    539      1.1  mrg 
    540      1.1  mrg       if (SvNOKp(sv))
    541      1.1  mrg         return USE_NVX;
    542      1.1  mrg 
    543      1.1  mrg       goto rok_or_unknown;
    544      1.1  mrg     }
    545      1.1  mrg 
    546      1.1  mrg   if (SvPOK(sv))
    547      1.1  mrg     return USE_PVX;
    548      1.1  mrg 
    549      1.1  mrg   if (SvIOK(sv))
    550      1.1  mrg     {
    551      1.1  mrg       if (SvIsUV(sv))
    552      1.1  mrg         {
    553      1.1  mrg           if (SvNOK(sv))
    554      1.1  mrg             {
    555      1.1  mrg               if (PERL_LT (5, 8))
    556      1.1  mrg                 {
    557      1.1  mrg                 u_or_n:
    558      1.1  mrg                   d = SvNVX(sv);
    559      1.1  mrg                   if (d >= ULONG_MAX_P1_AS_DOUBLE || d < 0.0)
    560      1.1  mrg                     return USE_NVX;
    561      1.1  mrg                 }
    562      1.1  mrg               d = SvNVX(sv);
    563      1.1  mrg               if (d != floor (d))
    564      1.1  mrg                 return USE_NVX;
    565      1.1  mrg             }
    566      1.1  mrg           return USE_UVX;
    567      1.1  mrg         }
    568      1.1  mrg       else
    569      1.1  mrg         {
    570      1.1  mrg           if (SvNOK(sv))
    571      1.1  mrg             {
    572      1.1  mrg               if (PERL_LT (5, 8))
    573      1.1  mrg                 {
    574      1.1  mrg                 i_or_n:
    575      1.1  mrg                   d = SvNVX(sv);
    576      1.1  mrg                   if (d >= LONG_MAX_P1_AS_DOUBLE || d < (double) LONG_MIN)
    577      1.1  mrg                     return USE_NVX;
    578      1.1  mrg                 }
    579      1.1  mrg               d = SvNVX(sv);
    580      1.1  mrg               if (d != floor (d))
    581      1.1  mrg                 return USE_NVX;
    582      1.1  mrg             }
    583      1.1  mrg           return USE_IVX;
    584      1.1  mrg         }
    585      1.1  mrg     }
    586      1.1  mrg 
    587      1.1  mrg   if (SvNOK(sv))
    588      1.1  mrg     return USE_NVX;
    589      1.1  mrg 
    590      1.1  mrg  rok_or_unknown:
    591      1.1  mrg   if (SvROK(sv))
    592      1.1  mrg     {
    593      1.1  mrg       if (sv_derived_from (sv, mpz_class))
    594      1.1  mrg         return USE_MPZ;
    595      1.1  mrg       if (sv_derived_from (sv, mpq_class))
    596      1.1  mrg         return USE_MPQ;
    597      1.1  mrg       if (sv_derived_from (sv, mpf_class))
    598      1.1  mrg         return USE_MPF;
    599      1.1  mrg     }
    600      1.1  mrg 
    601      1.1  mrg   return USE_UNKNOWN;
    602      1.1  mrg }
    603      1.1  mrg 
    604      1.1  mrg 
    605      1.1  mrg /* Coerce sv to an mpz.  Use tmp to hold the converted value if sv isn't
    606      1.1  mrg    already an mpz (or an mpq of which the numerator can be used).  Return
    607      1.1  mrg    the chosen mpz (tmp or the contents of sv).  */
    608      1.1  mrg 
    609      1.1  mrg static mpz_ptr
    610      1.1  mrg coerce_mpz_using (mpz_ptr tmp, SV *sv, int use)
    611      1.1  mrg {
    612      1.1  mrg   switch (use) {
    613      1.1  mrg   case USE_IVX:
    614      1.1  mrg     mpz_set_si (tmp, SvIVX(sv));
    615      1.1  mrg     return tmp;
    616      1.1  mrg 
    617      1.1  mrg   case USE_UVX:
    618      1.1  mrg     mpz_set_ui (tmp, SvUVX(sv));
    619      1.1  mrg     return tmp;
    620      1.1  mrg 
    621      1.1  mrg   case USE_NVX:
    622      1.1  mrg     {
    623      1.1  mrg       double d;
    624      1.1  mrg       d = SvNVX(sv);
    625      1.1  mrg       if (! double_integer_p (d))
    626      1.1  mrg         croak ("cannot coerce non-integer double to mpz");
    627      1.1  mrg       mpz_set_d (tmp, d);
    628      1.1  mrg       return tmp;
    629      1.1  mrg     }
    630      1.1  mrg 
    631      1.1  mrg   case USE_PVX:
    632      1.1  mrg     my_mpz_set_svstr (tmp, sv);
    633      1.1  mrg     return tmp;
    634      1.1  mrg 
    635      1.1  mrg   case USE_MPZ:
    636      1.1  mrg     return SvMPZ(sv)->m;
    637      1.1  mrg 
    638      1.1  mrg   case USE_MPQ:
    639      1.1  mrg     {
    640      1.1  mrg       mpq q = SvMPQ(sv);
    641      1.1  mrg       if (! x_mpq_integer_p (q->m))
    642      1.1  mrg         croak ("cannot coerce non-integer mpq to mpz");
    643      1.1  mrg       return mpq_numref(q->m);
    644      1.1  mrg     }
    645      1.1  mrg 
    646      1.1  mrg   case USE_MPF:
    647      1.1  mrg     {
    648      1.1  mrg       mpf f = SvMPF(sv);
    649      1.1  mrg       if (! mpf_integer_p (f))
    650      1.1  mrg         croak ("cannot coerce non-integer mpf to mpz");
    651      1.1  mrg       mpz_set_f (tmp, f);
    652      1.1  mrg       return tmp;
    653      1.1  mrg     }
    654      1.1  mrg 
    655      1.1  mrg   default:
    656      1.1  mrg     croak ("cannot coerce to mpz");
    657      1.1  mrg   }
    658      1.1  mrg }
    659      1.1  mrg static mpz_ptr
    660      1.1  mrg coerce_mpz (mpz_ptr tmp, SV *sv)
    661      1.1  mrg {
    662      1.1  mrg   return coerce_mpz_using (tmp, sv, use_sv (sv));
    663      1.1  mrg }
    664      1.1  mrg 
    665      1.1  mrg 
    666      1.1  mrg /* Coerce sv to an mpq.  If sv is an mpq then just return that, otherwise
    667      1.1  mrg    use tmp to hold the converted value and return that.  */
    668      1.1  mrg 
    669      1.1  mrg static mpq_ptr
    670      1.1  mrg coerce_mpq_using (mpq_ptr tmp, SV *sv, int use)
    671      1.1  mrg {
    672      1.1  mrg   TRACE (printf ("coerce_mpq_using %p %d\n", tmp, use));
    673      1.1  mrg   switch (use) {
    674      1.1  mrg   case USE_IVX:
    675      1.1  mrg     mpq_set_si (tmp, SvIVX(sv), 1L);
    676      1.1  mrg     return tmp;
    677      1.1  mrg 
    678      1.1  mrg   case USE_UVX:
    679      1.1  mrg     mpq_set_ui (tmp, SvUVX(sv), 1L);
    680      1.1  mrg     return tmp;
    681      1.1  mrg 
    682      1.1  mrg   case USE_NVX:
    683      1.1  mrg     mpq_set_d (tmp, SvNVX(sv));
    684      1.1  mrg     return tmp;
    685      1.1  mrg 
    686      1.1  mrg   case USE_PVX:
    687      1.1  mrg     my_mpq_set_svstr (tmp, sv);
    688      1.1  mrg     return tmp;
    689      1.1  mrg 
    690      1.1  mrg   case USE_MPZ:
    691      1.1  mrg     mpq_set_z (tmp, SvMPZ(sv)->m);
    692      1.1  mrg     return tmp;
    693      1.1  mrg 
    694      1.1  mrg   case USE_MPQ:
    695      1.1  mrg     return SvMPQ(sv)->m;
    696      1.1  mrg 
    697      1.1  mrg   case USE_MPF:
    698      1.1  mrg     mpq_set_f (tmp, SvMPF(sv));
    699      1.1  mrg     return tmp;
    700      1.1  mrg 
    701      1.1  mrg   default:
    702      1.1  mrg     croak ("cannot coerce to mpq");
    703      1.1  mrg   }
    704      1.1  mrg }
    705      1.1  mrg static mpq_ptr
    706      1.1  mrg coerce_mpq (mpq_ptr tmp, SV *sv)
    707      1.1  mrg {
    708      1.1  mrg   return coerce_mpq_using (tmp, sv, use_sv (sv));
    709      1.1  mrg }
    710      1.1  mrg 
    711      1.1  mrg 
    712      1.1  mrg static void
    713      1.1  mrg my_mpf_set_sv_using (mpf_ptr f, SV *sv, int use)
    714      1.1  mrg {
    715      1.1  mrg   switch (use) {
    716      1.1  mrg   case USE_IVX:
    717      1.1  mrg     mpf_set_si (f, SvIVX(sv));
    718      1.1  mrg     break;
    719      1.1  mrg 
    720      1.1  mrg   case USE_UVX:
    721      1.1  mrg     mpf_set_ui (f, SvUVX(sv));
    722      1.1  mrg     break;
    723      1.1  mrg 
    724      1.1  mrg   case USE_NVX:
    725      1.1  mrg     mpf_set_d (f, SvNVX(sv));
    726      1.1  mrg     break;
    727      1.1  mrg 
    728      1.1  mrg   case USE_PVX:
    729      1.1  mrg     my_mpf_set_svstr (f, sv);
    730      1.1  mrg     break;
    731      1.1  mrg 
    732      1.1  mrg   case USE_MPZ:
    733      1.1  mrg     mpf_set_z (f, SvMPZ(sv)->m);
    734      1.1  mrg     break;
    735      1.1  mrg 
    736      1.1  mrg   case USE_MPQ:
    737      1.1  mrg     mpf_set_q (f, SvMPQ(sv)->m);
    738      1.1  mrg     break;
    739      1.1  mrg 
    740      1.1  mrg   case USE_MPF:
    741      1.1  mrg     mpf_set (f, SvMPF(sv));
    742      1.1  mrg     break;
    743      1.1  mrg 
    744      1.1  mrg   default:
    745      1.1  mrg     croak ("cannot coerce to mpf");
    746      1.1  mrg   }
    747      1.1  mrg }
    748      1.1  mrg 
    749      1.1  mrg /* Coerce sv to an mpf.  If sv is an mpf then just return that, otherwise
    750      1.1  mrg    use tmp to hold the converted value (with prec precision).  */
    751      1.1  mrg static mpf_ptr
    752      1.1  mrg coerce_mpf_using (tmp_mpf_ptr tmp, SV *sv, unsigned long prec, int use)
    753      1.1  mrg {
    754      1.1  mrg   if (use == USE_MPF)
    755      1.1  mrg     return SvMPF(sv);
    756      1.1  mrg 
    757      1.1  mrg   tmp_mpf_set_prec (tmp, prec);
    758      1.1  mrg   my_mpf_set_sv_using (tmp->m, sv, use);
    759      1.1  mrg   return tmp->m;
    760      1.1  mrg }
    761      1.1  mrg static mpf_ptr
    762      1.1  mrg coerce_mpf (tmp_mpf_ptr tmp, SV *sv, unsigned long prec)
    763      1.1  mrg {
    764      1.1  mrg   return coerce_mpf_using (tmp, sv, prec, use_sv (sv));
    765      1.1  mrg }
    766      1.1  mrg 
    767      1.1  mrg 
    768      1.1  mrg /* Coerce xv to an mpf and store the pointer in x, ditto for yv to x.  If
    769      1.1  mrg    one of xv or yv is an mpf then use it for the precision, otherwise use
    770      1.1  mrg    the default precision.  */
    771      1.1  mrg unsigned long
    772      1.1  mrg coerce_mpf_pair (mpf *xp, SV *xv, mpf *yp, SV *yv)
    773      1.1  mrg {
    774      1.1  mrg   int x_use = use_sv (xv);
    775      1.1  mrg   int y_use = use_sv (yv);
    776      1.1  mrg   unsigned long  prec;
    777      1.1  mrg   mpf  x, y;
    778      1.1  mrg 
    779      1.1  mrg   if (x_use == USE_MPF)
    780      1.1  mrg     {
    781      1.1  mrg       x = SvMPF(xv);
    782      1.1  mrg       prec = mpf_get_prec (x);
    783      1.1  mrg       y = coerce_mpf_using (tmp_mpf_0, yv, prec, y_use);
    784      1.1  mrg     }
    785      1.1  mrg   else
    786      1.1  mrg     {
    787      1.1  mrg       y = coerce_mpf_using (tmp_mpf_0, yv, mpf_get_default_prec(), y_use);
    788      1.1  mrg       prec = mpf_get_prec (y);
    789      1.1  mrg       x = coerce_mpf_using (tmp_mpf_1, xv, prec, x_use);
    790      1.1  mrg     }
    791      1.1  mrg   *xp = x;
    792      1.1  mrg   *yp = y;
    793      1.1  mrg   return prec;
    794      1.1  mrg }
    795      1.1  mrg 
    796      1.1  mrg 
    797      1.1  mrg /* Note that SvUV is not used, since it merely treats the signed IV as if it
    798      1.1  mrg    was unsigned.  We get an IV and check its sign. */
    799      1.1  mrg static unsigned long
    800      1.1  mrg coerce_ulong (SV *sv)
    801      1.1  mrg {
    802      1.1  mrg   long  n;
    803      1.1  mrg 
    804      1.1  mrg   switch (use_sv (sv)) {
    805      1.1  mrg   case USE_IVX:
    806      1.1  mrg     n = SvIVX(sv);
    807      1.1  mrg   negative_check:
    808      1.1  mrg     if (n < 0)
    809      1.1  mrg       goto range_error;
    810      1.1  mrg     return n;
    811      1.1  mrg 
    812      1.1  mrg   case USE_UVX:
    813      1.1  mrg     return SvUVX(sv);
    814      1.1  mrg 
    815      1.1  mrg   case USE_NVX:
    816      1.1  mrg     {
    817      1.1  mrg       double d;
    818      1.1  mrg       d = SvNVX(sv);
    819      1.1  mrg       if (! double_integer_p (d))
    820      1.1  mrg         goto integer_error;
    821      1.1  mrg       n = SvIV(sv);
    822      1.1  mrg     }
    823      1.1  mrg     goto negative_check;
    824      1.1  mrg 
    825      1.1  mrg   case USE_PVX:
    826      1.1  mrg     /* FIXME: Check the string is an integer. */
    827      1.1  mrg     n = SvIV(sv);
    828      1.1  mrg     goto negative_check;
    829      1.1  mrg 
    830      1.1  mrg   case USE_MPZ:
    831      1.1  mrg     {
    832      1.1  mrg       mpz z = SvMPZ(sv);
    833      1.1  mrg       if (! mpz_fits_ulong_p (z->m))
    834      1.1  mrg         goto range_error;
    835      1.1  mrg       return mpz_get_ui (z->m);
    836      1.1  mrg     }
    837      1.1  mrg 
    838      1.1  mrg   case USE_MPQ:
    839      1.1  mrg     {
    840      1.1  mrg       mpq q = SvMPQ(sv);
    841      1.1  mrg       if (! x_mpq_integer_p (q->m))
    842      1.1  mrg         goto integer_error;
    843      1.1  mrg       if (! mpz_fits_ulong_p (mpq_numref (q->m)))
    844      1.1  mrg         goto range_error;
    845      1.1  mrg       return mpz_get_ui (mpq_numref (q->m));
    846      1.1  mrg     }
    847      1.1  mrg 
    848      1.1  mrg   case USE_MPF:
    849      1.1  mrg     {
    850      1.1  mrg       mpf f = SvMPF(sv);
    851      1.1  mrg       if (! mpf_integer_p (f))
    852      1.1  mrg         goto integer_error;
    853      1.1  mrg       if (! mpf_fits_ulong_p (f))
    854      1.1  mrg         goto range_error;
    855      1.1  mrg       return mpf_get_ui (f);
    856      1.1  mrg     }
    857      1.1  mrg 
    858      1.1  mrg   default:
    859      1.1  mrg     croak ("cannot coerce to ulong");
    860      1.1  mrg   }
    861      1.1  mrg 
    862      1.1  mrg  integer_error:
    863      1.1  mrg   croak ("not an integer");
    864      1.1  mrg 
    865      1.1  mrg  range_error:
    866      1.1  mrg   croak ("out of range for ulong");
    867      1.1  mrg }
    868      1.1  mrg 
    869      1.1  mrg 
    870      1.1  mrg static long
    871      1.1  mrg coerce_long (SV *sv)
    872      1.1  mrg {
    873      1.1  mrg   switch (use_sv (sv)) {
    874      1.1  mrg   case USE_IVX:
    875      1.1  mrg     return SvIVX(sv);
    876      1.1  mrg 
    877      1.1  mrg   case USE_UVX:
    878      1.1  mrg     {
    879      1.1  mrg       UV u = SvUVX(sv);
    880      1.1  mrg       if (u > (UV) LONG_MAX)
    881      1.1  mrg         goto range_error;
    882      1.1  mrg       return u;
    883      1.1  mrg     }
    884      1.1  mrg 
    885      1.1  mrg   case USE_NVX:
    886      1.1  mrg     {
    887      1.1  mrg       double d = SvNVX(sv);
    888      1.1  mrg       if (! double_integer_p (d))
    889      1.1  mrg         goto integer_error;
    890      1.1  mrg       return SvIV(sv);
    891      1.1  mrg     }
    892      1.1  mrg 
    893      1.1  mrg   case USE_PVX:
    894      1.1  mrg     /* FIXME: Check the string is an integer. */
    895      1.1  mrg     return SvIV(sv);
    896      1.1  mrg 
    897      1.1  mrg   case USE_MPZ:
    898      1.1  mrg     {
    899      1.1  mrg       mpz z = SvMPZ(sv);
    900      1.1  mrg       if (! mpz_fits_slong_p (z->m))
    901      1.1  mrg         goto range_error;
    902      1.1  mrg       return mpz_get_si (z->m);
    903      1.1  mrg     }
    904      1.1  mrg 
    905      1.1  mrg   case USE_MPQ:
    906      1.1  mrg     {
    907      1.1  mrg       mpq q = SvMPQ(sv);
    908      1.1  mrg       if (! x_mpq_integer_p (q->m))
    909      1.1  mrg         goto integer_error;
    910      1.1  mrg       if (! mpz_fits_slong_p (mpq_numref (q->m)))
    911      1.1  mrg         goto range_error;
    912      1.1  mrg       return mpz_get_si (mpq_numref (q->m));
    913      1.1  mrg     }
    914      1.1  mrg 
    915      1.1  mrg   case USE_MPF:
    916      1.1  mrg     {
    917      1.1  mrg       mpf f = SvMPF(sv);
    918      1.1  mrg       if (! mpf_integer_p (f))
    919      1.1  mrg         goto integer_error;
    920      1.1  mrg       if (! mpf_fits_slong_p (f))
    921      1.1  mrg         goto range_error;
    922      1.1  mrg       return mpf_get_si (f);
    923      1.1  mrg     }
    924      1.1  mrg 
    925      1.1  mrg   default:
    926      1.1  mrg     croak ("cannot coerce to long");
    927      1.1  mrg   }
    928      1.1  mrg 
    929      1.1  mrg  integer_error:
    930      1.1  mrg   croak ("not an integer");
    931      1.1  mrg 
    932      1.1  mrg  range_error:
    933      1.1  mrg   croak ("out of range for ulong");
    934      1.1  mrg }
    935      1.1  mrg 
    936      1.1  mrg 
    937      1.1  mrg /* ------------------------------------------------------------------------- */
    938      1.1  mrg 
    939      1.1  mrg MODULE = GMP         PACKAGE = GMP
    940      1.1  mrg 
    941      1.1  mrg BOOT:
    942      1.1  mrg     TRACE (printf ("GMP boot\n"));
    943      1.1  mrg     mp_set_memory_functions (my_gmp_alloc, my_gmp_realloc, my_gmp_free);
    944      1.1  mrg     mpz_init (tmp_mpz_0);
    945      1.1  mrg     mpz_init (tmp_mpz_1);
    946      1.1  mrg     mpz_init (tmp_mpz_2);
    947      1.1  mrg     mpq_init (tmp_mpq_0);
    948      1.1  mrg     mpq_init (tmp_mpq_1);
    949      1.1  mrg     tmp_mpf_init (tmp_mpf_0);
    950      1.1  mrg     tmp_mpf_init (tmp_mpf_1);
    951      1.1  mrg     mpz_class_hv = gv_stashpv (mpz_class, 1);
    952      1.1  mrg     mpq_class_hv = gv_stashpv (mpq_class, 1);
    953      1.1  mrg     mpf_class_hv = gv_stashpv (mpf_class, 1);
    954      1.1  mrg 
    955      1.1  mrg 
    956      1.1  mrg void
    957      1.1  mrg END()
    958      1.1  mrg CODE:
    959      1.1  mrg     TRACE (printf ("GMP end\n"));
    960      1.1  mrg     TRACE_ACTIVE ();
    961      1.1  mrg     /* These are not always true, see Bugs at the top of the file. */
    962      1.1  mrg     /* assert (mpz_count == 0); */
    963      1.1  mrg     /* assert (mpq_count == 0); */
    964      1.1  mrg     /* assert (mpf_count == 0); */
    965      1.1  mrg     /* assert (rand_count == 0); */
    966      1.1  mrg 
    967      1.1  mrg 
    968      1.1  mrg const_string
    969      1.1  mrg version()
    970      1.1  mrg CODE:
    971      1.1  mrg     RETVAL = gmp_version;
    972      1.1  mrg OUTPUT:
    973      1.1  mrg     RETVAL
    974      1.1  mrg 
    975      1.1  mrg 
    976      1.1  mrg bool
    977      1.1  mrg fits_slong_p (sv)
    978      1.1  mrg     SV *sv
    979      1.1  mrg CODE:
    980      1.1  mrg     switch (use_sv (sv)) {
    981      1.1  mrg     case USE_IVX:
    982      1.1  mrg       RETVAL = 1;
    983      1.1  mrg       break;
    984      1.1  mrg 
    985      1.1  mrg     case USE_UVX:
    986      1.1  mrg       {
    987      1.1  mrg         UV u = SvUVX(sv);
    988      1.1  mrg         RETVAL = (u <= LONG_MAX);
    989      1.1  mrg       }
    990      1.1  mrg       break;
    991      1.1  mrg 
    992      1.1  mrg     case USE_NVX:
    993      1.1  mrg       {
    994      1.1  mrg         double  d = SvNVX(sv);
    995      1.1  mrg         RETVAL = (d >= (double) LONG_MIN && d < LONG_MAX_P1_AS_DOUBLE);
    996      1.1  mrg       }
    997      1.1  mrg       break;
    998      1.1  mrg 
    999      1.1  mrg     case USE_PVX:
   1000      1.1  mrg       {
   1001      1.1  mrg         STRLEN len;
   1002      1.1  mrg         const char *str = SvPV (sv, len);
   1003      1.1  mrg         if (mpq_set_str (tmp_mpq_0, str, 0) == 0)
   1004      1.1  mrg           RETVAL = x_mpq_fits_slong_p (tmp_mpq_0);
   1005      1.1  mrg         else
   1006      1.1  mrg           {
   1007      1.1  mrg             /* enough precision for a long */
   1008      1.1  mrg             tmp_mpf_set_prec (tmp_mpf_0, 2*mp_bits_per_limb);
   1009      1.1  mrg             if (mpf_set_str (tmp_mpf_0->m, str, 10) != 0)
   1010      1.1  mrg               croak ("GMP::fits_slong_p invalid string format");
   1011      1.1  mrg             RETVAL = mpf_fits_slong_p (tmp_mpf_0->m);
   1012      1.1  mrg           }
   1013      1.1  mrg       }
   1014      1.1  mrg       break;
   1015      1.1  mrg 
   1016      1.1  mrg     case USE_MPZ:
   1017      1.1  mrg       RETVAL = mpz_fits_slong_p (SvMPZ(sv)->m);
   1018      1.1  mrg       break;
   1019      1.1  mrg 
   1020      1.1  mrg     case USE_MPQ:
   1021      1.1  mrg       RETVAL = x_mpq_fits_slong_p (SvMPQ(sv)->m);
   1022      1.1  mrg       break;
   1023      1.1  mrg 
   1024      1.1  mrg     case USE_MPF:
   1025      1.1  mrg       RETVAL = mpf_fits_slong_p (SvMPF(sv));
   1026      1.1  mrg       break;
   1027      1.1  mrg 
   1028      1.1  mrg     default:
   1029      1.1  mrg       croak ("GMP::fits_slong_p invalid argument");
   1030      1.1  mrg     }
   1031      1.1  mrg OUTPUT:
   1032      1.1  mrg     RETVAL
   1033      1.1  mrg 
   1034      1.1  mrg 
   1035      1.1  mrg double
   1036      1.1  mrg get_d (sv)
   1037      1.1  mrg     SV *sv
   1038      1.1  mrg CODE:
   1039      1.1  mrg     switch (use_sv (sv)) {
   1040      1.1  mrg     case USE_IVX:
   1041      1.1  mrg       RETVAL = (double) SvIVX(sv);
   1042      1.1  mrg       break;
   1043      1.1  mrg 
   1044      1.1  mrg     case USE_UVX:
   1045      1.1  mrg       RETVAL = (double) SvUVX(sv);
   1046      1.1  mrg       break;
   1047      1.1  mrg 
   1048      1.1  mrg     case USE_NVX:
   1049      1.1  mrg       RETVAL = SvNVX(sv);
   1050      1.1  mrg       break;
   1051      1.1  mrg 
   1052      1.1  mrg     case USE_PVX:
   1053      1.1  mrg       {
   1054      1.1  mrg         STRLEN len;
   1055      1.1  mrg         RETVAL = atof(SvPV(sv, len));
   1056      1.1  mrg       }
   1057      1.1  mrg       break;
   1058      1.1  mrg 
   1059      1.1  mrg     case USE_MPZ:
   1060      1.1  mrg       RETVAL = mpz_get_d (SvMPZ(sv)->m);
   1061      1.1  mrg       break;
   1062      1.1  mrg 
   1063      1.1  mrg     case USE_MPQ:
   1064      1.1  mrg       RETVAL = mpq_get_d (SvMPQ(sv)->m);
   1065      1.1  mrg       break;
   1066      1.1  mrg 
   1067      1.1  mrg     case USE_MPF:
   1068      1.1  mrg       RETVAL = mpf_get_d (SvMPF(sv));
   1069      1.1  mrg       break;
   1070      1.1  mrg 
   1071      1.1  mrg     default:
   1072      1.1  mrg       croak ("GMP::get_d invalid argument");
   1073      1.1  mrg     }
   1074      1.1  mrg OUTPUT:
   1075      1.1  mrg     RETVAL
   1076      1.1  mrg 
   1077      1.1  mrg 
   1078      1.1  mrg void
   1079      1.1  mrg get_d_2exp (sv)
   1080      1.1  mrg     SV *sv
   1081      1.1  mrg PREINIT:
   1082      1.1  mrg     double ret;
   1083      1.1  mrg     long   exp;
   1084      1.1  mrg PPCODE:
   1085      1.1  mrg     switch (use_sv (sv)) {
   1086      1.1  mrg     case USE_IVX:
   1087      1.1  mrg       ret = (double) SvIVX(sv);
   1088      1.1  mrg       goto use_frexp;
   1089      1.1  mrg 
   1090      1.1  mrg     case USE_UVX:
   1091      1.1  mrg       ret = (double) SvUVX(sv);
   1092      1.1  mrg       goto use_frexp;
   1093      1.1  mrg 
   1094      1.1  mrg     case USE_NVX:
   1095      1.1  mrg       {
   1096      1.1  mrg         int i_exp;
   1097      1.1  mrg         ret = SvNVX(sv);
   1098      1.1  mrg       use_frexp:
   1099      1.1  mrg         ret = frexp (ret, &i_exp);
   1100      1.1  mrg         exp = i_exp;
   1101      1.1  mrg       }
   1102      1.1  mrg       break;
   1103      1.1  mrg 
   1104      1.1  mrg     case USE_PVX:
   1105      1.1  mrg       /* put strings through mpf to give full exp range */
   1106      1.1  mrg       tmp_mpf_set_prec (tmp_mpf_0, DBL_MANT_DIG);
   1107      1.1  mrg       my_mpf_set_svstr (tmp_mpf_0->m, sv);
   1108      1.1  mrg       ret = mpf_get_d_2exp (&exp, tmp_mpf_0->m);
   1109      1.1  mrg       break;
   1110      1.1  mrg 
   1111      1.1  mrg     case USE_MPZ:
   1112      1.1  mrg       ret = mpz_get_d_2exp (&exp, SvMPZ(sv)->m);
   1113      1.1  mrg       break;
   1114      1.1  mrg 
   1115      1.1  mrg     case USE_MPQ:
   1116      1.1  mrg       tmp_mpf_set_prec (tmp_mpf_0, DBL_MANT_DIG);
   1117      1.1  mrg       mpf_set_q (tmp_mpf_0->m, SvMPQ(sv)->m);
   1118      1.1  mrg       ret = mpf_get_d_2exp (&exp, tmp_mpf_0->m);
   1119      1.1  mrg       break;
   1120      1.1  mrg 
   1121      1.1  mrg     case USE_MPF:
   1122      1.1  mrg       ret = mpf_get_d_2exp (&exp, SvMPF(sv));
   1123      1.1  mrg       break;
   1124      1.1  mrg 
   1125      1.1  mrg     default:
   1126      1.1  mrg       croak ("GMP::get_d_2exp invalid argument");
   1127      1.1  mrg     }
   1128      1.1  mrg     PUSHs (sv_2mortal (newSVnv (ret)));
   1129      1.1  mrg     PUSHs (sv_2mortal (newSViv (exp)));
   1130      1.1  mrg 
   1131      1.1  mrg 
   1132      1.1  mrg long
   1133      1.1  mrg get_si (sv)
   1134      1.1  mrg     SV *sv
   1135      1.1  mrg CODE:
   1136      1.1  mrg     switch (use_sv (sv)) {
   1137      1.1  mrg     case USE_IVX:
   1138      1.1  mrg       RETVAL = SvIVX(sv);
   1139      1.1  mrg       break;
   1140      1.1  mrg 
   1141      1.1  mrg     case USE_UVX:
   1142      1.1  mrg       RETVAL = SvUVX(sv);
   1143      1.1  mrg       break;
   1144      1.1  mrg 
   1145      1.1  mrg     case USE_NVX:
   1146      1.1  mrg       RETVAL = (long) SvNVX(sv);
   1147      1.1  mrg       break;
   1148      1.1  mrg 
   1149      1.1  mrg     case USE_PVX:
   1150      1.1  mrg       RETVAL = SvIV(sv);
   1151      1.1  mrg       break;
   1152      1.1  mrg 
   1153      1.1  mrg     case USE_MPZ:
   1154      1.1  mrg       RETVAL = mpz_get_si (SvMPZ(sv)->m);
   1155      1.1  mrg       break;
   1156      1.1  mrg 
   1157      1.1  mrg     case USE_MPQ:
   1158      1.1  mrg       mpz_set_q (tmp_mpz_0, SvMPQ(sv)->m);
   1159      1.1  mrg       RETVAL = mpz_get_si (tmp_mpz_0);
   1160      1.1  mrg       break;
   1161      1.1  mrg 
   1162      1.1  mrg     case USE_MPF:
   1163      1.1  mrg       RETVAL = mpf_get_si (SvMPF(sv));
   1164      1.1  mrg       break;
   1165      1.1  mrg 
   1166      1.1  mrg     default:
   1167      1.1  mrg       croak ("GMP::get_si invalid argument");
   1168      1.1  mrg     }
   1169      1.1  mrg OUTPUT:
   1170      1.1  mrg     RETVAL
   1171      1.1  mrg 
   1172      1.1  mrg 
   1173      1.1  mrg void
   1174      1.1  mrg get_str (sv, ...)
   1175      1.1  mrg     SV *sv
   1176      1.1  mrg PREINIT:
   1177      1.1  mrg     char      *str;
   1178      1.1  mrg     mp_exp_t  exp;
   1179      1.1  mrg     mpz_ptr   z;
   1180      1.1  mrg     mpq_ptr   q;
   1181      1.1  mrg     mpf       f;
   1182      1.1  mrg     int       base;
   1183      1.1  mrg     int       ndigits;
   1184      1.1  mrg PPCODE:
   1185      1.1  mrg     TRACE (printf ("GMP::get_str\n"));
   1186      1.1  mrg 
   1187      1.1  mrg     if (items >= 2)
   1188      1.1  mrg       base = coerce_long (ST(1));
   1189      1.1  mrg     else
   1190      1.1  mrg       base = 10;
   1191      1.1  mrg     TRACE (printf (" base=%d\n", base));
   1192      1.1  mrg 
   1193      1.1  mrg     if (items >= 3)
   1194      1.1  mrg       ndigits = coerce_long (ST(2));
   1195      1.1  mrg     else
   1196      1.1  mrg       ndigits = 10;
   1197      1.1  mrg     TRACE (printf (" ndigits=%d\n", ndigits));
   1198      1.1  mrg 
   1199      1.1  mrg     EXTEND (SP, 2);
   1200      1.1  mrg 
   1201      1.1  mrg     switch (use_sv (sv)) {
   1202      1.1  mrg     case USE_IVX:
   1203      1.1  mrg       mpz_set_si (tmp_mpz_0, SvIVX(sv));
   1204      1.1  mrg     get_tmp_mpz_0:
   1205      1.1  mrg       z = tmp_mpz_0;
   1206      1.1  mrg       goto get_mpz;
   1207      1.1  mrg 
   1208      1.1  mrg     case USE_UVX:
   1209      1.1  mrg       mpz_set_ui (tmp_mpz_0, SvUVX(sv));
   1210      1.1  mrg       goto get_tmp_mpz_0;
   1211      1.1  mrg 
   1212      1.1  mrg     case USE_NVX:
   1213      1.1  mrg       /* only digits in the original double, not in the coerced form */
   1214      1.1  mrg       if (ndigits == 0)
   1215      1.1  mrg         ndigits = DBL_DIG;
   1216      1.1  mrg       mpf_set_d (tmp_mpf_0->m, SvNVX(sv));
   1217      1.1  mrg       f = tmp_mpf_0->m;
   1218      1.1  mrg       goto get_mpf;
   1219      1.1  mrg 
   1220      1.1  mrg     case USE_PVX:
   1221      1.1  mrg       {
   1222      1.1  mrg         /* get_str on a string is not much more than a base conversion */
   1223      1.1  mrg         STRLEN len;
   1224      1.1  mrg         str = SvPV (sv, len);
   1225      1.1  mrg         if (mpz_set_str (tmp_mpz_0, str, 0) == 0)
   1226      1.1  mrg           {
   1227      1.1  mrg             z = tmp_mpz_0;
   1228      1.1  mrg             goto get_mpz;
   1229      1.1  mrg           }
   1230      1.1  mrg         else if (mpq_set_str (tmp_mpq_0, str, 0) == 0)
   1231      1.1  mrg           {
   1232      1.1  mrg             q = tmp_mpq_0;
   1233      1.1  mrg             goto get_mpq;
   1234      1.1  mrg           }
   1235      1.1  mrg         else
   1236      1.1  mrg           {
   1237      1.1  mrg             /* FIXME: Would like perhaps a precision equivalent to the
   1238      1.1  mrg                number of significant digits of the string, in its given
   1239      1.1  mrg                base.  */
   1240      1.1  mrg             tmp_mpf_set_prec (tmp_mpf_0, strlen(str));
   1241      1.1  mrg             if (mpf_set_str (tmp_mpf_0->m, str, 10) == 0)
   1242      1.1  mrg               {
   1243      1.1  mrg                 f = tmp_mpf_0->m;
   1244      1.1  mrg                 goto get_mpf;
   1245      1.1  mrg               }
   1246      1.1  mrg             else
   1247      1.1  mrg               croak ("GMP::get_str invalid string format");
   1248      1.1  mrg           }
   1249      1.1  mrg       }
   1250      1.1  mrg       break;
   1251      1.1  mrg 
   1252      1.1  mrg     case USE_MPZ:
   1253      1.1  mrg       z = SvMPZ(sv)->m;
   1254      1.1  mrg     get_mpz:
   1255      1.1  mrg       str = mpz_get_str (NULL, base, z);
   1256      1.1  mrg     push_str:
   1257      1.1  mrg       PUSHs (sv_2mortal (newSVpv (str, 0)));
   1258      1.1  mrg       break;
   1259      1.1  mrg 
   1260      1.1  mrg     case USE_MPQ:
   1261      1.1  mrg       q = SvMPQ(sv)->m;
   1262      1.1  mrg     get_mpq:
   1263      1.1  mrg       str = mpq_get_str (NULL, base, q);
   1264      1.1  mrg       goto push_str;
   1265      1.1  mrg 
   1266      1.1  mrg     case USE_MPF:
   1267      1.1  mrg       f = SvMPF(sv);
   1268      1.1  mrg     get_mpf:
   1269      1.1  mrg       str = mpf_get_str (NULL, &exp, base, 0, f);
   1270      1.1  mrg       PUSHs (sv_2mortal (newSVpv (str, 0)));
   1271      1.1  mrg       PUSHs (sv_2mortal (newSViv (exp)));
   1272      1.1  mrg       break;
   1273      1.1  mrg 
   1274      1.1  mrg     default:
   1275      1.1  mrg       croak ("GMP::get_str invalid argument");
   1276      1.1  mrg     }
   1277      1.1  mrg 
   1278      1.1  mrg 
   1279      1.1  mrg bool
   1280      1.1  mrg integer_p (sv)
   1281      1.1  mrg     SV *sv
   1282      1.1  mrg CODE:
   1283      1.1  mrg     switch (use_sv (sv)) {
   1284      1.1  mrg     case USE_IVX:
   1285      1.1  mrg     case USE_UVX:
   1286      1.1  mrg       RETVAL = 1;
   1287      1.1  mrg       break;
   1288      1.1  mrg 
   1289      1.1  mrg     case USE_NVX:
   1290      1.1  mrg       RETVAL = double_integer_p (SvNVX(sv));
   1291      1.1  mrg       break;
   1292      1.1  mrg 
   1293      1.1  mrg     case USE_PVX:
   1294      1.1  mrg       {
   1295      1.1  mrg         /* FIXME: Maybe this should be done by parsing the string, not by an
   1296      1.1  mrg            actual conversion.  */
   1297      1.1  mrg         STRLEN len;
   1298      1.1  mrg         const char *str = SvPV (sv, len);
   1299      1.1  mrg         if (mpq_set_str (tmp_mpq_0, str, 0) == 0)
   1300      1.1  mrg           RETVAL = x_mpq_integer_p (tmp_mpq_0);
   1301      1.1  mrg         else
   1302      1.1  mrg           {
   1303      1.1  mrg             /* enough for all digits of the string */
   1304      1.1  mrg             tmp_mpf_set_prec (tmp_mpf_0, strlen(str)+64);
   1305      1.1  mrg             if (mpf_set_str (tmp_mpf_0->m, str, 10) == 0)
   1306      1.1  mrg               RETVAL = mpf_integer_p (tmp_mpf_0->m);
   1307      1.1  mrg             else
   1308      1.1  mrg               croak ("GMP::integer_p invalid string format");
   1309      1.1  mrg           }
   1310      1.1  mrg       }
   1311      1.1  mrg       break;
   1312      1.1  mrg 
   1313      1.1  mrg     case USE_MPZ:
   1314      1.1  mrg       RETVAL = 1;
   1315      1.1  mrg       break;
   1316      1.1  mrg 
   1317      1.1  mrg     case USE_MPQ:
   1318      1.1  mrg       RETVAL = x_mpq_integer_p (SvMPQ(sv)->m);
   1319      1.1  mrg       break;
   1320      1.1  mrg 
   1321      1.1  mrg     case USE_MPF:
   1322      1.1  mrg       RETVAL = mpf_integer_p (SvMPF(sv));
   1323      1.1  mrg       break;
   1324      1.1  mrg 
   1325      1.1  mrg     default:
   1326      1.1  mrg       croak ("GMP::integer_p invalid argument");
   1327      1.1  mrg     }
   1328      1.1  mrg OUTPUT:
   1329      1.1  mrg     RETVAL
   1330      1.1  mrg 
   1331      1.1  mrg 
   1332      1.1  mrg int
   1333      1.1  mrg sgn (sv)
   1334      1.1  mrg     SV *sv
   1335      1.1  mrg CODE:
   1336      1.1  mrg     switch (use_sv (sv)) {
   1337      1.1  mrg     case USE_IVX:
   1338      1.1  mrg       RETVAL = SGN (SvIVX(sv));
   1339      1.1  mrg       break;
   1340      1.1  mrg 
   1341      1.1  mrg     case USE_UVX:
   1342      1.1  mrg       RETVAL = (SvUVX(sv) > 0);
   1343      1.1  mrg       break;
   1344      1.1  mrg 
   1345      1.1  mrg     case USE_NVX:
   1346      1.1  mrg       RETVAL = SGN (SvNVX(sv));
   1347      1.1  mrg       break;
   1348      1.1  mrg 
   1349      1.1  mrg     case USE_PVX:
   1350      1.1  mrg       {
   1351      1.1  mrg         /* FIXME: Maybe this should be done by parsing the string, not by an
   1352      1.1  mrg            actual conversion.  */
   1353      1.1  mrg         STRLEN len;
   1354      1.1  mrg         const char *str = SvPV (sv, len);
   1355      1.1  mrg         if (mpq_set_str (tmp_mpq_0, str, 0) == 0)
   1356      1.1  mrg           RETVAL = mpq_sgn (tmp_mpq_0);
   1357      1.1  mrg         else
   1358      1.1  mrg           {
   1359      1.1  mrg             /* enough for all digits of the string */
   1360      1.1  mrg             tmp_mpf_set_prec (tmp_mpf_0, strlen(str)+64);
   1361      1.1  mrg             if (mpf_set_str (tmp_mpf_0->m, str, 10) == 0)
   1362      1.1  mrg               RETVAL = mpf_sgn (tmp_mpf_0->m);
   1363      1.1  mrg             else
   1364      1.1  mrg               croak ("GMP::sgn invalid string format");
   1365      1.1  mrg           }
   1366      1.1  mrg       }
   1367      1.1  mrg       break;
   1368      1.1  mrg 
   1369      1.1  mrg     case USE_MPZ:
   1370      1.1  mrg       RETVAL = mpz_sgn (SvMPZ(sv)->m);
   1371      1.1  mrg       break;
   1372      1.1  mrg 
   1373      1.1  mrg     case USE_MPQ:
   1374      1.1  mrg       RETVAL = mpq_sgn (SvMPQ(sv)->m);
   1375      1.1  mrg       break;
   1376      1.1  mrg 
   1377      1.1  mrg     case USE_MPF:
   1378      1.1  mrg       RETVAL = mpf_sgn (SvMPF(sv));
   1379      1.1  mrg       break;
   1380      1.1  mrg 
   1381      1.1  mrg     default:
   1382      1.1  mrg       croak ("GMP::sgn invalid argument");
   1383      1.1  mrg     }
   1384      1.1  mrg OUTPUT:
   1385      1.1  mrg     RETVAL
   1386      1.1  mrg 
   1387      1.1  mrg 
   1388      1.1  mrg # currently undocumented
   1389      1.1  mrg void
   1390      1.1  mrg shrink ()
   1391      1.1  mrg CODE:
   1392      1.1  mrg #define x_mpz_shrink(z) \
   1393      1.1  mrg     mpz_set_ui (z, 0L); _mpz_realloc (z, 1)
   1394      1.1  mrg #define x_mpq_shrink(q) \
   1395      1.1  mrg     x_mpz_shrink (mpq_numref(q)); x_mpz_shrink (mpq_denref(q))
   1396      1.1  mrg 
   1397      1.1  mrg     x_mpz_shrink (tmp_mpz_0);
   1398      1.1  mrg     x_mpz_shrink (tmp_mpz_1);
   1399      1.1  mrg     x_mpz_shrink (tmp_mpz_2);
   1400      1.1  mrg     x_mpq_shrink (tmp_mpq_0);
   1401      1.1  mrg     x_mpq_shrink (tmp_mpq_1);
   1402      1.1  mrg     tmp_mpf_shrink (tmp_mpf_0);
   1403      1.1  mrg     tmp_mpf_shrink (tmp_mpf_1);
   1404      1.1  mrg 
   1405      1.1  mrg 
   1406      1.1  mrg 
   1407      1.1  mrg malloced_string
   1408      1.1  mrg sprintf_internal (fmt, sv)
   1409      1.1  mrg     const_string fmt
   1410      1.1  mrg     SV           *sv
   1411      1.1  mrg CODE:
   1412      1.1  mrg     assert (strlen (fmt) >= 3);
   1413      1.1  mrg     assert (SvROK(sv));
   1414      1.1  mrg     assert ((sv_derived_from (sv, mpz_class)    && fmt[strlen(fmt)-2] == 'Z')
   1415      1.1  mrg             || (sv_derived_from (sv, mpq_class) && fmt[strlen(fmt)-2] == 'Q')
   1416      1.1  mrg             || (sv_derived_from (sv, mpf_class) && fmt[strlen(fmt)-2] == 'F'));
   1417      1.1  mrg     TRACE (printf ("GMP::sprintf_internal\n");
   1418      1.1  mrg            printf ("  fmt  |%s|\n", fmt);
   1419      1.1  mrg            printf ("  sv   |%p|\n", SvMPZ(sv)));
   1420      1.1  mrg 
   1421      1.1  mrg     /* cheat a bit here, SvMPZ works for mpq and mpf too */
   1422      1.1  mrg     gmp_asprintf (&RETVAL, fmt, SvMPZ(sv));
   1423      1.1  mrg 
   1424      1.1  mrg     TRACE (printf ("  result |%s|\n", RETVAL));
   1425      1.1  mrg OUTPUT:
   1426      1.1  mrg     RETVAL
   1427      1.1  mrg 
   1428      1.1  mrg 
   1429      1.1  mrg 
   1430      1.1  mrg #------------------------------------------------------------------------------
   1431      1.1  mrg 
   1432      1.1  mrg MODULE = GMP         PACKAGE = GMP::Mpz
   1433      1.1  mrg 
   1434      1.1  mrg mpz
   1435      1.1  mrg mpz (...)
   1436      1.1  mrg ALIAS:
   1437      1.1  mrg     GMP::Mpz::new = 1
   1438      1.1  mrg PREINIT:
   1439      1.1  mrg     SV *sv;
   1440      1.1  mrg CODE:
   1441      1.1  mrg     TRACE (printf ("%s new, ix=%ld, items=%d\n", mpz_class, ix, (int) items));
   1442      1.1  mrg     RETVAL = new_mpz();
   1443      1.1  mrg 
   1444      1.1  mrg     switch (items) {
   1445      1.1  mrg     case 0:
   1446      1.1  mrg       mpz_set_ui (RETVAL->m, 0L);
   1447      1.1  mrg       break;
   1448      1.1  mrg 
   1449      1.1  mrg     case 1:
   1450      1.1  mrg       sv = ST(0);
   1451      1.1  mrg       TRACE (printf ("  use %d\n", use_sv (sv)));
   1452      1.1  mrg       switch (use_sv (sv)) {
   1453      1.1  mrg       case USE_IVX:
   1454      1.1  mrg         mpz_set_si (RETVAL->m, SvIVX(sv));
   1455      1.1  mrg         break;
   1456      1.1  mrg 
   1457      1.1  mrg       case USE_UVX:
   1458      1.1  mrg         mpz_set_ui (RETVAL->m, SvUVX(sv));
   1459      1.1  mrg         break;
   1460      1.1  mrg 
   1461      1.1  mrg       case USE_NVX:
   1462      1.1  mrg         mpz_set_d (RETVAL->m, SvNVX(sv));
   1463      1.1  mrg         break;
   1464      1.1  mrg 
   1465      1.1  mrg       case USE_PVX:
   1466      1.1  mrg         my_mpz_set_svstr (RETVAL->m, sv);
   1467      1.1  mrg         break;
   1468      1.1  mrg 
   1469      1.1  mrg       case USE_MPZ:
   1470      1.1  mrg         mpz_set (RETVAL->m, SvMPZ(sv)->m);
   1471      1.1  mrg         break;
   1472      1.1  mrg 
   1473      1.1  mrg       case USE_MPQ:
   1474      1.1  mrg         mpz_set_q (RETVAL->m, SvMPQ(sv)->m);
   1475      1.1  mrg         break;
   1476      1.1  mrg 
   1477      1.1  mrg       case USE_MPF:
   1478      1.1  mrg         mpz_set_f (RETVAL->m, SvMPF(sv));
   1479      1.1  mrg         break;
   1480      1.1  mrg 
   1481      1.1  mrg       default:
   1482      1.1  mrg         goto invalid;
   1483      1.1  mrg       }
   1484      1.1  mrg       break;
   1485      1.1  mrg 
   1486      1.1  mrg     default:
   1487      1.1  mrg     invalid:
   1488      1.1  mrg       croak ("%s new: invalid arguments", mpz_class);
   1489      1.1  mrg     }
   1490      1.1  mrg OUTPUT:
   1491      1.1  mrg     RETVAL
   1492      1.1  mrg 
   1493      1.1  mrg 
   1494      1.1  mrg void
   1495      1.1  mrg overload_constant (str, pv, d1, ...)
   1496      1.1  mrg     const_string_assume str
   1497      1.1  mrg     SV                  *pv
   1498      1.1  mrg     dummy               d1
   1499      1.1  mrg PREINIT:
   1500      1.1  mrg     mpz z;
   1501      1.1  mrg PPCODE:
   1502      1.1  mrg     TRACE (printf ("%s constant: %s\n", mpz_class, str));
   1503      1.1  mrg     z = new_mpz();
   1504      1.1  mrg     if (mpz_set_str (z->m, str, 0) == 0)
   1505      1.1  mrg       {
   1506      1.1  mrg         PUSHs (MPX_NEWMORTAL (z, mpz_class_hv));
   1507      1.1  mrg       }
   1508      1.1  mrg     else
   1509      1.1  mrg       {
   1510      1.1  mrg         free_mpz (z);
   1511      1.1  mrg         PUSHs(pv);
   1512      1.1  mrg       }
   1513      1.1  mrg 
   1514      1.1  mrg 
   1515      1.1  mrg mpz
   1516      1.1  mrg overload_copy (z, d1, d2)
   1517      1.1  mrg     mpz_assume z
   1518      1.1  mrg     dummy      d1
   1519      1.1  mrg     dummy      d2
   1520      1.1  mrg CODE:
   1521      1.1  mrg     RETVAL = new_mpz();
   1522      1.1  mrg     mpz_set (RETVAL->m, z->m);
   1523      1.1  mrg OUTPUT:
   1524      1.1  mrg     RETVAL
   1525      1.1  mrg 
   1526      1.1  mrg 
   1527      1.1  mrg void
   1528      1.1  mrg DESTROY (z)
   1529      1.1  mrg     mpz_assume z
   1530      1.1  mrg CODE:
   1531      1.1  mrg     TRACE (printf ("%s DESTROY %p\n", mpz_class, z));
   1532      1.1  mrg     free_mpz (z);
   1533      1.1  mrg 
   1534      1.1  mrg 
   1535      1.1  mrg malloced_string
   1536      1.1  mrg overload_string (z, d1, d2)
   1537      1.1  mrg     mpz_assume z
   1538      1.1  mrg     dummy      d1
   1539      1.1  mrg     dummy      d2
   1540      1.1  mrg CODE:
   1541      1.1  mrg     TRACE (printf ("%s overload_string %p\n", mpz_class, z));
   1542      1.1  mrg     RETVAL = mpz_get_str (NULL, 10, z->m);
   1543      1.1  mrg OUTPUT:
   1544      1.1  mrg     RETVAL
   1545      1.1  mrg 
   1546      1.1  mrg 
   1547      1.1  mrg mpz
   1548      1.1  mrg overload_add (xv, yv, order)
   1549      1.1  mrg     SV *xv
   1550      1.1  mrg     SV *yv
   1551      1.1  mrg     SV *order
   1552      1.1  mrg ALIAS:
   1553      1.1  mrg     GMP::Mpz::overload_sub = 1
   1554      1.1  mrg     GMP::Mpz::overload_mul = 2
   1555      1.1  mrg     GMP::Mpz::overload_div = 3
   1556      1.1  mrg     GMP::Mpz::overload_rem = 4
   1557      1.1  mrg     GMP::Mpz::overload_and = 5
   1558      1.1  mrg     GMP::Mpz::overload_ior = 6
   1559      1.1  mrg     GMP::Mpz::overload_xor = 7
   1560      1.1  mrg PREINIT:
   1561      1.1  mrg     static_functable const struct {
   1562      1.1  mrg       void (*op) (mpz_ptr, mpz_srcptr, mpz_srcptr);
   1563      1.1  mrg     } table[] = {
   1564      1.1  mrg       { mpz_add    }, /* 0 */
   1565      1.1  mrg       { mpz_sub    }, /* 1 */
   1566      1.1  mrg       { mpz_mul    }, /* 2 */
   1567      1.1  mrg       { mpz_tdiv_q }, /* 3 */
   1568      1.1  mrg       { mpz_tdiv_r }, /* 4 */
   1569      1.1  mrg       { mpz_and    }, /* 5 */
   1570      1.1  mrg       { mpz_ior    }, /* 6 */
   1571      1.1  mrg       { mpz_xor    }, /* 7 */
   1572      1.1  mrg     };
   1573      1.1  mrg CODE:
   1574      1.1  mrg     assert_table (ix);
   1575      1.1  mrg     if (order == &PL_sv_yes)
   1576      1.1  mrg       SV_PTR_SWAP (xv, yv);
   1577      1.1  mrg     RETVAL = new_mpz();
   1578      1.1  mrg     (*table[ix].op) (RETVAL->m,
   1579      1.1  mrg                      coerce_mpz (tmp_mpz_0, xv),
   1580      1.1  mrg                      coerce_mpz (tmp_mpz_1, yv));
   1581      1.1  mrg OUTPUT:
   1582      1.1  mrg     RETVAL
   1583      1.1  mrg 
   1584      1.1  mrg 
   1585      1.1  mrg void
   1586      1.1  mrg overload_addeq (x, y, o)
   1587      1.1  mrg     mpz_assume   x
   1588      1.1  mrg     mpz_coerce   y
   1589      1.1  mrg     order_noswap o
   1590      1.1  mrg ALIAS:
   1591      1.1  mrg     GMP::Mpz::overload_subeq = 1
   1592      1.1  mrg     GMP::Mpz::overload_muleq = 2
   1593      1.1  mrg     GMP::Mpz::overload_diveq = 3
   1594      1.1  mrg     GMP::Mpz::overload_remeq = 4
   1595      1.1  mrg     GMP::Mpz::overload_andeq = 5
   1596      1.1  mrg     GMP::Mpz::overload_ioreq = 6
   1597      1.1  mrg     GMP::Mpz::overload_xoreq = 7
   1598      1.1  mrg PREINIT:
   1599      1.1  mrg     static_functable const struct {
   1600      1.1  mrg       void (*op) (mpz_ptr, mpz_srcptr, mpz_srcptr);
   1601      1.1  mrg     } table[] = {
   1602      1.1  mrg       { mpz_add    }, /* 0 */
   1603      1.1  mrg       { mpz_sub    }, /* 1 */
   1604      1.1  mrg       { mpz_mul    }, /* 2 */
   1605      1.1  mrg       { mpz_tdiv_q }, /* 3 */
   1606      1.1  mrg       { mpz_tdiv_r }, /* 4 */
   1607      1.1  mrg       { mpz_and    }, /* 5 */
   1608      1.1  mrg       { mpz_ior    }, /* 6 */
   1609      1.1  mrg       { mpz_xor    }, /* 7 */
   1610      1.1  mrg     };
   1611      1.1  mrg PPCODE:
   1612      1.1  mrg     assert_table (ix);
   1613      1.1  mrg     (*table[ix].op) (x->m, x->m, y);
   1614      1.1  mrg     XPUSHs (ST(0));
   1615      1.1  mrg 
   1616      1.1  mrg 
   1617      1.1  mrg mpz
   1618      1.1  mrg overload_lshift (zv, nv, order)
   1619      1.1  mrg     SV *zv
   1620      1.1  mrg     SV *nv
   1621      1.1  mrg     SV *order
   1622      1.1  mrg ALIAS:
   1623      1.1  mrg     GMP::Mpz::overload_rshift   = 1
   1624      1.1  mrg     GMP::Mpz::overload_pow      = 2
   1625      1.1  mrg PREINIT:
   1626      1.1  mrg     static_functable const struct {
   1627      1.1  mrg       void (*op) (mpz_ptr, mpz_srcptr, unsigned long);
   1628      1.1  mrg     } table[] = {
   1629      1.1  mrg       { mpz_mul_2exp }, /* 0 */
   1630  1.1.1.2  mrg       { mpz_fdiv_q_2exp }, /* 1 */
   1631      1.1  mrg       { mpz_pow_ui   }, /* 2 */
   1632      1.1  mrg     };
   1633      1.1  mrg CODE:
   1634      1.1  mrg     assert_table (ix);
   1635      1.1  mrg     if (order == &PL_sv_yes)
   1636      1.1  mrg       SV_PTR_SWAP (zv, nv);
   1637      1.1  mrg     RETVAL = new_mpz();
   1638      1.1  mrg     (*table[ix].op) (RETVAL->m, coerce_mpz (RETVAL->m, zv), coerce_ulong (nv));
   1639      1.1  mrg OUTPUT:
   1640      1.1  mrg     RETVAL
   1641      1.1  mrg 
   1642      1.1  mrg 
   1643      1.1  mrg void
   1644      1.1  mrg overload_lshifteq (z, n, o)
   1645      1.1  mrg     mpz_assume   z
   1646      1.1  mrg     ulong_coerce n
   1647      1.1  mrg     order_noswap o
   1648      1.1  mrg ALIAS:
   1649      1.1  mrg     GMP::Mpz::overload_rshifteq   = 1
   1650      1.1  mrg     GMP::Mpz::overload_poweq      = 2
   1651      1.1  mrg PREINIT:
   1652      1.1  mrg     static_functable const struct {
   1653      1.1  mrg       void (*op) (mpz_ptr, mpz_srcptr, unsigned long);
   1654      1.1  mrg     } table[] = {
   1655      1.1  mrg       { mpz_mul_2exp }, /* 0 */
   1656  1.1.1.2  mrg       { mpz_fdiv_q_2exp }, /* 1 */
   1657      1.1  mrg       { mpz_pow_ui   }, /* 2 */
   1658      1.1  mrg     };
   1659      1.1  mrg PPCODE:
   1660      1.1  mrg     assert_table (ix);
   1661      1.1  mrg     (*table[ix].op) (z->m, z->m, n);
   1662      1.1  mrg     XPUSHs(ST(0));
   1663      1.1  mrg 
   1664      1.1  mrg 
   1665      1.1  mrg mpz
   1666      1.1  mrg overload_abs (z, d1, d2)
   1667      1.1  mrg     mpz_assume z
   1668      1.1  mrg     dummy      d1
   1669      1.1  mrg     dummy      d2
   1670      1.1  mrg ALIAS:
   1671      1.1  mrg     GMP::Mpz::overload_neg  = 1
   1672      1.1  mrg     GMP::Mpz::overload_com  = 2
   1673      1.1  mrg     GMP::Mpz::overload_sqrt = 3
   1674      1.1  mrg PREINIT:
   1675      1.1  mrg     static_functable const struct {
   1676      1.1  mrg       void (*op) (mpz_ptr w, mpz_srcptr x);
   1677      1.1  mrg     } table[] = {
   1678      1.1  mrg       { mpz_abs  }, /* 0 */
   1679      1.1  mrg       { mpz_neg  }, /* 1 */
   1680      1.1  mrg       { mpz_com  }, /* 2 */
   1681      1.1  mrg       { mpz_sqrt }, /* 3 */
   1682      1.1  mrg     };
   1683      1.1  mrg CODE:
   1684      1.1  mrg     assert_table (ix);
   1685      1.1  mrg     RETVAL = new_mpz();
   1686      1.1  mrg     (*table[ix].op) (RETVAL->m, z->m);
   1687      1.1  mrg OUTPUT:
   1688      1.1  mrg     RETVAL
   1689      1.1  mrg 
   1690      1.1  mrg 
   1691      1.1  mrg void
   1692      1.1  mrg overload_inc (z, d1, d2)
   1693      1.1  mrg     mpz_assume z
   1694      1.1  mrg     dummy      d1
   1695      1.1  mrg     dummy      d2
   1696      1.1  mrg ALIAS:
   1697      1.1  mrg     GMP::Mpz::overload_dec = 1
   1698      1.1  mrg PREINIT:
   1699      1.1  mrg     static_functable const struct {
   1700      1.1  mrg       void (*op) (mpz_ptr w, mpz_srcptr x, unsigned long y);
   1701      1.1  mrg     } table[] = {
   1702      1.1  mrg       { mpz_add_ui }, /* 0 */
   1703      1.1  mrg       { mpz_sub_ui }, /* 1 */
   1704      1.1  mrg     };
   1705      1.1  mrg CODE:
   1706      1.1  mrg     assert_table (ix);
   1707      1.1  mrg     (*table[ix].op) (z->m, z->m, 1L);
   1708      1.1  mrg 
   1709      1.1  mrg 
   1710      1.1  mrg int
   1711      1.1  mrg overload_spaceship (xv, yv, order)
   1712      1.1  mrg     SV *xv
   1713      1.1  mrg     SV *yv
   1714      1.1  mrg     SV *order
   1715      1.1  mrg PREINIT:
   1716      1.1  mrg     mpz x;
   1717      1.1  mrg CODE:
   1718      1.1  mrg     TRACE (printf ("%s overload_spaceship\n", mpz_class));
   1719      1.1  mrg     MPZ_ASSUME (x, xv);
   1720      1.1  mrg     switch (use_sv (yv)) {
   1721      1.1  mrg     case USE_IVX:
   1722      1.1  mrg       RETVAL = mpz_cmp_si (x->m, SvIVX(yv));
   1723      1.1  mrg       break;
   1724      1.1  mrg     case USE_UVX:
   1725      1.1  mrg       RETVAL = mpz_cmp_ui (x->m, SvUVX(yv));
   1726      1.1  mrg       break;
   1727      1.1  mrg     case USE_PVX:
   1728      1.1  mrg       RETVAL = mpz_cmp (x->m, coerce_mpz (tmp_mpz_0, yv));
   1729      1.1  mrg       break;
   1730      1.1  mrg     case USE_NVX:
   1731      1.1  mrg       RETVAL = mpz_cmp_d (x->m, SvNVX(yv));
   1732      1.1  mrg       break;
   1733      1.1  mrg     case USE_MPZ:
   1734      1.1  mrg       RETVAL = mpz_cmp (x->m, SvMPZ(yv)->m);
   1735      1.1  mrg       break;
   1736      1.1  mrg     case USE_MPQ:
   1737      1.1  mrg       RETVAL = x_mpz_cmp_q (x->m, SvMPQ(yv)->m);
   1738      1.1  mrg       break;
   1739      1.1  mrg     case USE_MPF:
   1740      1.1  mrg       RETVAL = x_mpz_cmp_f (x->m, SvMPF(yv));
   1741      1.1  mrg       break;
   1742      1.1  mrg     default:
   1743      1.1  mrg       croak ("%s <=>: invalid operand", mpz_class);
   1744      1.1  mrg     }
   1745      1.1  mrg     RETVAL = SGN (RETVAL);
   1746      1.1  mrg     if (order == &PL_sv_yes)
   1747      1.1  mrg       RETVAL = -RETVAL;
   1748      1.1  mrg OUTPUT:
   1749      1.1  mrg     RETVAL
   1750      1.1  mrg 
   1751      1.1  mrg 
   1752      1.1  mrg bool
   1753      1.1  mrg overload_bool (z, d1, d2)
   1754      1.1  mrg     mpz_assume z
   1755      1.1  mrg     dummy      d1
   1756      1.1  mrg     dummy      d2
   1757      1.1  mrg ALIAS:
   1758      1.1  mrg     GMP::Mpz::overload_not = 1
   1759      1.1  mrg CODE:
   1760      1.1  mrg     RETVAL = (mpz_sgn (z->m) != 0) ^ ix;
   1761      1.1  mrg OUTPUT:
   1762      1.1  mrg     RETVAL
   1763      1.1  mrg 
   1764      1.1  mrg 
   1765      1.1  mrg mpz
   1766      1.1  mrg bin (n, k)
   1767      1.1  mrg     mpz_coerce   n
   1768      1.1  mrg     ulong_coerce k
   1769      1.1  mrg ALIAS:
   1770      1.1  mrg     GMP::Mpz::root = 1
   1771      1.1  mrg PREINIT:
   1772      1.1  mrg     /* mpz_root returns an int, hence the cast */
   1773      1.1  mrg     static_functable const struct {
   1774      1.1  mrg       void (*op) (mpz_ptr, mpz_srcptr, unsigned long);
   1775      1.1  mrg     } table[] = {
   1776      1.1  mrg       {                                                mpz_bin_ui }, /* 0 */
   1777      1.1  mrg       { (void (*)(mpz_ptr, mpz_srcptr, unsigned long)) mpz_root   }, /* 1 */
   1778      1.1  mrg     };
   1779      1.1  mrg CODE:
   1780      1.1  mrg     assert_table (ix);
   1781      1.1  mrg     RETVAL = new_mpz();
   1782      1.1  mrg     (*table[ix].op) (RETVAL->m, n, k);
   1783      1.1  mrg OUTPUT:
   1784      1.1  mrg     RETVAL
   1785      1.1  mrg 
   1786      1.1  mrg 
   1787      1.1  mrg void
   1788      1.1  mrg cdiv (a, d)
   1789      1.1  mrg     mpz_coerce a
   1790      1.1  mrg     mpz_coerce d
   1791      1.1  mrg ALIAS:
   1792      1.1  mrg     GMP::Mpz::fdiv = 1
   1793      1.1  mrg     GMP::Mpz::tdiv = 2
   1794      1.1  mrg PREINIT:
   1795      1.1  mrg     static_functable const struct {
   1796      1.1  mrg       void (*op) (mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr);
   1797      1.1  mrg     } table[] = {
   1798      1.1  mrg       { mpz_cdiv_qr }, /* 0 */
   1799      1.1  mrg       { mpz_fdiv_qr }, /* 1 */
   1800      1.1  mrg       { mpz_tdiv_qr }, /* 2 */
   1801      1.1  mrg     };
   1802      1.1  mrg     mpz q, r;
   1803      1.1  mrg PPCODE:
   1804      1.1  mrg     assert_table (ix);
   1805      1.1  mrg     q = new_mpz();
   1806      1.1  mrg     r = new_mpz();
   1807      1.1  mrg     (*table[ix].op) (q->m, r->m, a, d);
   1808      1.1  mrg     EXTEND (SP, 2);
   1809      1.1  mrg     PUSHs (MPX_NEWMORTAL (q, mpz_class_hv));
   1810      1.1  mrg     PUSHs (MPX_NEWMORTAL (r, mpz_class_hv));
   1811      1.1  mrg 
   1812      1.1  mrg 
   1813      1.1  mrg void
   1814      1.1  mrg cdiv_2exp (a, d)
   1815      1.1  mrg     mpz_coerce   a
   1816      1.1  mrg     ulong_coerce d
   1817      1.1  mrg ALIAS:
   1818      1.1  mrg     GMP::Mpz::fdiv_2exp = 1
   1819      1.1  mrg     GMP::Mpz::tdiv_2exp = 2
   1820      1.1  mrg PREINIT:
   1821      1.1  mrg     static_functable const struct {
   1822      1.1  mrg       void (*q) (mpz_ptr, mpz_srcptr, unsigned long);
   1823      1.1  mrg       void (*r) (mpz_ptr, mpz_srcptr, unsigned long);
   1824      1.1  mrg     } table[] = {
   1825      1.1  mrg       { mpz_cdiv_q_2exp, mpz_cdiv_r_2exp }, /* 0 */
   1826      1.1  mrg       { mpz_fdiv_q_2exp, mpz_fdiv_r_2exp }, /* 1 */
   1827      1.1  mrg       { mpz_tdiv_q_2exp, mpz_tdiv_r_2exp }, /* 2 */
   1828      1.1  mrg     };
   1829      1.1  mrg     mpz q, r;
   1830      1.1  mrg PPCODE:
   1831      1.1  mrg     assert_table (ix);
   1832      1.1  mrg     q = new_mpz();
   1833      1.1  mrg     r = new_mpz();
   1834      1.1  mrg     (*table[ix].q) (q->m, a, d);
   1835      1.1  mrg     (*table[ix].r) (r->m, a, d);
   1836      1.1  mrg     EXTEND (SP, 2);
   1837      1.1  mrg     PUSHs (MPX_NEWMORTAL (q, mpz_class_hv));
   1838      1.1  mrg     PUSHs (MPX_NEWMORTAL (r, mpz_class_hv));
   1839      1.1  mrg 
   1840      1.1  mrg 
   1841      1.1  mrg bool
   1842      1.1  mrg congruent_p (a, c, d)
   1843      1.1  mrg     mpz_coerce a
   1844      1.1  mrg     mpz_coerce c
   1845      1.1  mrg     mpz_coerce d
   1846      1.1  mrg PREINIT:
   1847      1.1  mrg CODE:
   1848      1.1  mrg     RETVAL = mpz_congruent_p (a, c, d);
   1849      1.1  mrg OUTPUT:
   1850      1.1  mrg     RETVAL
   1851      1.1  mrg 
   1852      1.1  mrg 
   1853      1.1  mrg bool
   1854      1.1  mrg congruent_2exp_p (a, c, d)
   1855      1.1  mrg     mpz_coerce   a
   1856      1.1  mrg     mpz_coerce   c
   1857      1.1  mrg     ulong_coerce d
   1858      1.1  mrg PREINIT:
   1859      1.1  mrg CODE:
   1860      1.1  mrg     RETVAL = mpz_congruent_2exp_p (a, c, d);
   1861      1.1  mrg OUTPUT:
   1862      1.1  mrg     RETVAL
   1863      1.1  mrg 
   1864      1.1  mrg 
   1865      1.1  mrg mpz
   1866      1.1  mrg divexact (a, d)
   1867      1.1  mrg     mpz_coerce a
   1868      1.1  mrg     mpz_coerce d
   1869      1.1  mrg ALIAS:
   1870      1.1  mrg     GMP::Mpz::mod = 1
   1871      1.1  mrg PREINIT:
   1872      1.1  mrg     static_functable const struct {
   1873      1.1  mrg       void (*op) (mpz_ptr, mpz_srcptr, mpz_srcptr);
   1874      1.1  mrg     } table[] = {
   1875      1.1  mrg       { mpz_divexact }, /* 0 */
   1876      1.1  mrg       { mpz_mod      }, /* 1 */
   1877      1.1  mrg     };
   1878      1.1  mrg CODE:
   1879      1.1  mrg     assert_table (ix);
   1880      1.1  mrg     RETVAL = new_mpz();
   1881      1.1  mrg     (*table[ix].op) (RETVAL->m, a, d);
   1882      1.1  mrg OUTPUT:
   1883      1.1  mrg     RETVAL
   1884      1.1  mrg 
   1885      1.1  mrg 
   1886      1.1  mrg bool
   1887      1.1  mrg divisible_p (a, d)
   1888      1.1  mrg     mpz_coerce a
   1889      1.1  mrg     mpz_coerce d
   1890      1.1  mrg CODE:
   1891      1.1  mrg     RETVAL = mpz_divisible_p (a, d);
   1892      1.1  mrg OUTPUT:
   1893      1.1  mrg     RETVAL
   1894      1.1  mrg 
   1895      1.1  mrg 
   1896      1.1  mrg bool
   1897      1.1  mrg divisible_2exp_p (a, d)
   1898      1.1  mrg     mpz_coerce   a
   1899      1.1  mrg     ulong_coerce d
   1900      1.1  mrg CODE:
   1901      1.1  mrg     RETVAL = mpz_divisible_2exp_p (a, d);
   1902      1.1  mrg OUTPUT:
   1903      1.1  mrg     RETVAL
   1904      1.1  mrg 
   1905      1.1  mrg 
   1906      1.1  mrg bool
   1907      1.1  mrg even_p (z)
   1908      1.1  mrg     mpz_coerce z
   1909      1.1  mrg ALIAS:
   1910      1.1  mrg     GMP::Mpz::odd_p            = 1
   1911      1.1  mrg     GMP::Mpz::perfect_square_p = 2
   1912      1.1  mrg     GMP::Mpz::perfect_power_p  = 3
   1913      1.1  mrg PREINIT:
   1914      1.1  mrg     static_functable const struct {
   1915      1.1  mrg       int (*op) (mpz_srcptr z);
   1916      1.1  mrg     } table[] = {
   1917      1.1  mrg       { x_mpz_even_p         }, /* 0 */
   1918      1.1  mrg       { x_mpz_odd_p          }, /* 1 */
   1919      1.1  mrg       { mpz_perfect_square_p }, /* 2 */
   1920      1.1  mrg       { mpz_perfect_power_p  }, /* 3 */
   1921      1.1  mrg     };
   1922      1.1  mrg CODE:
   1923      1.1  mrg     assert_table (ix);
   1924      1.1  mrg     RETVAL = (*table[ix].op) (z);
   1925      1.1  mrg OUTPUT:
   1926      1.1  mrg     RETVAL
   1927      1.1  mrg 
   1928      1.1  mrg 
   1929      1.1  mrg mpz
   1930      1.1  mrg fac (n)
   1931      1.1  mrg     ulong_coerce n
   1932      1.1  mrg ALIAS:
   1933      1.1  mrg     GMP::Mpz::fib    = 1
   1934      1.1  mrg     GMP::Mpz::lucnum = 2
   1935      1.1  mrg PREINIT:
   1936      1.1  mrg     static_functable const struct {
   1937      1.1  mrg       void (*op) (mpz_ptr r, unsigned long n);
   1938      1.1  mrg     } table[] = {
   1939      1.1  mrg       { mpz_fac_ui },    /* 0 */
   1940      1.1  mrg       { mpz_fib_ui },    /* 1 */
   1941      1.1  mrg       { mpz_lucnum_ui }, /* 2 */
   1942      1.1  mrg     };
   1943      1.1  mrg CODE:
   1944      1.1  mrg     assert_table (ix);
   1945      1.1  mrg     RETVAL = new_mpz();
   1946      1.1  mrg     (*table[ix].op) (RETVAL->m, n);
   1947      1.1  mrg OUTPUT:
   1948      1.1  mrg     RETVAL
   1949      1.1  mrg 
   1950      1.1  mrg 
   1951      1.1  mrg void
   1952      1.1  mrg fib2 (n)
   1953      1.1  mrg     ulong_coerce n
   1954      1.1  mrg ALIAS:
   1955      1.1  mrg     GMP::Mpz::lucnum2 = 1
   1956      1.1  mrg PREINIT:
   1957      1.1  mrg     static_functable const struct {
   1958      1.1  mrg       void (*op) (mpz_ptr r, mpz_ptr r2, unsigned long n);
   1959      1.1  mrg     } table[] = {
   1960      1.1  mrg       { mpz_fib2_ui },    /* 0 */
   1961      1.1  mrg       { mpz_lucnum2_ui }, /* 1 */
   1962      1.1  mrg     };
   1963      1.1  mrg     mpz  r, r2;
   1964      1.1  mrg PPCODE:
   1965      1.1  mrg     assert_table (ix);
   1966      1.1  mrg     r = new_mpz();
   1967      1.1  mrg     r2 = new_mpz();
   1968      1.1  mrg     (*table[ix].op) (r->m, r2->m, n);
   1969      1.1  mrg     EXTEND (SP, 2);
   1970      1.1  mrg     PUSHs (MPX_NEWMORTAL (r,  mpz_class_hv));
   1971      1.1  mrg     PUSHs (MPX_NEWMORTAL (r2, mpz_class_hv));
   1972      1.1  mrg 
   1973      1.1  mrg 
   1974      1.1  mrg mpz
   1975      1.1  mrg gcd (x, ...)
   1976      1.1  mrg     mpz_coerce x
   1977      1.1  mrg ALIAS:
   1978      1.1  mrg     GMP::Mpz::lcm = 1
   1979      1.1  mrg PREINIT:
   1980      1.1  mrg     static_functable const struct {
   1981      1.1  mrg       void (*op) (mpz_ptr w, mpz_srcptr x, mpz_srcptr y);
   1982      1.1  mrg       void (*op_ui) (mpz_ptr w, mpz_srcptr x, unsigned long y);
   1983      1.1  mrg     } table[] = {
   1984      1.1  mrg       /* cast to ignore ulong return from mpz_gcd_ui */
   1985      1.1  mrg       { mpz_gcd,
   1986      1.1  mrg         (void (*) (mpz_ptr, mpz_srcptr, unsigned long)) mpz_gcd_ui }, /* 0 */
   1987      1.1  mrg       { mpz_lcm, mpz_lcm_ui },                                        /* 1 */
   1988      1.1  mrg     };
   1989      1.1  mrg     int  i;
   1990      1.1  mrg     SV   *yv;
   1991      1.1  mrg CODE:
   1992      1.1  mrg     assert_table (ix);
   1993      1.1  mrg     RETVAL = new_mpz();
   1994      1.1  mrg     if (items == 1)
   1995      1.1  mrg       mpz_set (RETVAL->m, x);
   1996      1.1  mrg     else
   1997      1.1  mrg       {
   1998      1.1  mrg         for (i = 1; i < items; i++)
   1999      1.1  mrg           {
   2000      1.1  mrg             yv = ST(i);
   2001      1.1  mrg             if (SvIOK(yv))
   2002      1.1  mrg               (*table[ix].op_ui) (RETVAL->m, x, ABS(SvIVX(yv)));
   2003      1.1  mrg             else
   2004      1.1  mrg               (*table[ix].op) (RETVAL->m, x, coerce_mpz (tmp_mpz_1, yv));
   2005      1.1  mrg             x = RETVAL->m;
   2006      1.1  mrg           }
   2007      1.1  mrg       }
   2008      1.1  mrg OUTPUT:
   2009      1.1  mrg     RETVAL
   2010      1.1  mrg 
   2011      1.1  mrg 
   2012      1.1  mrg void
   2013      1.1  mrg gcdext (a, b)
   2014      1.1  mrg     mpz_coerce a
   2015      1.1  mrg     mpz_coerce b
   2016      1.1  mrg PREINIT:
   2017      1.1  mrg     mpz g, x, y;
   2018      1.1  mrg     SV  *sv;
   2019      1.1  mrg PPCODE:
   2020      1.1  mrg     g = new_mpz();
   2021      1.1  mrg     x = new_mpz();
   2022      1.1  mrg     y = new_mpz();
   2023      1.1  mrg     mpz_gcdext (g->m, x->m, y->m, a, b);
   2024      1.1  mrg     EXTEND (SP, 3);
   2025      1.1  mrg     PUSHs (MPX_NEWMORTAL (g, mpz_class_hv));
   2026      1.1  mrg     PUSHs (MPX_NEWMORTAL (x, mpz_class_hv));
   2027      1.1  mrg     PUSHs (MPX_NEWMORTAL (y, mpz_class_hv));
   2028      1.1  mrg 
   2029      1.1  mrg 
   2030      1.1  mrg unsigned long
   2031      1.1  mrg hamdist (x, y)
   2032      1.1  mrg     mpz_coerce x
   2033      1.1  mrg     mpz_coerce y
   2034      1.1  mrg CODE:
   2035      1.1  mrg     RETVAL = mpz_hamdist (x, y);
   2036      1.1  mrg OUTPUT:
   2037      1.1  mrg     RETVAL
   2038      1.1  mrg 
   2039      1.1  mrg 
   2040      1.1  mrg mpz
   2041      1.1  mrg invert (a, m)
   2042      1.1  mrg     mpz_coerce a
   2043      1.1  mrg     mpz_coerce m
   2044      1.1  mrg CODE:
   2045      1.1  mrg     RETVAL = new_mpz();
   2046      1.1  mrg     if (! mpz_invert (RETVAL->m, a, m))
   2047      1.1  mrg       {
   2048      1.1  mrg         free_mpz (RETVAL);
   2049      1.1  mrg         XSRETURN_UNDEF;
   2050      1.1  mrg       }
   2051      1.1  mrg OUTPUT:
   2052      1.1  mrg     RETVAL
   2053      1.1  mrg 
   2054      1.1  mrg 
   2055      1.1  mrg int
   2056      1.1  mrg jacobi (a, b)
   2057      1.1  mrg     mpz_coerce a
   2058      1.1  mrg     mpz_coerce b
   2059      1.1  mrg CODE:
   2060      1.1  mrg     RETVAL = mpz_jacobi (a, b);
   2061      1.1  mrg OUTPUT:
   2062      1.1  mrg     RETVAL
   2063      1.1  mrg 
   2064      1.1  mrg 
   2065      1.1  mrg int
   2066      1.1  mrg kronecker (a, b)
   2067      1.1  mrg     SV *a
   2068      1.1  mrg     SV *b
   2069      1.1  mrg CODE:
   2070      1.1  mrg     if (SvIOK(b))
   2071      1.1  mrg       RETVAL = mpz_kronecker_si (coerce_mpz(tmp_mpz_0,a), SvIVX(b));
   2072      1.1  mrg     else if (SvIOK(a))
   2073      1.1  mrg       RETVAL = mpz_si_kronecker (SvIVX(a), coerce_mpz(tmp_mpz_0,b));
   2074      1.1  mrg     else
   2075      1.1  mrg       RETVAL = mpz_kronecker (coerce_mpz(tmp_mpz_0,a),
   2076      1.1  mrg                               coerce_mpz(tmp_mpz_1,b));
   2077      1.1  mrg OUTPUT:
   2078      1.1  mrg     RETVAL
   2079      1.1  mrg 
   2080      1.1  mrg 
   2081      1.1  mrg void
   2082      1.1  mrg mpz_export (order, size, endian, nails, z)
   2083      1.1  mrg     int        order
   2084      1.1  mrg     size_t     size
   2085      1.1  mrg     int        endian
   2086      1.1  mrg     size_t     nails
   2087      1.1  mrg     mpz_coerce z
   2088      1.1  mrg PREINIT:
   2089      1.1  mrg     size_t  numb, count, bytes, actual_count;
   2090      1.1  mrg     char    *data;
   2091      1.1  mrg     SV      *sv;
   2092      1.1  mrg PPCODE:
   2093      1.1  mrg     numb = 8*size - nails;
   2094      1.1  mrg     count = (mpz_sizeinbase (z, 2) + numb-1) / numb;
   2095      1.1  mrg     bytes = count * size;
   2096      1.1  mrg     New (GMP_MALLOC_ID, data, bytes+1, char);
   2097      1.1  mrg     mpz_export (data, &actual_count, order, size, endian, nails, z);
   2098      1.1  mrg     assert (count == actual_count);
   2099      1.1  mrg     data[bytes] = '\0';
   2100      1.1  mrg     sv = sv_newmortal(); sv_usepvn_mg (sv, data, bytes); PUSHs(sv);
   2101      1.1  mrg 
   2102      1.1  mrg 
   2103      1.1  mrg mpz
   2104      1.1  mrg mpz_import (order, size, endian, nails, sv)
   2105      1.1  mrg     int     order
   2106      1.1  mrg     size_t  size
   2107      1.1  mrg     int     endian
   2108      1.1  mrg     size_t  nails
   2109      1.1  mrg     SV      *sv
   2110      1.1  mrg PREINIT:
   2111      1.1  mrg     size_t      count;
   2112      1.1  mrg     const char  *data;
   2113      1.1  mrg     STRLEN      len;
   2114      1.1  mrg CODE:
   2115      1.1  mrg     data = SvPV (sv, len);
   2116      1.1  mrg     if ((len % size) != 0)
   2117      1.1  mrg       croak ("%s mpz_import: string not a multiple of the given size",
   2118      1.1  mrg              mpz_class);
   2119      1.1  mrg     count = len / size;
   2120      1.1  mrg     RETVAL = new_mpz();
   2121      1.1  mrg     mpz_import (RETVAL->m, count, order, size, endian, nails, data);
   2122      1.1  mrg OUTPUT:
   2123      1.1  mrg     RETVAL
   2124      1.1  mrg 
   2125      1.1  mrg 
   2126      1.1  mrg mpz
   2127      1.1  mrg nextprime (z)
   2128      1.1  mrg     mpz_coerce z
   2129      1.1  mrg CODE:
   2130      1.1  mrg     RETVAL = new_mpz();
   2131      1.1  mrg     mpz_nextprime (RETVAL->m, z);
   2132      1.1  mrg OUTPUT:
   2133      1.1  mrg     RETVAL
   2134      1.1  mrg 
   2135      1.1  mrg 
   2136      1.1  mrg unsigned long
   2137      1.1  mrg popcount (x)
   2138      1.1  mrg     mpz_coerce x
   2139      1.1  mrg CODE:
   2140      1.1  mrg     RETVAL = mpz_popcount (x);
   2141      1.1  mrg OUTPUT:
   2142      1.1  mrg     RETVAL
   2143      1.1  mrg 
   2144      1.1  mrg 
   2145      1.1  mrg mpz
   2146      1.1  mrg powm (b, e, m)
   2147      1.1  mrg     mpz_coerce b
   2148      1.1  mrg     mpz_coerce e
   2149      1.1  mrg     mpz_coerce m
   2150      1.1  mrg CODE:
   2151      1.1  mrg     RETVAL = new_mpz();
   2152      1.1  mrg     mpz_powm (RETVAL->m, b, e, m);
   2153      1.1  mrg OUTPUT:
   2154      1.1  mrg     RETVAL
   2155      1.1  mrg 
   2156      1.1  mrg 
   2157      1.1  mrg bool
   2158      1.1  mrg probab_prime_p (z, n)
   2159      1.1  mrg     mpz_coerce   z
   2160      1.1  mrg     ulong_coerce n
   2161      1.1  mrg CODE:
   2162      1.1  mrg     RETVAL = mpz_probab_prime_p (z, n);
   2163      1.1  mrg OUTPUT:
   2164      1.1  mrg     RETVAL
   2165      1.1  mrg 
   2166      1.1  mrg 
   2167      1.1  mrg # No attempt to coerce here, only an mpz makes sense.
   2168      1.1  mrg void
   2169      1.1  mrg realloc (z, limbs)
   2170      1.1  mrg     mpz z
   2171      1.1  mrg     int limbs
   2172      1.1  mrg CODE:
   2173      1.1  mrg     _mpz_realloc (z->m, limbs);
   2174      1.1  mrg 
   2175      1.1  mrg 
   2176      1.1  mrg void
   2177      1.1  mrg remove (z, f)
   2178      1.1  mrg     mpz_coerce z
   2179      1.1  mrg     mpz_coerce f
   2180      1.1  mrg PREINIT:
   2181      1.1  mrg     SV             *sv;
   2182      1.1  mrg     mpz            rem;
   2183      1.1  mrg     unsigned long  mult;
   2184      1.1  mrg PPCODE:
   2185      1.1  mrg     rem = new_mpz();
   2186      1.1  mrg     mult = mpz_remove (rem->m, z, f);
   2187      1.1  mrg     EXTEND (SP, 2);
   2188      1.1  mrg     PUSHs (MPX_NEWMORTAL (rem, mpz_class_hv));
   2189      1.1  mrg     PUSHs (sv_2mortal (newSViv (mult)));
   2190      1.1  mrg 
   2191      1.1  mrg 
   2192      1.1  mrg void
   2193      1.1  mrg roote (z, n)
   2194      1.1  mrg     mpz_coerce   z
   2195      1.1  mrg     ulong_coerce n
   2196      1.1  mrg PREINIT:
   2197      1.1  mrg     SV  *sv;
   2198      1.1  mrg     mpz root;
   2199      1.1  mrg     int exact;
   2200      1.1  mrg PPCODE:
   2201      1.1  mrg     root = new_mpz();
   2202      1.1  mrg     exact = mpz_root (root->m, z, n);
   2203      1.1  mrg     EXTEND (SP, 2);
   2204      1.1  mrg     PUSHs (MPX_NEWMORTAL (root, mpz_class_hv));
   2205      1.1  mrg     sv = (exact ? &PL_sv_yes : &PL_sv_no); sv_2mortal(sv); PUSHs(sv);
   2206      1.1  mrg 
   2207      1.1  mrg 
   2208      1.1  mrg void
   2209      1.1  mrg rootrem (z, n)
   2210      1.1  mrg     mpz_coerce   z
   2211      1.1  mrg     ulong_coerce n
   2212      1.1  mrg PREINIT:
   2213      1.1  mrg     SV  *sv;
   2214      1.1  mrg     mpz root;
   2215      1.1  mrg     mpz rem;
   2216      1.1  mrg PPCODE:
   2217      1.1  mrg     root = new_mpz();
   2218      1.1  mrg     rem = new_mpz();
   2219      1.1  mrg     mpz_rootrem (root->m, rem->m, z, n);
   2220      1.1  mrg     EXTEND (SP, 2);
   2221      1.1  mrg     PUSHs (MPX_NEWMORTAL (root, mpz_class_hv));
   2222      1.1  mrg     PUSHs (MPX_NEWMORTAL (rem,  mpz_class_hv));
   2223      1.1  mrg 
   2224      1.1  mrg 
   2225      1.1  mrg # In the past scan0 and scan1 were described as returning ULONG_MAX which
   2226      1.1  mrg # could be obtained in perl with ~0.  That wasn't true on 64-bit systems
   2227      1.1  mrg # (eg. alpha) with perl 5.005, since in that version IV and UV were still
   2228      1.1  mrg # 32-bits.
   2229      1.1  mrg #
   2230      1.1  mrg # We changed in gmp 4.2 to just say ~0 for the not-found return.  It's
   2231      1.1  mrg # likely most people have used ~0 rather than POSIX::ULONG_MAX(), so this
   2232      1.1  mrg # change should match existing usage.  It only actually makes a difference
   2233      1.1  mrg # in old perl, since recent versions have gone to 64-bits for IV and UV, the
   2234      1.1  mrg # same as a ulong.
   2235      1.1  mrg #
   2236      1.1  mrg # In perl 5.005 we explicitly mask the mpz return down to 32-bits to get ~0.
   2237      1.1  mrg # UV_MAX is no good, it reflects the size of the UV type (64-bits), rather
   2238      1.1  mrg # than the size of the values one ought to be storing in an SV (32-bits).
   2239      1.1  mrg 
   2240      1.1  mrg gmp_UV
   2241      1.1  mrg scan0 (z, start)
   2242      1.1  mrg     mpz_coerce   z
   2243      1.1  mrg     ulong_coerce start
   2244      1.1  mrg ALIAS:
   2245      1.1  mrg     GMP::Mpz::scan1 = 1
   2246      1.1  mrg PREINIT:
   2247      1.1  mrg     static_functable const struct {
   2248      1.1  mrg       unsigned long (*op) (mpz_srcptr, unsigned long);
   2249      1.1  mrg     } table[] = {
   2250      1.1  mrg       { mpz_scan0  }, /* 0 */
   2251      1.1  mrg       { mpz_scan1  }, /* 1 */
   2252      1.1  mrg     };
   2253      1.1  mrg CODE:
   2254      1.1  mrg     assert_table (ix);
   2255      1.1  mrg     RETVAL = (*table[ix].op) (z, start);
   2256      1.1  mrg     if (PERL_LT (5,6))
   2257      1.1  mrg       RETVAL &= 0xFFFFFFFF;
   2258      1.1  mrg OUTPUT:
   2259      1.1  mrg     RETVAL
   2260      1.1  mrg 
   2261      1.1  mrg 
   2262      1.1  mrg void
   2263      1.1  mrg setbit (sv, bit)
   2264      1.1  mrg     SV           *sv
   2265      1.1  mrg     ulong_coerce bit
   2266      1.1  mrg ALIAS:
   2267      1.1  mrg     GMP::Mpz::clrbit = 1
   2268      1.1  mrg     GMP::Mpz::combit = 2
   2269      1.1  mrg PREINIT:
   2270      1.1  mrg     static_functable const struct {
   2271      1.1  mrg       void (*op) (mpz_ptr, unsigned long);
   2272      1.1  mrg     } table[] = {
   2273      1.1  mrg       { mpz_setbit }, /* 0 */
   2274      1.1  mrg       { mpz_clrbit }, /* 1 */
   2275      1.1  mrg       { mpz_combit }, /* 2 */
   2276      1.1  mrg     };
   2277      1.1  mrg     int  use;
   2278      1.1  mrg     mpz  z;
   2279      1.1  mrg CODE:
   2280      1.1  mrg     use = use_sv (sv);
   2281      1.1  mrg     if (use == USE_MPZ && SvREFCNT(SvRV(sv)) == 1 && ! SvSMAGICAL(sv))
   2282      1.1  mrg       {
   2283      1.1  mrg         /* our operand is a non-magical mpz with a reference count of 1, so
   2284      1.1  mrg            we can just modify it */
   2285      1.1  mrg         (*table[ix].op) (SvMPZ(sv)->m, bit);
   2286      1.1  mrg       }
   2287      1.1  mrg     else
   2288      1.1  mrg       {
   2289      1.1  mrg         /* otherwise we need to make a new mpz, from whatever we have, and
   2290      1.1  mrg            operate on that, possibly invoking magic when storing back */
   2291      1.1  mrg         SV   *new_sv;
   2292      1.1  mrg         mpz  z = new_mpz ();
   2293      1.1  mrg         mpz_ptr  coerce_ptr = coerce_mpz_using (z->m, sv, use);
   2294      1.1  mrg         if (coerce_ptr != z->m)
   2295      1.1  mrg           mpz_set (z->m, coerce_ptr);
   2296      1.1  mrg         (*table[ix].op) (z->m, bit);
   2297      1.1  mrg         new_sv = sv_bless (sv_setref_pv (sv_newmortal(), NULL, z),
   2298      1.1  mrg                            mpz_class_hv);
   2299      1.1  mrg         SvSetMagicSV (sv, new_sv);
   2300      1.1  mrg       }
   2301      1.1  mrg 
   2302      1.1  mrg 
   2303      1.1  mrg void
   2304      1.1  mrg sqrtrem (z)
   2305      1.1  mrg     mpz_coerce z
   2306      1.1  mrg PREINIT:
   2307      1.1  mrg     SV  *sv;
   2308      1.1  mrg     mpz root;
   2309      1.1  mrg     mpz rem;
   2310      1.1  mrg PPCODE:
   2311      1.1  mrg     root = new_mpz();
   2312      1.1  mrg     rem = new_mpz();
   2313      1.1  mrg     mpz_sqrtrem (root->m, rem->m, z);
   2314      1.1  mrg     EXTEND (SP, 2);
   2315      1.1  mrg     PUSHs (MPX_NEWMORTAL (root, mpz_class_hv));
   2316      1.1  mrg     PUSHs (MPX_NEWMORTAL (rem,  mpz_class_hv));
   2317      1.1  mrg 
   2318      1.1  mrg 
   2319      1.1  mrg size_t
   2320      1.1  mrg sizeinbase (z, base)
   2321      1.1  mrg     mpz_coerce z
   2322      1.1  mrg     int        base
   2323      1.1  mrg CODE:
   2324      1.1  mrg     RETVAL = mpz_sizeinbase (z, base);
   2325      1.1  mrg OUTPUT:
   2326      1.1  mrg     RETVAL
   2327      1.1  mrg 
   2328      1.1  mrg 
   2329      1.1  mrg int
   2330      1.1  mrg tstbit (z, bit)
   2331      1.1  mrg     mpz_coerce   z
   2332      1.1  mrg     ulong_coerce bit
   2333      1.1  mrg CODE:
   2334      1.1  mrg     RETVAL = mpz_tstbit (z, bit);
   2335      1.1  mrg OUTPUT:
   2336      1.1  mrg     RETVAL
   2337      1.1  mrg 
   2338      1.1  mrg 
   2339      1.1  mrg 
   2340      1.1  mrg #------------------------------------------------------------------------------
   2341      1.1  mrg 
   2342      1.1  mrg MODULE = GMP         PACKAGE = GMP::Mpq
   2343      1.1  mrg 
   2344      1.1  mrg 
   2345      1.1  mrg mpq
   2346      1.1  mrg mpq (...)
   2347      1.1  mrg ALIAS:
   2348      1.1  mrg     GMP::Mpq::new = 1
   2349      1.1  mrg CODE:
   2350      1.1  mrg     TRACE (printf ("%s new, ix=%ld, items=%d\n", mpq_class, ix, (int) items));
   2351      1.1  mrg     RETVAL = new_mpq();
   2352      1.1  mrg     switch (items) {
   2353      1.1  mrg     case 0:
   2354      1.1  mrg       mpq_set_ui (RETVAL->m, 0L, 1L);
   2355      1.1  mrg       break;
   2356      1.1  mrg     case 1:
   2357      1.1  mrg       {
   2358      1.1  mrg         mpq_ptr rp = RETVAL->m;
   2359      1.1  mrg         mpq_ptr cp = coerce_mpq (rp, ST(0));
   2360      1.1  mrg         if (cp != rp)
   2361      1.1  mrg           mpq_set (rp, cp);
   2362      1.1  mrg       }
   2363      1.1  mrg       break;
   2364      1.1  mrg     case 2:
   2365      1.1  mrg       {
   2366      1.1  mrg         mpz_ptr rp, cp;
   2367      1.1  mrg         rp = mpq_numref (RETVAL->m);
   2368      1.1  mrg         cp = coerce_mpz (rp, ST(0));
   2369      1.1  mrg         if (cp != rp)
   2370      1.1  mrg           mpz_set (rp, cp);
   2371      1.1  mrg         rp = mpq_denref (RETVAL->m);
   2372      1.1  mrg         cp = coerce_mpz (rp, ST(1));
   2373      1.1  mrg         if (cp != rp)
   2374      1.1  mrg           mpz_set (rp, cp);
   2375      1.1  mrg       }
   2376      1.1  mrg       break;
   2377      1.1  mrg     default:
   2378      1.1  mrg       croak ("%s new: invalid arguments", mpq_class);
   2379      1.1  mrg     }
   2380      1.1  mrg OUTPUT:
   2381      1.1  mrg     RETVAL
   2382      1.1  mrg 
   2383      1.1  mrg 
   2384      1.1  mrg void
   2385      1.1  mrg overload_constant (str, pv, d1, ...)
   2386      1.1  mrg     const_string_assume str
   2387      1.1  mrg     SV                  *pv
   2388      1.1  mrg     dummy               d1
   2389      1.1  mrg PREINIT:
   2390      1.1  mrg     SV  *sv;
   2391      1.1  mrg     mpq q;
   2392      1.1  mrg PPCODE:
   2393      1.1  mrg     TRACE (printf ("%s constant: %s\n", mpq_class, str));
   2394      1.1  mrg     q = new_mpq();
   2395      1.1  mrg     if (mpq_set_str (q->m, str, 0) == 0)
   2396      1.1  mrg       { sv = sv_bless (sv_setref_pv (sv_newmortal(), NULL, q), mpq_class_hv); }
   2397      1.1  mrg     else
   2398      1.1  mrg       { free_mpq (q); sv = pv; }
   2399      1.1  mrg     XPUSHs(sv);
   2400      1.1  mrg 
   2401      1.1  mrg 
   2402      1.1  mrg mpq
   2403      1.1  mrg overload_copy (q, d1, d2)
   2404      1.1  mrg     mpq_assume q
   2405      1.1  mrg     dummy      d1
   2406      1.1  mrg     dummy      d2
   2407      1.1  mrg CODE:
   2408      1.1  mrg     RETVAL = new_mpq();
   2409      1.1  mrg     mpq_set (RETVAL->m, q->m);
   2410      1.1  mrg OUTPUT:
   2411      1.1  mrg     RETVAL
   2412      1.1  mrg 
   2413      1.1  mrg 
   2414      1.1  mrg void
   2415      1.1  mrg DESTROY (q)
   2416      1.1  mrg     mpq_assume q
   2417      1.1  mrg CODE:
   2418      1.1  mrg     TRACE (printf ("%s DESTROY %p\n", mpq_class, q));
   2419      1.1  mrg     free_mpq (q);
   2420      1.1  mrg 
   2421      1.1  mrg 
   2422      1.1  mrg malloced_string
   2423      1.1  mrg overload_string (q, d1, d2)
   2424      1.1  mrg     mpq_assume q
   2425      1.1  mrg     dummy      d1
   2426      1.1  mrg     dummy      d2
   2427      1.1  mrg CODE:
   2428      1.1  mrg     TRACE (printf ("%s overload_string %p\n", mpq_class, q));
   2429      1.1  mrg     RETVAL = mpq_get_str (NULL, 10, q->m);
   2430      1.1  mrg OUTPUT:
   2431      1.1  mrg     RETVAL
   2432      1.1  mrg 
   2433      1.1  mrg 
   2434      1.1  mrg mpq
   2435      1.1  mrg overload_add (xv, yv, order)
   2436      1.1  mrg     SV *xv
   2437      1.1  mrg     SV *yv
   2438      1.1  mrg     SV *order
   2439      1.1  mrg ALIAS:
   2440      1.1  mrg     GMP::Mpq::overload_sub   = 1
   2441      1.1  mrg     GMP::Mpq::overload_mul   = 2
   2442      1.1  mrg     GMP::Mpq::overload_div   = 3
   2443      1.1  mrg PREINIT:
   2444      1.1  mrg     static_functable const struct {
   2445      1.1  mrg       void (*op) (mpq_ptr, mpq_srcptr, mpq_srcptr);
   2446      1.1  mrg     } table[] = {
   2447      1.1  mrg       { mpq_add }, /* 0 */
   2448      1.1  mrg       { mpq_sub }, /* 1 */
   2449      1.1  mrg       { mpq_mul }, /* 2 */
   2450      1.1  mrg       { mpq_div }, /* 3 */
   2451      1.1  mrg     };
   2452      1.1  mrg CODE:
   2453      1.1  mrg     TRACE (printf ("%s binary\n", mpf_class));
   2454      1.1  mrg     assert_table (ix);
   2455      1.1  mrg     if (order == &PL_sv_yes)
   2456      1.1  mrg       SV_PTR_SWAP (xv, yv);
   2457      1.1  mrg     RETVAL = new_mpq();
   2458      1.1  mrg     (*table[ix].op) (RETVAL->m,
   2459      1.1  mrg                      coerce_mpq (tmp_mpq_0, xv),
   2460      1.1  mrg                      coerce_mpq (tmp_mpq_1, yv));
   2461      1.1  mrg OUTPUT:
   2462      1.1  mrg     RETVAL
   2463      1.1  mrg 
   2464      1.1  mrg 
   2465      1.1  mrg void
   2466      1.1  mrg overload_addeq (x, y, o)
   2467      1.1  mrg     mpq_assume   x
   2468      1.1  mrg     mpq_coerce   y
   2469      1.1  mrg     order_noswap o
   2470      1.1  mrg ALIAS:
   2471      1.1  mrg     GMP::Mpq::overload_subeq = 1
   2472      1.1  mrg     GMP::Mpq::overload_muleq = 2
   2473      1.1  mrg     GMP::Mpq::overload_diveq = 3
   2474      1.1  mrg PREINIT:
   2475      1.1  mrg     static_functable const struct {
   2476      1.1  mrg       void (*op) (mpq_ptr, mpq_srcptr, mpq_srcptr);
   2477      1.1  mrg     } table[] = {
   2478      1.1  mrg       { mpq_add    }, /* 0 */
   2479      1.1  mrg       { mpq_sub    }, /* 1 */
   2480      1.1  mrg       { mpq_mul    }, /* 2 */
   2481      1.1  mrg       { mpq_div    }, /* 3 */
   2482      1.1  mrg     };
   2483      1.1  mrg PPCODE:
   2484      1.1  mrg     assert_table (ix);
   2485      1.1  mrg     (*table[ix].op) (x->m, x->m, y);
   2486      1.1  mrg     XPUSHs(ST(0));
   2487      1.1  mrg 
   2488      1.1  mrg 
   2489      1.1  mrg mpq
   2490      1.1  mrg overload_lshift (qv, nv, order)
   2491      1.1  mrg     SV *qv
   2492      1.1  mrg     SV *nv
   2493      1.1  mrg     SV *order
   2494      1.1  mrg ALIAS:
   2495      1.1  mrg     GMP::Mpq::overload_rshift   = 1
   2496      1.1  mrg     GMP::Mpq::overload_pow      = 2
   2497      1.1  mrg PREINIT:
   2498      1.1  mrg     static_functable const struct {
   2499      1.1  mrg       void (*op) (mpq_ptr, mpq_srcptr, unsigned long);
   2500      1.1  mrg     } table[] = {
   2501      1.1  mrg       { mpq_mul_2exp }, /* 0 */
   2502      1.1  mrg       { mpq_div_2exp }, /* 1 */
   2503      1.1  mrg       { x_mpq_pow_ui }, /* 2 */
   2504      1.1  mrg     };
   2505      1.1  mrg CODE:
   2506      1.1  mrg     assert_table (ix);
   2507      1.1  mrg     if (order == &PL_sv_yes)
   2508      1.1  mrg       SV_PTR_SWAP (qv, nv);
   2509      1.1  mrg     RETVAL = new_mpq();
   2510      1.1  mrg     (*table[ix].op) (RETVAL->m, coerce_mpq (RETVAL->m, qv), coerce_ulong (nv));
   2511      1.1  mrg OUTPUT:
   2512      1.1  mrg     RETVAL
   2513      1.1  mrg 
   2514      1.1  mrg 
   2515      1.1  mrg void
   2516      1.1  mrg overload_lshifteq (q, n, o)
   2517      1.1  mrg     mpq_assume   q
   2518      1.1  mrg     ulong_coerce n
   2519      1.1  mrg     order_noswap o
   2520      1.1  mrg ALIAS:
   2521      1.1  mrg     GMP::Mpq::overload_rshifteq   = 1
   2522      1.1  mrg     GMP::Mpq::overload_poweq      = 2
   2523      1.1  mrg PREINIT:
   2524      1.1  mrg     static_functable const struct {
   2525      1.1  mrg       void (*op) (mpq_ptr, mpq_srcptr, unsigned long);
   2526      1.1  mrg     } table[] = {
   2527      1.1  mrg       { mpq_mul_2exp }, /* 0 */
   2528      1.1  mrg       { mpq_div_2exp }, /* 1 */
   2529      1.1  mrg       { x_mpq_pow_ui }, /* 2 */
   2530      1.1  mrg     };
   2531      1.1  mrg PPCODE:
   2532      1.1  mrg     assert_table (ix);
   2533      1.1  mrg     (*table[ix].op) (q->m, q->m, n);
   2534      1.1  mrg     XPUSHs(ST(0));
   2535      1.1  mrg 
   2536      1.1  mrg 
   2537      1.1  mrg void
   2538      1.1  mrg overload_inc (q, d1, d2)
   2539      1.1  mrg     mpq_assume q
   2540      1.1  mrg     dummy      d1
   2541      1.1  mrg     dummy      d2
   2542      1.1  mrg ALIAS:
   2543      1.1  mrg     GMP::Mpq::overload_dec = 1
   2544      1.1  mrg PREINIT:
   2545      1.1  mrg     static_functable const struct {
   2546      1.1  mrg       void (*op) (mpz_ptr, mpz_srcptr, mpz_srcptr);
   2547      1.1  mrg     } table[] = {
   2548      1.1  mrg       { mpz_add }, /* 0 */
   2549      1.1  mrg       { mpz_sub }, /* 1 */
   2550      1.1  mrg     };
   2551      1.1  mrg CODE:
   2552      1.1  mrg     assert_table (ix);
   2553      1.1  mrg     (*table[ix].op) (mpq_numref(q->m), mpq_numref(q->m), mpq_denref(q->m));
   2554      1.1  mrg 
   2555      1.1  mrg 
   2556      1.1  mrg mpq
   2557      1.1  mrg overload_abs (q, d1, d2)
   2558      1.1  mrg     mpq_assume q
   2559      1.1  mrg     dummy      d1
   2560      1.1  mrg     dummy      d2
   2561      1.1  mrg ALIAS:
   2562      1.1  mrg     GMP::Mpq::overload_neg = 1
   2563      1.1  mrg PREINIT:
   2564      1.1  mrg     static_functable const struct {
   2565      1.1  mrg       void (*op) (mpq_ptr w, mpq_srcptr x);
   2566      1.1  mrg     } table[] = {
   2567      1.1  mrg       { mpq_abs }, /* 0 */
   2568      1.1  mrg       { mpq_neg }, /* 1 */
   2569      1.1  mrg     };
   2570      1.1  mrg CODE:
   2571      1.1  mrg     assert_table (ix);
   2572      1.1  mrg     RETVAL = new_mpq();
   2573      1.1  mrg     (*table[ix].op) (RETVAL->m, q->m);
   2574      1.1  mrg OUTPUT:
   2575      1.1  mrg     RETVAL
   2576      1.1  mrg 
   2577      1.1  mrg 
   2578      1.1  mrg int
   2579      1.1  mrg overload_spaceship (x, y, order)
   2580      1.1  mrg     mpq_assume x
   2581      1.1  mrg     mpq_coerce y
   2582      1.1  mrg     SV         *order
   2583      1.1  mrg CODE:
   2584      1.1  mrg     RETVAL = mpq_cmp (x->m, y);
   2585      1.1  mrg     RETVAL = SGN (RETVAL);
   2586      1.1  mrg     if (order == &PL_sv_yes)
   2587      1.1  mrg       RETVAL = -RETVAL;
   2588      1.1  mrg OUTPUT:
   2589      1.1  mrg     RETVAL
   2590      1.1  mrg 
   2591      1.1  mrg 
   2592      1.1  mrg bool
   2593      1.1  mrg overload_bool (q, d1, d2)
   2594      1.1  mrg     mpq_assume q
   2595      1.1  mrg     dummy      d1
   2596      1.1  mrg     dummy      d2
   2597      1.1  mrg ALIAS:
   2598      1.1  mrg     GMP::Mpq::overload_not = 1
   2599      1.1  mrg CODE:
   2600      1.1  mrg     RETVAL = (mpq_sgn (q->m) != 0) ^ ix;
   2601      1.1  mrg OUTPUT:
   2602      1.1  mrg     RETVAL
   2603      1.1  mrg 
   2604      1.1  mrg 
   2605      1.1  mrg bool
   2606      1.1  mrg overload_eq (x, yv, d)
   2607      1.1  mrg     mpq_assume x
   2608      1.1  mrg     SV         *yv
   2609      1.1  mrg     dummy      d
   2610      1.1  mrg ALIAS:
   2611      1.1  mrg     GMP::Mpq::overload_ne = 1
   2612      1.1  mrg PREINIT:
   2613      1.1  mrg     int  use;
   2614      1.1  mrg CODE:
   2615      1.1  mrg     use = use_sv (yv);
   2616      1.1  mrg     switch (use) {
   2617      1.1  mrg     case USE_IVX:
   2618      1.1  mrg     case USE_UVX:
   2619      1.1  mrg     case USE_MPZ:
   2620      1.1  mrg       RETVAL = 0;
   2621      1.1  mrg       if (x_mpq_integer_p (x->m))
   2622      1.1  mrg         {
   2623      1.1  mrg           switch (use) {
   2624      1.1  mrg           case USE_IVX:
   2625      1.1  mrg             RETVAL = (mpz_cmp_si (mpq_numref(x->m), SvIVX(yv)) == 0);
   2626      1.1  mrg             break;
   2627      1.1  mrg           case USE_UVX:
   2628      1.1  mrg             RETVAL = (mpz_cmp_ui (mpq_numref(x->m), SvUVX(yv)) == 0);
   2629      1.1  mrg             break;
   2630      1.1  mrg           case USE_MPZ:
   2631      1.1  mrg             RETVAL = (mpz_cmp (mpq_numref(x->m), SvMPZ(yv)->m) == 0);
   2632      1.1  mrg             break;
   2633      1.1  mrg           }
   2634      1.1  mrg         }
   2635      1.1  mrg       break;
   2636      1.1  mrg 
   2637      1.1  mrg     case USE_MPQ:
   2638      1.1  mrg       RETVAL = (mpq_equal (x->m, SvMPQ(yv)->m) != 0);
   2639      1.1  mrg       break;
   2640      1.1  mrg 
   2641      1.1  mrg     default:
   2642      1.1  mrg       RETVAL = (mpq_equal (x->m, coerce_mpq_using (tmp_mpq_0, yv, use)) != 0);
   2643      1.1  mrg       break;
   2644      1.1  mrg     }
   2645      1.1  mrg     RETVAL ^= ix;
   2646      1.1  mrg OUTPUT:
   2647      1.1  mrg     RETVAL
   2648      1.1  mrg 
   2649      1.1  mrg 
   2650      1.1  mrg void
   2651      1.1  mrg canonicalize (q)
   2652      1.1  mrg     mpq q
   2653      1.1  mrg CODE:
   2654      1.1  mrg     mpq_canonicalize (q->m);
   2655      1.1  mrg 
   2656      1.1  mrg 
   2657      1.1  mrg mpq
   2658      1.1  mrg inv (q)
   2659      1.1  mrg     mpq_coerce q
   2660      1.1  mrg CODE:
   2661      1.1  mrg     RETVAL = new_mpq();
   2662      1.1  mrg     mpq_inv (RETVAL->m, q);
   2663      1.1  mrg OUTPUT:
   2664      1.1  mrg     RETVAL
   2665      1.1  mrg 
   2666      1.1  mrg 
   2667      1.1  mrg mpz
   2668      1.1  mrg num (q)
   2669      1.1  mrg     mpq q
   2670      1.1  mrg ALIAS:
   2671      1.1  mrg     GMP::Mpq::den = 1
   2672      1.1  mrg CODE:
   2673      1.1  mrg     RETVAL = new_mpz();
   2674      1.1  mrg     mpz_set (RETVAL->m, (ix == 0 ? mpq_numref(q->m) : mpq_denref(q->m)));
   2675      1.1  mrg OUTPUT:
   2676      1.1  mrg     RETVAL
   2677      1.1  mrg 
   2678      1.1  mrg 
   2679      1.1  mrg 
   2680      1.1  mrg #------------------------------------------------------------------------------
   2681      1.1  mrg 
   2682      1.1  mrg MODULE = GMP         PACKAGE = GMP::Mpf
   2683      1.1  mrg 
   2684      1.1  mrg 
   2685      1.1  mrg mpf
   2686      1.1  mrg mpf (...)
   2687      1.1  mrg ALIAS:
   2688      1.1  mrg     GMP::Mpf::new = 1
   2689      1.1  mrg PREINIT:
   2690      1.1  mrg     unsigned long  prec;
   2691      1.1  mrg CODE:
   2692      1.1  mrg     TRACE (printf ("%s new\n", mpf_class));
   2693      1.1  mrg     if (items > 2)
   2694      1.1  mrg       croak ("%s new: invalid arguments", mpf_class);
   2695      1.1  mrg     prec = (items == 2 ? coerce_ulong (ST(1)) : mpf_get_default_prec());
   2696      1.1  mrg     RETVAL = new_mpf (prec);
   2697      1.1  mrg     if (items >= 1)
   2698      1.1  mrg       {
   2699      1.1  mrg         SV *sv = ST(0);
   2700      1.1  mrg         my_mpf_set_sv_using (RETVAL, sv, use_sv(sv));
   2701      1.1  mrg       }
   2702      1.1  mrg OUTPUT:
   2703      1.1  mrg     RETVAL
   2704      1.1  mrg 
   2705      1.1  mrg 
   2706      1.1  mrg mpf
   2707      1.1  mrg overload_constant (sv, d1, d2, ...)
   2708      1.1  mrg     SV     *sv
   2709      1.1  mrg     dummy  d1
   2710      1.1  mrg     dummy  d2
   2711      1.1  mrg CODE:
   2712      1.1  mrg     assert (SvPOK (sv));
   2713      1.1  mrg     TRACE (printf ("%s constant: %s\n", mpq_class, SvPVX(sv)));
   2714      1.1  mrg     RETVAL = new_mpf (mpf_get_default_prec());
   2715      1.1  mrg     my_mpf_set_svstr (RETVAL, sv);
   2716      1.1  mrg OUTPUT:
   2717      1.1  mrg     RETVAL
   2718      1.1  mrg 
   2719      1.1  mrg 
   2720      1.1  mrg mpf
   2721      1.1  mrg overload_copy (f, d1, d2)
   2722      1.1  mrg     mpf_assume f
   2723      1.1  mrg     dummy      d1
   2724      1.1  mrg     dummy      d2
   2725      1.1  mrg CODE:
   2726      1.1  mrg     TRACE (printf ("%s copy\n", mpf_class));
   2727      1.1  mrg     RETVAL = new_mpf (mpf_get_prec (f));
   2728      1.1  mrg     mpf_set (RETVAL, f);
   2729      1.1  mrg OUTPUT:
   2730      1.1  mrg     RETVAL
   2731      1.1  mrg 
   2732      1.1  mrg 
   2733      1.1  mrg void
   2734      1.1  mrg DESTROY (f)
   2735      1.1  mrg     mpf_assume f
   2736      1.1  mrg CODE:
   2737      1.1  mrg     TRACE (printf ("%s DESTROY %p\n", mpf_class, f));
   2738      1.1  mrg     mpf_clear (f);
   2739      1.1  mrg     Safefree (f);
   2740      1.1  mrg     assert_support (mpf_count--);
   2741      1.1  mrg     TRACE_ACTIVE ();
   2742      1.1  mrg 
   2743      1.1  mrg 
   2744      1.1  mrg mpf
   2745      1.1  mrg overload_add (x, y, order)
   2746      1.1  mrg     mpf_assume     x
   2747      1.1  mrg     mpf_coerce_st0 y
   2748      1.1  mrg     SV             *order
   2749      1.1  mrg ALIAS:
   2750      1.1  mrg     GMP::Mpf::overload_sub   = 1
   2751      1.1  mrg     GMP::Mpf::overload_mul   = 2
   2752      1.1  mrg     GMP::Mpf::overload_div   = 3
   2753      1.1  mrg PREINIT:
   2754      1.1  mrg     static_functable const struct {
   2755      1.1  mrg       void (*op) (mpf_ptr, mpf_srcptr, mpf_srcptr);
   2756      1.1  mrg     } table[] = {
   2757      1.1  mrg       { mpf_add }, /* 0 */
   2758      1.1  mrg       { mpf_sub }, /* 1 */
   2759      1.1  mrg       { mpf_mul }, /* 2 */
   2760      1.1  mrg       { mpf_div }, /* 3 */
   2761      1.1  mrg     };
   2762      1.1  mrg CODE:
   2763      1.1  mrg     assert_table (ix);
   2764      1.1  mrg     RETVAL = new_mpf (mpf_get_prec (x));
   2765      1.1  mrg     if (order == &PL_sv_yes)
   2766      1.1  mrg       MPF_PTR_SWAP (x, y);
   2767      1.1  mrg     (*table[ix].op) (RETVAL, x, y);
   2768      1.1  mrg OUTPUT:
   2769      1.1  mrg     RETVAL
   2770      1.1  mrg 
   2771      1.1  mrg 
   2772      1.1  mrg void
   2773      1.1  mrg overload_addeq (x, y, o)
   2774      1.1  mrg     mpf_assume     x
   2775      1.1  mrg     mpf_coerce_st0 y
   2776      1.1  mrg     order_noswap   o
   2777      1.1  mrg ALIAS:
   2778      1.1  mrg     GMP::Mpf::overload_subeq = 1
   2779      1.1  mrg     GMP::Mpf::overload_muleq = 2
   2780      1.1  mrg     GMP::Mpf::overload_diveq = 3
   2781      1.1  mrg PREINIT:
   2782      1.1  mrg     static_functable const struct {
   2783      1.1  mrg       void (*op) (mpf_ptr, mpf_srcptr, mpf_srcptr);
   2784      1.1  mrg     } table[] = {
   2785      1.1  mrg       { mpf_add }, /* 0 */
   2786      1.1  mrg       { mpf_sub }, /* 1 */
   2787      1.1  mrg       { mpf_mul }, /* 2 */
   2788      1.1  mrg       { mpf_div }, /* 3 */
   2789      1.1  mrg     };
   2790      1.1  mrg PPCODE:
   2791      1.1  mrg     assert_table (ix);
   2792      1.1  mrg     (*table[ix].op) (x, x, y);
   2793      1.1  mrg     XPUSHs(ST(0));
   2794      1.1  mrg 
   2795      1.1  mrg 
   2796      1.1  mrg mpf
   2797      1.1  mrg overload_lshift (fv, nv, order)
   2798      1.1  mrg     SV *fv
   2799      1.1  mrg     SV *nv
   2800      1.1  mrg     SV *order
   2801      1.1  mrg ALIAS:
   2802      1.1  mrg     GMP::Mpf::overload_rshift = 1
   2803      1.1  mrg     GMP::Mpf::overload_pow    = 2
   2804      1.1  mrg PREINIT:
   2805      1.1  mrg     static_functable const struct {
   2806      1.1  mrg       void (*op) (mpf_ptr, mpf_srcptr, unsigned long);
   2807      1.1  mrg     } table[] = {
   2808      1.1  mrg       { mpf_mul_2exp }, /* 0 */
   2809      1.1  mrg       { mpf_div_2exp }, /* 1 */
   2810      1.1  mrg       { mpf_pow_ui   }, /* 2 */
   2811      1.1  mrg     };
   2812      1.1  mrg     mpf f;
   2813      1.1  mrg     unsigned long prec;
   2814      1.1  mrg CODE:
   2815      1.1  mrg     assert_table (ix);
   2816      1.1  mrg     MPF_ASSUME (f, fv);
   2817      1.1  mrg     prec = mpf_get_prec (f);
   2818      1.1  mrg     if (order == &PL_sv_yes)
   2819      1.1  mrg       SV_PTR_SWAP (fv, nv);
   2820      1.1  mrg     f = coerce_mpf (tmp_mpf_0, fv, prec);
   2821      1.1  mrg     RETVAL = new_mpf (prec);
   2822      1.1  mrg     (*table[ix].op) (RETVAL, f, coerce_ulong (nv));
   2823      1.1  mrg OUTPUT:
   2824      1.1  mrg     RETVAL
   2825      1.1  mrg 
   2826      1.1  mrg 
   2827      1.1  mrg void
   2828      1.1  mrg overload_lshifteq (f, n, o)
   2829      1.1  mrg     mpf_assume   f
   2830      1.1  mrg     ulong_coerce n
   2831      1.1  mrg     order_noswap o
   2832      1.1  mrg ALIAS:
   2833      1.1  mrg     GMP::Mpf::overload_rshifteq   = 1
   2834      1.1  mrg     GMP::Mpf::overload_poweq      = 2
   2835      1.1  mrg PREINIT:
   2836      1.1  mrg     static_functable const struct {
   2837      1.1  mrg       void (*op) (mpf_ptr, mpf_srcptr, unsigned long);
   2838      1.1  mrg     } table[] = {
   2839      1.1  mrg       { mpf_mul_2exp }, /* 0 */
   2840      1.1  mrg       { mpf_div_2exp }, /* 1 */
   2841      1.1  mrg       { mpf_pow_ui   }, /* 2 */
   2842      1.1  mrg     };
   2843      1.1  mrg PPCODE:
   2844      1.1  mrg     assert_table (ix);
   2845      1.1  mrg     (*table[ix].op) (f, f, n);
   2846      1.1  mrg     XPUSHs(ST(0));
   2847      1.1  mrg 
   2848      1.1  mrg 
   2849      1.1  mrg mpf
   2850      1.1  mrg overload_abs (f, d1, d2)
   2851      1.1  mrg     mpf_assume f
   2852      1.1  mrg     dummy      d1
   2853      1.1  mrg     dummy      d2
   2854      1.1  mrg ALIAS:
   2855      1.1  mrg     GMP::Mpf::overload_neg   = 1
   2856      1.1  mrg     GMP::Mpf::overload_sqrt  = 2
   2857      1.1  mrg PREINIT:
   2858      1.1  mrg     static_functable const struct {
   2859      1.1  mrg       void (*op) (mpf_ptr w, mpf_srcptr x);
   2860      1.1  mrg     } table[] = {
   2861      1.1  mrg       { mpf_abs  }, /* 0 */
   2862      1.1  mrg       { mpf_neg  }, /* 1 */
   2863      1.1  mrg       { mpf_sqrt }, /* 2 */
   2864      1.1  mrg     };
   2865      1.1  mrg CODE:
   2866      1.1  mrg     assert_table (ix);
   2867      1.1  mrg     RETVAL = new_mpf (mpf_get_prec (f));
   2868      1.1  mrg     (*table[ix].op) (RETVAL, f);
   2869      1.1  mrg OUTPUT:
   2870      1.1  mrg     RETVAL
   2871      1.1  mrg 
   2872      1.1  mrg 
   2873      1.1  mrg void
   2874      1.1  mrg overload_inc (f, d1, d2)
   2875      1.1  mrg     mpf_assume f
   2876      1.1  mrg     dummy      d1
   2877      1.1  mrg     dummy      d2
   2878      1.1  mrg ALIAS:
   2879      1.1  mrg     GMP::Mpf::overload_dec = 1
   2880      1.1  mrg PREINIT:
   2881      1.1  mrg     static_functable const struct {
   2882      1.1  mrg       void (*op) (mpf_ptr w, mpf_srcptr x, unsigned long y);
   2883      1.1  mrg     } table[] = {
   2884      1.1  mrg       { mpf_add_ui }, /* 0 */
   2885      1.1  mrg       { mpf_sub_ui }, /* 1 */
   2886      1.1  mrg     };
   2887      1.1  mrg CODE:
   2888      1.1  mrg     assert_table (ix);
   2889      1.1  mrg     (*table[ix].op) (f, f, 1L);
   2890      1.1  mrg 
   2891      1.1  mrg 
   2892      1.1  mrg int
   2893      1.1  mrg overload_spaceship (xv, yv, order)
   2894      1.1  mrg     SV *xv
   2895      1.1  mrg     SV *yv
   2896      1.1  mrg     SV *order
   2897      1.1  mrg PREINIT:
   2898      1.1  mrg     mpf x;
   2899      1.1  mrg CODE:
   2900      1.1  mrg     MPF_ASSUME (x, xv);
   2901      1.1  mrg     switch (use_sv (yv)) {
   2902      1.1  mrg     case USE_IVX:
   2903      1.1  mrg       RETVAL = mpf_cmp_si (x, SvIVX(yv));
   2904      1.1  mrg       break;
   2905      1.1  mrg     case USE_UVX:
   2906      1.1  mrg       RETVAL = mpf_cmp_ui (x, SvUVX(yv));
   2907      1.1  mrg       break;
   2908      1.1  mrg     case USE_NVX:
   2909      1.1  mrg       RETVAL = mpf_cmp_d (x, SvNVX(yv));
   2910      1.1  mrg       break;
   2911      1.1  mrg     case USE_PVX:
   2912      1.1  mrg       {
   2913      1.1  mrg         STRLEN len;
   2914      1.1  mrg         const char *str = SvPV (yv, len);
   2915      1.1  mrg         /* enough for all digits of the string */
   2916      1.1  mrg         tmp_mpf_set_prec (tmp_mpf_0, strlen(str)+64);
   2917      1.1  mrg         if (mpf_set_str (tmp_mpf_0->m, str, 10) != 0)
   2918      1.1  mrg           croak ("%s <=>: invalid string format", mpf_class);
   2919      1.1  mrg         RETVAL = mpf_cmp (x, tmp_mpf_0->m);
   2920      1.1  mrg       }
   2921      1.1  mrg       break;
   2922      1.1  mrg     case USE_MPZ:
   2923      1.1  mrg       RETVAL = - x_mpz_cmp_f (SvMPZ(yv)->m, x);
   2924      1.1  mrg       break;
   2925      1.1  mrg     case USE_MPF:
   2926      1.1  mrg       RETVAL = mpf_cmp (x, SvMPF(yv));
   2927      1.1  mrg       break;
   2928      1.1  mrg     default:
   2929      1.1  mrg       RETVAL = mpq_cmp (coerce_mpq (tmp_mpq_0, xv),
   2930      1.1  mrg                         coerce_mpq (tmp_mpq_1, yv));
   2931      1.1  mrg       break;
   2932      1.1  mrg     }
   2933      1.1  mrg     RETVAL = SGN (RETVAL);
   2934      1.1  mrg     if (order == &PL_sv_yes)
   2935      1.1  mrg       RETVAL = -RETVAL;
   2936      1.1  mrg OUTPUT:
   2937      1.1  mrg     RETVAL
   2938      1.1  mrg 
   2939      1.1  mrg 
   2940      1.1  mrg bool
   2941      1.1  mrg overload_bool (f, d1, d2)
   2942      1.1  mrg     mpf_assume f
   2943      1.1  mrg     dummy      d1
   2944      1.1  mrg     dummy      d2
   2945      1.1  mrg ALIAS:
   2946      1.1  mrg     GMP::Mpf::overload_not = 1
   2947      1.1  mrg CODE:
   2948      1.1  mrg     RETVAL = (mpf_sgn (f) != 0) ^ ix;
   2949      1.1  mrg OUTPUT:
   2950      1.1  mrg     RETVAL
   2951      1.1  mrg 
   2952      1.1  mrg 
   2953      1.1  mrg mpf
   2954      1.1  mrg ceil (f)
   2955      1.1  mrg     mpf_coerce_def f
   2956      1.1  mrg ALIAS:
   2957      1.1  mrg     GMP::Mpf::floor = 1
   2958      1.1  mrg     GMP::Mpf::trunc = 2
   2959      1.1  mrg PREINIT:
   2960      1.1  mrg     static_functable const struct {
   2961      1.1  mrg       void (*op) (mpf_ptr w, mpf_srcptr x);
   2962      1.1  mrg     } table[] = {
   2963      1.1  mrg       { mpf_ceil  }, /* 0 */
   2964      1.1  mrg       { mpf_floor }, /* 1 */
   2965      1.1  mrg       { mpf_trunc }, /* 2 */
   2966      1.1  mrg     };
   2967      1.1  mrg CODE:
   2968      1.1  mrg     assert_table (ix);
   2969      1.1  mrg     RETVAL = new_mpf (mpf_get_prec (f));
   2970      1.1  mrg     (*table[ix].op) (RETVAL, f);
   2971      1.1  mrg OUTPUT:
   2972      1.1  mrg     RETVAL
   2973      1.1  mrg 
   2974      1.1  mrg 
   2975      1.1  mrg unsigned long
   2976      1.1  mrg get_default_prec ()
   2977      1.1  mrg CODE:
   2978      1.1  mrg     RETVAL = mpf_get_default_prec();
   2979      1.1  mrg OUTPUT:
   2980      1.1  mrg     RETVAL
   2981      1.1  mrg 
   2982      1.1  mrg 
   2983      1.1  mrg unsigned long
   2984      1.1  mrg get_prec (f)
   2985      1.1  mrg     mpf_coerce_def f
   2986      1.1  mrg CODE:
   2987      1.1  mrg     RETVAL = mpf_get_prec (f);
   2988      1.1  mrg OUTPUT:
   2989      1.1  mrg     RETVAL
   2990      1.1  mrg 
   2991      1.1  mrg 
   2992      1.1  mrg bool
   2993      1.1  mrg mpf_eq (xv, yv, bits)
   2994      1.1  mrg     SV           *xv
   2995      1.1  mrg     SV           *yv
   2996      1.1  mrg     ulong_coerce bits
   2997      1.1  mrg PREINIT:
   2998      1.1  mrg     mpf  x, y;
   2999      1.1  mrg CODE:
   3000      1.1  mrg     TRACE (printf ("%s eq\n", mpf_class));
   3001      1.1  mrg     coerce_mpf_pair (&x,xv, &y,yv);
   3002      1.1  mrg     RETVAL = mpf_eq (x, y, bits);
   3003      1.1  mrg OUTPUT:
   3004      1.1  mrg     RETVAL
   3005      1.1  mrg 
   3006      1.1  mrg 
   3007      1.1  mrg mpf
   3008      1.1  mrg reldiff (xv, yv)
   3009      1.1  mrg     SV *xv
   3010      1.1  mrg     SV *yv
   3011      1.1  mrg PREINIT:
   3012      1.1  mrg     mpf  x, y;
   3013      1.1  mrg     unsigned long prec;
   3014      1.1  mrg CODE:
   3015      1.1  mrg     TRACE (printf ("%s reldiff\n", mpf_class));
   3016      1.1  mrg     prec = coerce_mpf_pair (&x,xv, &y,yv);
   3017      1.1  mrg     RETVAL = new_mpf (prec);
   3018      1.1  mrg     mpf_reldiff (RETVAL, x, y);
   3019      1.1  mrg OUTPUT:
   3020      1.1  mrg     RETVAL
   3021      1.1  mrg 
   3022      1.1  mrg 
   3023      1.1  mrg void
   3024      1.1  mrg set_default_prec (prec)
   3025      1.1  mrg     ulong_coerce prec
   3026      1.1  mrg CODE:
   3027      1.1  mrg     TRACE (printf ("%s set_default_prec %lu\n", mpf_class, prec));
   3028      1.1  mrg     mpf_set_default_prec (prec);
   3029      1.1  mrg 
   3030      1.1  mrg 
   3031      1.1  mrg void
   3032      1.1  mrg set_prec (sv, prec)
   3033      1.1  mrg     SV           *sv
   3034      1.1  mrg     ulong_coerce prec
   3035      1.1  mrg PREINIT:
   3036      1.1  mrg     mpf_ptr  old_f, new_f;
   3037      1.1  mrg     int      use;
   3038      1.1  mrg CODE:
   3039      1.1  mrg     TRACE (printf ("%s set_prec to %lu\n", mpf_class, prec));
   3040      1.1  mrg     use = use_sv (sv);
   3041      1.1  mrg     if (use == USE_MPF)
   3042      1.1  mrg       {
   3043      1.1  mrg         old_f = SvMPF(sv);
   3044      1.1  mrg         if (SvREFCNT(SvRV(sv)) == 1)
   3045      1.1  mrg           mpf_set_prec (old_f, prec);
   3046      1.1  mrg         else
   3047      1.1  mrg           {
   3048      1.1  mrg             TRACE (printf ("  fork new mpf\n"));
   3049      1.1  mrg             new_f = new_mpf (prec);
   3050      1.1  mrg             mpf_set (new_f, old_f);
   3051      1.1  mrg             goto setref;
   3052      1.1  mrg           }
   3053      1.1  mrg       }
   3054      1.1  mrg     else
   3055      1.1  mrg       {
   3056      1.1  mrg         TRACE (printf ("  coerce to mpf\n"));
   3057      1.1  mrg         new_f = new_mpf (prec);
   3058      1.1  mrg         my_mpf_set_sv_using (new_f, sv, use);
   3059      1.1  mrg       setref:
   3060      1.1  mrg         sv_bless (sv_setref_pv (sv, NULL, new_f), mpf_class_hv);
   3061      1.1  mrg       }
   3062      1.1  mrg 
   3063      1.1  mrg 
   3064      1.1  mrg 
   3065      1.1  mrg #------------------------------------------------------------------------------
   3066      1.1  mrg 
   3067      1.1  mrg MODULE = GMP         PACKAGE = GMP::Rand
   3068      1.1  mrg 
   3069      1.1  mrg randstate
   3070      1.1  mrg new (...)
   3071      1.1  mrg ALIAS:
   3072      1.1  mrg     GMP::Rand::randstate = 1
   3073      1.1  mrg CODE:
   3074      1.1  mrg     TRACE (printf ("%s new\n", rand_class));
   3075      1.1  mrg     New (GMP_MALLOC_ID, RETVAL, 1, __gmp_randstate_struct);
   3076      1.1  mrg     TRACE (printf ("  RETVAL %p\n", RETVAL));
   3077      1.1  mrg     assert_support (rand_count++);
   3078      1.1  mrg     TRACE_ACTIVE ();
   3079      1.1  mrg 
   3080      1.1  mrg     if (items == 0)
   3081      1.1  mrg       {
   3082      1.1  mrg         gmp_randinit_default (RETVAL);
   3083      1.1  mrg       }
   3084      1.1  mrg     else
   3085      1.1  mrg       {
   3086      1.1  mrg         if (SvROK (ST(0)) && sv_derived_from (ST(0), rand_class))
   3087      1.1  mrg           {
   3088      1.1  mrg             if (items != 1)
   3089      1.1  mrg               goto invalid;
   3090      1.1  mrg             gmp_randinit_set (RETVAL, SvRANDSTATE (ST(0)));
   3091      1.1  mrg           }
   3092      1.1  mrg         else
   3093      1.1  mrg           {
   3094      1.1  mrg             STRLEN      len;
   3095      1.1  mrg             const char  *method = SvPV (ST(0), len);
   3096      1.1  mrg             assert (len == strlen (method));
   3097      1.1  mrg             if (strcmp (method, "lc_2exp") == 0)
   3098      1.1  mrg               {
   3099      1.1  mrg                 if (items != 4)
   3100      1.1  mrg                   goto invalid;
   3101      1.1  mrg                 gmp_randinit_lc_2exp (RETVAL,
   3102      1.1  mrg                                       coerce_mpz (tmp_mpz_0, ST(1)),
   3103      1.1  mrg                                       coerce_ulong (ST(2)),
   3104      1.1  mrg                                       coerce_ulong (ST(3)));
   3105      1.1  mrg               }
   3106      1.1  mrg             else if (strcmp (method, "lc_2exp_size") == 0)
   3107      1.1  mrg               {
   3108      1.1  mrg                 if (items != 2)
   3109      1.1  mrg                   goto invalid;
   3110      1.1  mrg                 if (! gmp_randinit_lc_2exp_size (RETVAL, coerce_ulong (ST(1))))
   3111      1.1  mrg                   {
   3112      1.1  mrg                     Safefree (RETVAL);
   3113      1.1  mrg                     XSRETURN_UNDEF;
   3114      1.1  mrg                   }
   3115      1.1  mrg               }
   3116      1.1  mrg             else if (strcmp (method, "mt") == 0)
   3117      1.1  mrg               {
   3118      1.1  mrg                 if (items != 1)
   3119      1.1  mrg                   goto invalid;
   3120      1.1  mrg                 gmp_randinit_mt (RETVAL);
   3121      1.1  mrg               }
   3122      1.1  mrg             else
   3123      1.1  mrg               {
   3124      1.1  mrg               invalid:
   3125      1.1  mrg                 croak ("%s new: invalid arguments", rand_class);
   3126      1.1  mrg               }
   3127      1.1  mrg           }
   3128      1.1  mrg       }
   3129      1.1  mrg OUTPUT:
   3130      1.1  mrg     RETVAL
   3131      1.1  mrg 
   3132      1.1  mrg 
   3133      1.1  mrg void
   3134      1.1  mrg DESTROY (r)
   3135      1.1  mrg     randstate r
   3136      1.1  mrg CODE:
   3137      1.1  mrg     TRACE (printf ("%s DESTROY\n", rand_class));
   3138      1.1  mrg     gmp_randclear (r);
   3139      1.1  mrg     Safefree (r);
   3140      1.1  mrg     assert_support (rand_count--);
   3141      1.1  mrg     TRACE_ACTIVE ();
   3142      1.1  mrg 
   3143      1.1  mrg 
   3144      1.1  mrg void
   3145      1.1  mrg seed (r, z)
   3146      1.1  mrg     randstate  r
   3147      1.1  mrg     mpz_coerce z
   3148      1.1  mrg CODE:
   3149      1.1  mrg     gmp_randseed (r, z);
   3150      1.1  mrg 
   3151      1.1  mrg 
   3152      1.1  mrg mpz
   3153      1.1  mrg mpz_urandomb (r, bits)
   3154      1.1  mrg     randstate    r
   3155      1.1  mrg     ulong_coerce bits
   3156      1.1  mrg ALIAS:
   3157      1.1  mrg     GMP::Rand::mpz_rrandomb = 1
   3158      1.1  mrg PREINIT:
   3159      1.1  mrg     static_functable const struct {
   3160      1.1  mrg       void (*fun) (mpz_ptr, gmp_randstate_t r, unsigned long bits);
   3161      1.1  mrg     } table[] = {
   3162      1.1  mrg       { mpz_urandomb }, /* 0 */
   3163      1.1  mrg       { mpz_rrandomb }, /* 1 */
   3164      1.1  mrg     };
   3165      1.1  mrg CODE:
   3166      1.1  mrg     assert_table (ix);
   3167      1.1  mrg     RETVAL = new_mpz();
   3168      1.1  mrg     (*table[ix].fun) (RETVAL->m, r, bits);
   3169      1.1  mrg OUTPUT:
   3170      1.1  mrg     RETVAL
   3171      1.1  mrg 
   3172      1.1  mrg 
   3173      1.1  mrg mpz
   3174      1.1  mrg mpz_urandomm (r, m)
   3175      1.1  mrg     randstate  r
   3176      1.1  mrg     mpz_coerce m
   3177      1.1  mrg CODE:
   3178      1.1  mrg     RETVAL = new_mpz();
   3179      1.1  mrg     mpz_urandomm (RETVAL->m, r, m);
   3180      1.1  mrg OUTPUT:
   3181      1.1  mrg     RETVAL
   3182      1.1  mrg 
   3183      1.1  mrg 
   3184      1.1  mrg mpf
   3185      1.1  mrg mpf_urandomb (r, bits)
   3186      1.1  mrg     randstate    r
   3187      1.1  mrg     ulong_coerce bits
   3188      1.1  mrg CODE:
   3189      1.1  mrg     RETVAL = new_mpf (bits);
   3190      1.1  mrg     mpf_urandomb (RETVAL, r, bits);
   3191      1.1  mrg OUTPUT:
   3192      1.1  mrg     RETVAL
   3193      1.1  mrg 
   3194      1.1  mrg 
   3195      1.1  mrg unsigned long
   3196      1.1  mrg gmp_urandomb_ui (r, bits)
   3197      1.1  mrg     randstate    r
   3198      1.1  mrg     ulong_coerce bits
   3199      1.1  mrg ALIAS:
   3200      1.1  mrg     GMP::Rand::gmp_urandomm_ui = 1
   3201      1.1  mrg PREINIT:
   3202      1.1  mrg     static_functable const struct {
   3203      1.1  mrg       unsigned long (*fun) (gmp_randstate_t r, unsigned long bits);
   3204      1.1  mrg     } table[] = {
   3205      1.1  mrg       { gmp_urandomb_ui }, /* 0 */
   3206      1.1  mrg       { gmp_urandomm_ui }, /* 1 */
   3207      1.1  mrg     };
   3208      1.1  mrg CODE:
   3209      1.1  mrg     assert_table (ix);
   3210      1.1  mrg     RETVAL = (*table[ix].fun) (r, bits);
   3211      1.1  mrg OUTPUT:
   3212      1.1  mrg     RETVAL
   3213