GMP.xs
上传用户:qaz666999
上传日期:2022-08-06
资源大小:2570k
文件大小:71k
源码类别:

数学计算

开发平台:

Unix_Linux

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