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