1
2 #ifdef __MINGW32__
3 #ifndef __USE_MINGW_ANSI_STDIO
4 #define __USE_MINGW_ANSI_STDIO 1
5 #endif
6 #endif
7
8 #define PERL_NO_GET_CONTEXT 1
9
10 #include "EXTERN.h"
11 #include "perl.h"
12 #include "XSUB.h"
13
14
15
16 #include "math_gmpz_include.h"
17
MATH_GMPz_IV_MAX(pTHX)18 SV * MATH_GMPz_IV_MAX(pTHX) {
19 return newSViv((IV)IV_MAX);
20 }
21
MATH_GMPz_IV_MIN(pTHX)22 SV * MATH_GMPz_IV_MIN(pTHX) {
23 return newSViv((IV)IV_MIN);
24 }
25
MATH_GMPz_UV_MAX(pTHX)26 SV * MATH_GMPz_UV_MAX(pTHX) {
27 return newSVuv((UV)UV_MAX);
28 }
29
_is_infstring(char * s)30 int _is_infstring(char * s) {
31 int sign = 1;
32
33 if(s[0] == '-') {
34 sign = -1;
35 s++;
36 }
37 else {
38 if(s[0] == '+') s++;
39 }
40
41 if((s[0] == 'i' || s[0] == 'I') && (s[1] == 'n' || s[1] == 'N') && (s[2] == 'f' || s[2] == 'F'))
42 return sign;
43
44 #ifdef _WIN32_BIZARRE_INFNAN /* older Win32 perls stringify infinities as(-)1.#INF */
45
46 if(!strcmp(s, "1.#INF")) return sign;
47
48 #endif
49
50 return 0;
51 }
52
Rmpz_init_set_str_nobless(pTHX_ SV * num,SV * base)53 SV * Rmpz_init_set_str_nobless(pTHX_ SV * num, SV * base) {
54 mpz_t * mpz_t_obj;
55 int b = (int)SvUV(base);
56 SV * obj_ref, * obj;
57
58 if(b == 1 || b > 62) croak("Second argument supplied to Rmpz_init_set_str_nobless is not in acceptable range");
59
60 New(1, mpz_t_obj, 1, mpz_t);
61 if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_create function");
62 if(mpz_init_set_str (*mpz_t_obj, SvPV_nolen(num), b))
63 croak("First argument supplied to Rmpz_create_init_nobless is not a valid base %u integer", b);
64
65 obj_ref = newSV(0);
66 obj = newSVrv(obj_ref, NULL);
67 sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
68 SvREADONLY_on(obj);
69 return obj_ref;
70
71 }
72
Rmpz_init2_nobless(pTHX_ SV * bits)73 SV * Rmpz_init2_nobless(pTHX_ SV * bits) {
74 mpz_t * mpz_t_obj;
75 SV * obj_ref, * obj;
76
77 New(1, mpz_t_obj, 1, mpz_t);
78 if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_init2_nobless function");
79 obj_ref = newSV(0);
80 obj = newSVrv(obj_ref, NULL);
81 mpz_init2 (*mpz_t_obj, SvUV(bits));
82
83 sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
84 SvREADONLY_on(obj);
85 return obj_ref;
86
87 }
88
Rmpz_init_nobless(pTHX)89 SV * Rmpz_init_nobless(pTHX) {
90 mpz_t * mpz_t_obj;
91 SV * obj_ref, * obj;
92
93 New(1, mpz_t_obj, 1, mpz_t);
94 if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_init_nobless function");
95 obj_ref = newSV(0);
96 obj = newSVrv(obj_ref, NULL);
97 mpz_init(*mpz_t_obj);
98
99 sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
100 SvREADONLY_on(obj);
101 return obj_ref;
102 }
103
Rmpz_init_set_nobless(pTHX_ mpz_t * p)104 SV * Rmpz_init_set_nobless(pTHX_ mpz_t * p) {
105 mpz_t * mpz_t_obj;
106 SV * obj_ref, * obj;
107
108 New(1, mpz_t_obj, 1, mpz_t);
109 if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_init_set_nobless function");
110 obj_ref = newSV(0);
111 obj = newSVrv(obj_ref, NULL);
112 mpz_init_set(*mpz_t_obj, *p);
113
114 sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
115 SvREADONLY_on(obj);
116 return obj_ref;
117 }
118
Rmpz_init_set_ui_nobless(pTHX_ SV * p)119 SV * Rmpz_init_set_ui_nobless(pTHX_ SV * p) {
120 mpz_t * mpz_t_obj;
121 SV * obj_ref, * obj;
122
123 New(1, mpz_t_obj, 1, mpz_t);
124 if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_init_set_ui_nobless function");
125 obj_ref = newSV(0);
126 obj = newSVrv(obj_ref, NULL);
127 mpz_init_set_ui(*mpz_t_obj, SvUV(p));
128
129 sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
130 SvREADONLY_on(obj);
131 return obj_ref;
132 }
133
Rmpz_init_set_si_nobless(pTHX_ SV * p)134 SV * Rmpz_init_set_si_nobless(pTHX_ SV * p) {
135 mpz_t * mpz_t_obj;
136 SV * obj_ref, * obj;
137
138 New(1, mpz_t_obj, 1, mpz_t);
139 if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_init_set_si_nobless function");
140 obj_ref = newSV(0);
141 obj = newSVrv(obj_ref, NULL);
142 mpz_init_set_si(*mpz_t_obj, SvIV(p));
143
144 sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
145 SvREADONLY_on(obj);
146 return obj_ref;
147 }
148
149
Rmpz_init_set_d_nobless(pTHX_ SV * p)150 SV * Rmpz_init_set_d_nobless(pTHX_ SV * p) {
151 mpz_t * mpz_t_obj;
152 SV * obj_ref, * obj;
153 double d = SvNV(p);
154
155 if(d != d) croak("In Rmpz_set_d, cannot coerce a NaN to a Math::GMPz value");
156 if(d != 0 && (d / d != 1))
157 croak("In Rmpz_init_set_d_nobless, cannot coerce an Inf to a Math::GMPz value");
158
159 New(1, mpz_t_obj, 1, mpz_t);
160 if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_init_set_d_nobless function");
161 obj_ref = newSV(0);
162 obj = newSVrv(obj_ref, NULL);
163 mpz_init_set_d(*mpz_t_obj, d);
164
165 sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
166 SvREADONLY_on(obj);
167 return obj_ref;
168 }
169
Rmpz_init(pTHX)170 SV * Rmpz_init(pTHX) {
171 mpz_t * mpz_t_obj;
172 SV * obj_ref, * obj;
173
174 New(1, mpz_t_obj, 1, mpz_t);
175 if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_init function");
176 obj_ref = newSV(0);
177 obj = newSVrv(obj_ref, "Math::GMPz");
178 mpz_init(*mpz_t_obj);
179
180 sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
181 SvREADONLY_on(obj);
182 return obj_ref;
183 }
184
Rmpz_init_set(pTHX_ mpz_t * p)185 SV * Rmpz_init_set(pTHX_ mpz_t * p) {
186 mpz_t * mpz_t_obj;
187 SV * obj_ref, * obj;
188
189 New(1, mpz_t_obj, 1, mpz_t);
190 if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_init_set function");
191 obj_ref = newSV(0);
192 obj = newSVrv(obj_ref, "Math::GMPz");
193 mpz_init_set(*mpz_t_obj, *p);
194
195 sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
196 SvREADONLY_on(obj);
197 return obj_ref;
198 }
199
Rmpz_init_set_ui(pTHX_ SV * p)200 SV * Rmpz_init_set_ui(pTHX_ SV * p) {
201 mpz_t * mpz_t_obj;
202 SV * obj_ref, * obj;
203
204 New(1, mpz_t_obj, 1, mpz_t);
205 if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_init_set_ui function");
206 obj_ref = newSV(0);
207 obj = newSVrv(obj_ref, "Math::GMPz");
208 mpz_init_set_ui(*mpz_t_obj, SvUV(p));
209
210 sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
211 SvREADONLY_on(obj);
212 return obj_ref;
213 }
214
Rmpz_init_set_si(pTHX_ SV * p)215 SV * Rmpz_init_set_si(pTHX_ SV * p) {
216 mpz_t * mpz_t_obj;
217 SV * obj_ref, * obj;
218
219 New(1, mpz_t_obj, 1, mpz_t);
220 if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_init_set_si function");
221 obj_ref = newSV(0);
222 obj = newSVrv(obj_ref, "Math::GMPz");
223 mpz_init_set_si(*mpz_t_obj, SvIV(p));
224
225 sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
226 SvREADONLY_on(obj);
227 return obj_ref;
228 }
229
Rmpz_set_uj(mpz_t * copy,UV original)230 void Rmpz_set_uj(mpz_t * copy, UV original) {
231 #ifdef MATH_GMPZ_NEED_LONG_LONG_INT
232 mpz_set_ui(*copy, original >> 32);
233 if(mpz_cmp_ui(*copy, 0))
234 mpz_mul_2exp(*copy, *copy, 32);
235 mpz_add_ui(*copy, *copy, original & 4294967295);
236
237 #else
238 croak("Rmpz_set_uj function not implemented on this build of perl");
239
240 #endif
241
242 }
243
Rmpz_set_sj(mpz_t * copy,IV original)244 void Rmpz_set_sj(mpz_t * copy, IV original) {
245 #ifdef MATH_GMPZ_NEED_LONG_LONG_INT
246 if(original >= 0) Rmpz_set_uj(copy, original);
247 else {
248 Rmpz_set_uj(copy, -original);
249 mpz_neg(*copy, *copy);
250 }
251
252 #else
253 croak("Rmpz_set_sj function not implemented on this build of perl");
254
255 #endif
256
257 }
258
259 /* also handles UV values */
260
Rmpz_set_IV(pTHX_ mpz_t * copy,SV * original)261 void Rmpz_set_IV(pTHX_ mpz_t * copy, SV * original) {
262
263 if(SV_IS_IOK(original)) {
264 #ifndef MATH_GMPZ_NEED_LONG_LONG_INT
265 if(SvUOK(original)) mpz_set_ui(*copy, SvUVX(original));
266 else mpz_set_si(*copy, SvIVX(original));
267 }
268
269 #else
270 if(SvUOK(original)) Rmpz_set_uj(copy, SvUVX(original));
271 else Rmpz_set_sj(copy, SvIVX(original));
272 }
273
274 #endif
275 else croak("Arg provided to Rmpz_set_IV is not an IV");
276 }
277
278 /* also handles UV values */
Rmpz_init_set_IV(pTHX_ SV * p)279 SV * Rmpz_init_set_IV(pTHX_ SV * p) {
280 mpz_t * mpz_t_obj;
281 SV * obj_ref, * obj;
282
283 New(1, mpz_t_obj, 1, mpz_t);
284 if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_init_set_IV function");
285 obj_ref = newSV(0);
286 obj = newSVrv(obj_ref, "Math::GMPz");
287
288 mpz_init(*mpz_t_obj);
289
290 sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
291 Rmpz_set_IV(aTHX_ mpz_t_obj, p);
292 SvREADONLY_on(obj);
293 return obj_ref;
294 }
295
296 /* also handles UV values */
Rmpz_init_set_IV_nobless(pTHX_ SV * p)297 SV * Rmpz_init_set_IV_nobless(pTHX_ SV * p) {
298 mpz_t * mpz_t_obj;
299 SV * obj_ref, * obj;
300
301 New(1, mpz_t_obj, 1, mpz_t);
302 if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_init_set_IV_nobless function");
303 obj_ref = newSV(0);
304 obj = newSVrv(obj_ref, "NULL");
305
306 mpz_init(*mpz_t_obj);
307
308 sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
309 Rmpz_set_IV(aTHX_ mpz_t_obj, p);
310 SvREADONLY_on(obj);
311 return obj_ref;
312 }
313
314 /* also handles UV values */
_Rmpz_get_IV(pTHX_ mpz_t * n)315 SV * _Rmpz_get_IV(pTHX_ mpz_t * n) {
316
317 #ifdef MATH_GMPZ_NEED_LONG_LONG_INT
318
319 int negative = 0;
320 char * out;
321 SV * outsv;
322 mpz_t temp;
323 mpz_t _uv_max;
324 mpz_t _iv_max;
325 mpz_t _iv_min;
326
327 #endif
328
329 if(mpz_fits_slong_p(*n))
330 return newSViv(mpz_get_si(*n));
331
332 if(mpz_fits_ulong_p(*n))
333 return newSVuv(mpz_get_ui(*n));
334
335 #ifndef MATH_GMPZ_NEED_LONG_LONG_INT
336
337 if(mpz_cmp_ui(*n, 0) > 0)
338 return newSVuv(mpz_get_ui(*n));
339
340 return newSViv(mpz_get_si(*n));
341
342 #else
343
344 if(mpz_sgn(*n) < 0) negative = 1;
345
346 Newxz(out, 24, char);
347 if(out == NULL)
348 croak("Failed to allocate memory in Rmpz_get_IV function");
349
350 if(negative) { /* must be less than LONG_MIN */
351 mpz_init_set_str(_iv_min, SvPV_nolen(MATH_GMPz_IV_MIN(aTHX)), 10);
352 if(mpz_cmp(*n, _iv_min) < 0) { /* must be less than IV_MIN */
353 mpz_clear(_iv_min);
354 mpz_init(temp);
355 mpz_init_set_str(_iv_max, SvPV_nolen(MATH_GMPz_IV_MAX(aTHX)), 10);
356 mpz_abs(temp, *n);
357 mpz_and(temp, temp, _iv_max);
358 mpz_clear(_iv_max);
359 mpz_neg(temp, temp);
360 mpz_get_str(out, 10, temp);
361 mpz_clear(temp);
362 outsv = newSVpv(out, 0);
363 Safefree(out);
364 return outsv;
365 }
366 else { /* must fit into an IV */
367 mpz_clear(_iv_min);
368 mpz_get_str(out, 10, *n);
369 outsv = newSVpv(out, 0);
370 Safefree(out);
371 return outsv;
372 }
373 }
374 else { /* it's +ve */
375 mpz_init_set_str(_uv_max, SvPV_nolen(MATH_GMPz_UV_MAX(aTHX)), 10);
376 if(mpz_cmp(*n, _uv_max) > 0) { /* needs to be truncated */
377 mpz_init_set(temp, *n);
378 mpz_and(temp, temp, _uv_max);
379 mpz_clear(_uv_max);
380 mpz_get_str(out, 10, temp);
381 mpz_clear(temp);
382 outsv = newSVpv(out, 0);
383 Safefree(out);
384 return outsv;
385 }
386 else { /* must fit into a UV */
387 mpz_clear(_uv_max);
388 mpz_get_str(out, 10, *n);
389 outsv = newSVpv(out, 0);
390 Safefree(out);
391 return outsv;
392 }
393 }
394
395 #endif
396 }
397
398 /* also handles UVs */
Rmpz_fits_IV_p(pTHX_ mpz_t * n)399 int Rmpz_fits_IV_p(pTHX_ mpz_t * n) {
400
401 #ifndef MATH_GMPZ_NEED_LONG_LONG_INT
402 if(mpz_fits_slong_p(*n) || mpz_fits_ulong_p(*n)) return 1;
403 return 0;
404 #else
405 mpz_t t;
406
407 if(mpz_fits_slong_p(*n) || mpz_fits_ulong_p(*n)) return 1;
408
409 mpz_init_set_str(t, SvPV_nolen(MATH_GMPz_UV_MAX(aTHX)), 10);
410 if(mpz_cmp(*n, t) > 0) {
411 mpz_clear(t);
412 return 0;
413 }
414
415 mpz_set_str(t, SvPV_nolen(MATH_GMPz_IV_MIN(aTHX)), 10);
416 if(mpz_cmp(*n, t) < 0) {
417 mpz_clear(t);
418 return 0;
419 }
420
421 mpz_clear(t);
422 return 1;
423
424 #endif
425 }
426
Rmpz_get_d(mpz_t * n)427 double Rmpz_get_d(mpz_t * n) {
428 return mpz_get_d(*n);
429 }
430
Rmpz_get_NV(mpz_t * n)431 NV Rmpz_get_NV(mpz_t * n) {
432
433 #if NVSIZE == 8
434 return mpz_get_d(*n);
435
436 #else
437 /* Rely on strtold/strtoflt128 to correctly handle *
438 * the stringified form of the mpz_t argument */
439 NV d;
440 char * out;
441
442 Newxz(out, mpz_sizeinbase(*n, 10) + 3, char);
443 if(out == NULL) croak("Failed to allocate memory in Rmpz_get_NV function");
444
445 mpz_get_str(out, 10, *n);
446
447 # if defined(USE_LONG_DOUBLE)
448 d = strtold(out, NULL);
449
450 # elif defined(USE_QUADMATH)
451 d = strtoflt128(out, NULL);
452
453 # else
454 Safefree(out);
455 croak("Unrecognized nvtype");
456
457 # endif
458 Safefree(out);
459 return d;
460
461 #endif
462 }
463
464 /* also handles UV values */
465
Rmpz_cmp_IV(pTHX_ mpz_t * z,SV * iv)466 int Rmpz_cmp_IV(pTHX_ mpz_t * z, SV * iv) {
467 int ret;
468
469 #ifndef MATH_GMPZ_NEED_LONG_LONG_INT
470 if(SV_IS_IOK(iv)) {
471 if(SvUOK(iv)) ret = mpz_cmp_ui(*z, SvUVX(iv));
472 else ret = mpz_cmp_si(*z, SvIVX(iv));
473 return ret;
474 }
475 else croak("Arg provided to Rmpz_cmp_IV is not an IV");
476 #else
477 mpz_t temp;
478 if(SV_IS_IOK(iv)) mpz_init_set_str(temp, SvPV_nolen(iv), 10);
479 else croak("Arg provided to Rmpz_cmp_IV is not an IV");
480 ret = mpz_cmp(*z, temp);
481 mpz_clear(temp);
482 return ret;
483 #endif
484
485
486 }
487
Rmpz_init_set_d(pTHX_ SV * p)488 SV * Rmpz_init_set_d(pTHX_ SV * p) {
489 mpz_t * mpz_t_obj;
490 SV * obj_ref, * obj;
491 double d = SvNV(p);
492
493 if(d != d) croak("In Rmpz_init_set_d, cannot coerce a NaN to a Math::GMPz value");
494 if(d != 0 && (d / d != 1))
495 croak("In Rmpz_init_set_d, cannot coerce an Inf to a Math::GMPz value");
496
497 New(1, mpz_t_obj, 1, mpz_t);
498 if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_init_set_d function");
499 obj_ref = newSV(0);
500 obj = newSVrv(obj_ref, "Math::GMPz");
501 mpz_init_set_d(*mpz_t_obj, d);
502
503 sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
504 SvREADONLY_on(obj);
505 return obj_ref;
506 }
507
_mpf_set_dd(mpf_t * q,SV * p)508 void _mpf_set_dd(mpf_t * q, SV * p) {
509 #if defined(NV_IS_DOUBLEDOUBLE) /* double-double */
510 double msd; /* Most Significant Double */
511 mpf_t t, d;
512 long double lsd; /* Will be assigned the Least Siginficant Double */
513
514 msd = (double)SvNV(p);
515 if(msd != 0.0) {
516 if(msd != msd) croak("In _Rmpf_set_ld, cannot coerce a NaN to a Math::GMPf object");
517 if(msd / msd != 1.0) croak("In _Rmpf_set_ld, cannot coerce an Inf to a Math::GMPf object");
518 }
519
520 lsd = SvNV(p) - (long double)msd;
521
522 mpf_init2(t, 2098);
523 mpf_init2(d, 53);
524 mpf_set_d(t, msd);
525 mpf_set_d(d, (double)lsd);
526 mpf_add(t, t, d);
527
528 mpf_clear(d);
529
530 mpf_set(*q, t);
531
532 mpf_clear(t);
533 #else
534 croak("_mpf_set_dd is unavailable because NV is not DoubleDouble");
535
536 #endif
537 }
538
Rmpz_set_NV(pTHX_ mpz_t * copy,SV * original)539 void Rmpz_set_NV(pTHX_ mpz_t * copy, SV * original) {
540 NV nv;
541
542 #if defined(USE_QUADMATH) || defined(USE_LONG_DOUBLE)
543 # if defined(NV_IS_DOUBLEDOUBLE)
544 mpf_t f;
545
546 # else
547 NV buffer_size;
548 int returned;
549 char * buffer;
550
551 # endif
552
553 #endif
554
555 if(!SV_IS_NOK(original))
556 croak("In Rmpz_set_NV, 2nd argument is not an NV");
557
558 nv = SvNV(original); /* First check that the NV flag is set *
559 * else flags of "original" might change */
560
561 if(nv != nv) croak("In Rmpz_set_NV, cannot coerce a NaN to a Math::GMPz value");
562
563 if(nv != 0 && (nv / nv != 1))
564 croak("In Rmpz_set_NV, cannot coerce an Inf to a Math::GMPz value");
565
566 #if defined(USE_QUADMATH)
567 buffer_size = nv < 0.0Q ? nv * -1.0Q : nv;
568 buffer_size = ceilq(logq(buffer_size + 1) / 2.30258509299404568401799145468436418Q);
569
570 Newxz(buffer, (int)buffer_size + 5, char);
571
572 nv = nv >= 0 ? floorq(nv) : ceilq(nv);
573
574 returned = quadmath_snprintf(buffer, (size_t)buffer_size + 5, "%.0Qf", nv);
575 if(returned < 0) croak("In Rmpz_set_NV, encoding error in quadmath_snprintf function");
576 if(returned >= buffer_size + 5) croak("In Rmpz_set_NV, buffer given to quadmath_snprintf function was too small");
577 mpz_set_str(*copy, buffer, 10);
578 Safefree(buffer);
579
580 #elif defined(USE_LONG_DOUBLE)
581 # if defined(NV_IS_DOUBLEDOUBLE)
582 mpf_init2(f, 2098);
583 _mpf_set_dd(&f, original);
584 mpz_set_f(*copy, f);
585 mpf_clear(f);
586
587 # else
588 buffer_size = nv < 0.0L ? nv * -1.0L : nv;
589 buffer_size = ceill(logl(buffer_size + 1) / 2.30258509299404568401799145468436418L);
590 Newxz(buffer, buffer_size + 5, char);
591
592 nv = nv >= 0 ? floorl(nv) : ceill(nv);
593 if(sprintf(buffer, "%.0Lf", nv) >= (int)buffer_size + 5) croak("In Rmpz_set_NV, buffer overflow in sprintf function");
594
595 mpz_set_str(*copy, buffer, 10);
596 Safefree(buffer);
597
598 # endif
599
600 #else
601 mpz_set_d(*copy, nv);
602
603 #endif
604 }
605
Rmpz_init_set_NV(pTHX_ SV * p)606 SV * Rmpz_init_set_NV(pTHX_ SV * p) {
607 mpz_t * mpz_t_obj;
608 SV * obj_ref, * obj;
609
610 Newx(mpz_t_obj, 1, mpz_t);
611 if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_init_set_NV function");
612 obj_ref = newSV(0);
613 obj = newSVrv(obj_ref, "Math::GMPz");
614
615 mpz_init(*mpz_t_obj);
616
617 sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
618 Rmpz_set_NV(aTHX_ mpz_t_obj, p);
619 SvREADONLY_on(obj);
620 return obj_ref;
621 }
622
Rmpz_init_set_NV_nobless(pTHX_ SV * p)623 SV * Rmpz_init_set_NV_nobless(pTHX_ SV * p) {
624 mpz_t * mpz_t_obj;
625 SV * obj_ref, * obj;
626
627 Newx(mpz_t_obj, 1, mpz_t);
628 if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_init_set_NV_nobless function");
629 obj_ref = newSV(0);
630 obj = newSVrv(obj_ref, "NULL");
631
632 mpz_init(*mpz_t_obj);
633
634 sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
635 Rmpz_set_NV(aTHX_ mpz_t_obj, p);
636 SvREADONLY_on(obj);
637 return obj_ref;
638 }
639
Rmpz_init_set_str(pTHX_ SV * num,SV * base)640 SV * Rmpz_init_set_str(pTHX_ SV * num, SV * base) {
641 mpz_t * mpz_t_obj;
642 int b = (int)SvUV(base);
643 SV * obj_ref, * obj;
644
645 if(b == 1 || b > 62) croak("Second argument supplied to Rmpz_init_set_str is not in acceptable range");
646
647 New(1, mpz_t_obj, 1, mpz_t);
648 if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_init_set_str function");
649 if(mpz_init_set_str (*mpz_t_obj, SvPV_nolen(num), b))
650 croak("First argument supplied to Rmpz_init_set_str is not a valid base %u integer", b);
651
652 obj_ref = newSV(0);
653 obj = newSVrv(obj_ref, "Math::GMPz");
654 sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
655 SvREADONLY_on(obj);
656 return obj_ref;
657
658 }
659
Rmpz_init2(pTHX_ SV * bits)660 SV * Rmpz_init2(pTHX_ SV * bits) {
661 mpz_t * mpz_t_obj;
662 SV * obj_ref, * obj;
663
664 New(1, mpz_t_obj, 1, mpz_t);
665 if(mpz_t_obj == NULL) croak("Failed to allocate memory in Rmpz_init2 function");
666 obj_ref = newSV(0);
667 obj = newSVrv(obj_ref, "Math::GMPz");
668 mpz_init2 (*mpz_t_obj, SvUV(bits));
669
670 sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
671 SvREADONLY_on(obj);
672 return obj_ref;
673
674 }
675
Rmpz_get_str(pTHX_ mpz_t * p,SV * base)676 SV * Rmpz_get_str(pTHX_ mpz_t * p, SV * base) {
677 char * out;
678 SV * outsv;
679 int c = (int)SvIV(base), b = (int)SvIV(base);
680
681 if((b > -2 && b < 2) || b < -36 || b > 62) croak("Second argument supplied to Rmpz_get_str is not in acceptable range");
682
683 if(c < 0) c *= -1;
684
685 New(2, out, mpz_sizeinbase(*p, c) + 5, char);
686 if(out == NULL) croak("Failed to allocate memory in Rmpz_deref function");
687
688 mpz_get_str(out, b, *p);
689 outsv = newSVpv(out, 0);
690 Safefree(out);
691 return outsv;
692 }
693
DESTROY(pTHX_ mpz_t * p)694 void DESTROY(pTHX_ mpz_t * p) {
695 /* printf("Destroying mpz "); */
696 mpz_clear(*p);
697 Safefree(p);
698 /* printf("...destroyed\n"); */
699 }
700
Rmpz_clear(pTHX_ mpz_t * p)701 void Rmpz_clear(pTHX_ mpz_t * p) {
702 mpz_clear(*p);
703 Safefree(p);
704 }
705
Rmpz_clear_mpz(mpz_t * p)706 void Rmpz_clear_mpz(mpz_t * p) {
707 mpz_clear(*p);
708 }
709
Rmpz_clear_ptr(pTHX_ mpz_t * p)710 void Rmpz_clear_ptr(pTHX_ mpz_t * p) {
711 Safefree(p);
712 }
713
Rmpz_realloc2(pTHX_ mpz_t * integer,SV * bits)714 void Rmpz_realloc2(pTHX_ mpz_t * integer, SV * bits){
715 mpz_realloc2(*integer, SvUV(bits));
716 }
717
Rmpz_set(mpz_t * copy,mpz_t * original)718 void Rmpz_set(mpz_t * copy, mpz_t * original) {
719 mpz_set(*copy, *original);
720 }
721
Rmpz_set_q(mpz_t * copy,mpq_t * original)722 void Rmpz_set_q(mpz_t * copy, mpq_t * original) {
723 mpz_set_q(*copy, *original);
724 }
725
Rmpz_set_f(mpz_t * copy,mpf_t * original)726 void Rmpz_set_f(mpz_t * copy, mpf_t * original) {
727 mpz_set_f(*copy, *original);
728 }
729
Rmpz_set_si(mpz_t * copy,long original)730 void Rmpz_set_si(mpz_t * copy, long original) {
731 mpz_set_si(*copy, original);
732 }
733
Rmpz_set_ui(mpz_t * copy,unsigned long original)734 void Rmpz_set_ui(mpz_t * copy, unsigned long original) {
735 mpz_set_ui(*copy, original);
736 }
737
Rmpz_set_d(mpz_t * copy,double d)738 void Rmpz_set_d(mpz_t * copy, double d) {
739
740 if(d != d) croak("In Rmpz_set_d, cannot coerce a NaN to a Math::GMPz value");
741 if(d != 0 && (d / d != 1))
742 croak("In Rmpz_set_d, cannot coerce an Inf to a Math::GMPz value");
743 mpz_set_d(*copy, d);
744 }
745
Rmpz_set_str(pTHX_ mpz_t * copy,SV * original,int base)746 void Rmpz_set_str(pTHX_ mpz_t * copy, SV * original, int base) {
747 if(base == 1 || base > 62) croak("Second argument supplied to Rmpz_set_str is not in acceptable range");
748 if(mpz_set_str(*copy, SvPV_nolen(original), base))
749 croak("Second argument supplied to Rmpz_set_str is not a valid base %u integer", base);
750 }
751
Rmpz_swap(mpz_t * a,mpz_t * b)752 void Rmpz_swap(mpz_t * a, mpz_t * b) {
753 mpz_swap(*a, *b);
754 }
755
Rmpz_get_ui(mpz_t * n)756 unsigned long Rmpz_get_ui(mpz_t * n) {
757 return mpz_get_ui(*n);
758 }
759
Rmpz_get_si(mpz_t * n)760 long Rmpz_get_si(mpz_t * n) {
761 return mpz_get_si(*n);
762 }
763
Rmpz_get_d_2exp(pTHX_ mpz_t * n)764 void Rmpz_get_d_2exp(pTHX_ mpz_t * n) {
765 dXSARGS;
766 double d;
767 long exp;
768
769 d = mpz_get_d_2exp(&exp, *n);
770
771 /* sp = mark; */ /* not needed */
772 EXTEND(SP, 2);
773 ST(0) = sv_2mortal(newSVnv(d));
774 ST(1) = sv_2mortal(newSVuv(exp));
775 /* PUTBACK; */ /* not needed */
776 XSRETURN(2);
777 }
778
Rmpz_getlimbn(pTHX_ mpz_t * p,SV * n)779 SV * Rmpz_getlimbn(pTHX_ mpz_t * p, SV * n) {
780 return newSVuv(mpz_getlimbn(*p, SvUV(n)));
781 }
782
Rmpz_add(mpz_t * dest,mpz_t * src1,mpz_t * src2)783 void Rmpz_add(mpz_t * dest, mpz_t * src1, mpz_t * src2) {
784 mpz_add(*dest, *src1, *src2 );
785 }
786
Rmpz_add_ui(mpz_t * dest,mpz_t * src,unsigned long num)787 void Rmpz_add_ui(mpz_t * dest, mpz_t * src, unsigned long num) {
788 mpz_add_ui(*dest, *src, num);
789 /* return sv_setref_pv(newSViv(0), Nullch, INT2PTR(mpz_t *, SvIVX(SvRV(dest)))); */
790 }
791
Rmpz_sub(mpz_t * dest,mpz_t * src1,mpz_t * src2)792 void Rmpz_sub(mpz_t * dest, mpz_t * src1, mpz_t * src2) {
793 mpz_sub(*dest, *src1, *src2 );
794 }
795
Rmpz_sub_ui(mpz_t * dest,mpz_t * src,unsigned long num)796 void Rmpz_sub_ui(mpz_t * dest, mpz_t * src, unsigned long num) {
797 mpz_sub_ui(*dest, *src, num);
798 }
799
Rmpz_ui_sub(mpz_t * dest,unsigned long num,mpz_t * src)800 void Rmpz_ui_sub(mpz_t * dest, unsigned long num, mpz_t * src) {
801 mpz_ui_sub(*dest, num, *src);
802 }
803
Rmpz_mul(mpz_t * dest,mpz_t * src1,mpz_t * src2)804 void Rmpz_mul(mpz_t * dest, mpz_t * src1, mpz_t * src2) {
805 mpz_mul(*dest, *src1, *src2 );
806 }
807
Rmpz_mul_si(mpz_t * dest,mpz_t * src,long num)808 void Rmpz_mul_si(mpz_t * dest, mpz_t * src, long num) {
809 mpz_mul_si(*dest, *src, num);
810 }
811
812 /* NOT TO BE USED
813 void overload_mul_expt(SV * op, SV * iv, SV * unused) {
814 mpz_mul_si(*(INT2PTR(mpz_t *, SvIVX(SvRV(op)))),
815 *(INT2PTR(mpz_t *, SvIVX(SvRV(op)))),
816 SvIV(iv));
817 }
818 */
819
Rmpz_mul_ui(mpz_t * dest,mpz_t * src,unsigned long num)820 void Rmpz_mul_ui(mpz_t * dest, mpz_t * src, unsigned long num) {
821 mpz_mul_ui(*dest, *src, num);
822 }
823
Rmpz_addmul(mpz_t * dest,mpz_t * src1,mpz_t * src2)824 void Rmpz_addmul(mpz_t * dest, mpz_t * src1, mpz_t * src2) {
825 mpz_addmul(*dest, *src1, *src2 );
826 }
827
Rmpz_addmul_ui(mpz_t * dest,mpz_t * src,unsigned long num)828 void Rmpz_addmul_ui(mpz_t * dest, mpz_t * src, unsigned long num) {
829 mpz_addmul_ui(*dest, *src, num);
830 }
831
Rmpz_submul(mpz_t * dest,mpz_t * src1,mpz_t * src2)832 void Rmpz_submul(mpz_t * dest, mpz_t * src1, mpz_t * src2) {
833 mpz_submul(*dest, *src1, *src2 );
834 }
835
Rmpz_submul_ui(mpz_t * dest,mpz_t * src,unsigned long num)836 void Rmpz_submul_ui(mpz_t * dest, mpz_t * src, unsigned long num) {
837 mpz_submul_ui(*dest, *src, num);
838 }
839
Rmpz_mul_2exp(pTHX_ mpz_t * dest,mpz_t * src1,SV * b)840 void Rmpz_mul_2exp(pTHX_ mpz_t * dest, mpz_t * src1, SV * b) {
841
842 CHECK_MP_BITCNT_T_OVERFLOW(b)
843
844 mpz_mul_2exp(*dest, *src1, (mp_bitcnt_t)SvUVX(b));
845 }
846
Rmpz_div_2exp(pTHX_ mpz_t * dest,mpz_t * src1,SV * b)847 void Rmpz_div_2exp(pTHX_ mpz_t * dest, mpz_t * src1, SV * b) {
848
849 CHECK_MP_BITCNT_T_OVERFLOW(b)
850
851 mpz_div_2exp(*dest, *src1, (mp_bitcnt_t)SvUVX(b));
852 }
853
Rmpz_neg(mpz_t * dest,mpz_t * src)854 void Rmpz_neg(mpz_t * dest, mpz_t * src) {
855 mpz_neg(*dest, *src );
856 }
857
Rmpz_abs(mpz_t * dest,mpz_t * src)858 void Rmpz_abs(mpz_t * dest, mpz_t * src) {
859 mpz_abs(*dest, *src );
860 }
861
Rmpz_cdiv_q(mpz_t * q,mpz_t * n,mpz_t * d)862 void Rmpz_cdiv_q( mpz_t * q, mpz_t * n, mpz_t * d) {
863 if(!mpz_cmp_ui(*d, 0))
864 croak("Division by 0 not allowed in Rmpz_cdiv_q");
865 mpz_cdiv_q(*q, *n, *d);
866 }
867
Rmpz_cdiv_r(mpz_t * mod,mpz_t * n,mpz_t * d)868 void Rmpz_cdiv_r( mpz_t * mod, mpz_t * n, mpz_t * d) {
869 if(!mpz_cmp_ui(*d, 0))
870 croak("Division by 0 not allowed in Rmpz_cdiv_r");
871 mpz_cdiv_r(*mod, *n, *d);
872 }
873
Rmpz_cdiv_qr(mpz_t * q,mpz_t * r,mpz_t * n,mpz_t * d)874 void Rmpz_cdiv_qr( mpz_t * q, mpz_t * r, mpz_t * n, mpz_t * d) {
875 if(!mpz_cmp_ui(*d, 0))
876 croak("Division by 0 not allowed in Rmpz_cdiv_qr");
877 mpz_cdiv_qr(*q, *r, *n, *d);
878 }
879
Rmpz_cdiv_q_ui(mpz_t * q,mpz_t * n,unsigned long d)880 unsigned long Rmpz_cdiv_q_ui( mpz_t * q, mpz_t * n, unsigned long d) {
881 if(d == 0)
882 croak("Division by 0 not allowed in Rmpz_cdiv_q_ui");
883 return mpz_cdiv_q_ui(*q, *n, d);
884 }
885
Rmpz_cdiv_r_ui(mpz_t * q,mpz_t * n,unsigned long d)886 unsigned long Rmpz_cdiv_r_ui( mpz_t * q, mpz_t * n, unsigned long d) {
887 if(d == 0)
888 croak("Division by 0 not allowed in Rmpz_cdiv_r_ui");
889 return mpz_cdiv_r_ui(*q, *n, d);
890 }
891
Rmpz_cdiv_qr_ui(mpz_t * q,mpz_t * r,mpz_t * n,unsigned long d)892 unsigned long Rmpz_cdiv_qr_ui( mpz_t * q, mpz_t * r, mpz_t * n, unsigned long d) {
893 if(d == 0)
894 croak("Division by 0 not allowed in Rmpz_cdiv_qr_ui");
895 return mpz_cdiv_qr_ui(*q, *r, *n, d);
896 }
897
Rmpz_cdiv_ui(mpz_t * n,unsigned long d)898 unsigned long Rmpz_cdiv_ui( mpz_t * n, unsigned long d) {
899 if(d == 0)
900 croak("Division by 0 not allowed in Rmpz_cdiv_ui");
901 return mpz_cdiv_ui(*n, d);
902 }
903
Rmpz_cdiv_q_2exp(pTHX_ mpz_t * q,mpz_t * n,SV * b)904 void Rmpz_cdiv_q_2exp(pTHX_ mpz_t * q, mpz_t * n, SV * b) {
905
906 CHECK_MP_BITCNT_T_OVERFLOW(b)
907
908 mpz_cdiv_q_2exp(*q, *n, (mp_bitcnt_t)SvUVX(b));
909 }
910
Rmpz_cdiv_r_2exp(pTHX_ mpz_t * r,mpz_t * n,SV * b)911 void Rmpz_cdiv_r_2exp(pTHX_ mpz_t * r, mpz_t * n, SV * b) {
912
913 CHECK_MP_BITCNT_T_OVERFLOW(b)
914
915 mpz_cdiv_r_2exp(*r, *n, (mp_bitcnt_t)SvUVX(b));
916 }
917
Rmpz_fdiv_q(mpz_t * q,mpz_t * n,mpz_t * d)918 void Rmpz_fdiv_q( mpz_t * q, mpz_t * n, mpz_t * d) {
919 if(!mpz_cmp_ui(*d, 0))
920 croak("Division by 0 not allowed in Rmpz_fdiv_q");
921 mpz_fdiv_q(*q, *n, *d);
922 }
923
Rmpz_div(mpz_t * q,mpz_t * n,mpz_t * d)924 void Rmpz_div( mpz_t * q, mpz_t * n, mpz_t * d) {
925 if(!mpz_cmp_ui(*d, 0))
926 croak("Division by 0 not allowed in Rmpz_div");
927 mpz_div(*q, *n, *d);
928 }
929
930 /* % mpz-t (modulus) operator */
Rmpz_fdiv_r(mpz_t * mod,mpz_t * n,mpz_t * d)931 void Rmpz_fdiv_r( mpz_t * mod, mpz_t * n, mpz_t * d) {
932 if(!mpz_cmp_ui(*d, 0))
933 croak("Division by 0 not allowed in Rmpz_fdiv_r");
934 mpz_fdiv_r(*mod, *n, *d);
935 }
936
Rmpz_fdiv_qr(mpz_t * q,mpz_t * r,mpz_t * n,mpz_t * d)937 void Rmpz_fdiv_qr( mpz_t * q, mpz_t * r, mpz_t * n, mpz_t * d) {
938 if(!mpz_cmp_ui(*d, 0))
939 croak("Division by 0 not allowed in Rmpz_fdiv_qr");
940 mpz_fdiv_qr(*q, *r, *n, *d);
941 }
942
Rmpz_divmod(mpz_t * q,mpz_t * r,mpz_t * n,mpz_t * d)943 void Rmpz_divmod( mpz_t * q, mpz_t * r, mpz_t * n, mpz_t * d) {
944 if(!mpz_cmp_ui(*d, 0))
945 croak("Division by 0 not allowed in Rmpz_divmod");
946 mpz_divmod(*q, *r, *n, *d);
947 }
948
Rmpz_fdiv_q_ui(mpz_t * q,mpz_t * n,unsigned long d)949 unsigned long Rmpz_fdiv_q_ui( mpz_t * q, mpz_t * n, unsigned long d) {
950 if(d == 0)
951 croak("Division by 0 not allowed in Rmpz_fdiv_q_ui");
952 return mpz_fdiv_q_ui(*q, *n, d);
953 }
954
Rmpz_div_ui(mpz_t * q,mpz_t * n,unsigned long d)955 unsigned long Rmpz_div_ui( mpz_t * q, mpz_t * n, unsigned long d) {
956 if(d == 0)
957 croak("Division by 0 not allowed in Rmpz_div_ui");
958 return mpz_div_ui(*q, *n, d);
959 }
960
Rmpz_fdiv_r_ui(mpz_t * q,mpz_t * n,unsigned long d)961 unsigned long Rmpz_fdiv_r_ui( mpz_t * q, mpz_t * n, unsigned long d) {
962 if(d == 0)
963 croak("Division by 0 not allowed in Rmpz_fdiv_r_ui");
964 return mpz_fdiv_r_ui(*q, *n, d);
965 }
966
Rmpz_fdiv_qr_ui(mpz_t * q,mpz_t * r,mpz_t * n,unsigned long d)967 unsigned long Rmpz_fdiv_qr_ui( mpz_t * q, mpz_t * r, mpz_t * n, unsigned long d) {
968 if(d == 0)
969 croak("Division by 0 not allowed in Rmpz_fdiv_qr_ui");
970 return mpz_fdiv_qr_ui(*q, *r, *n, d);
971 }
972
Rmpz_divmod_ui(mpz_t * q,mpz_t * r,mpz_t * n,unsigned long d)973 unsigned long Rmpz_divmod_ui( mpz_t * q, mpz_t * r, mpz_t * n, unsigned long d) {
974 if(d == 0)
975 croak("Division by 0 not allowed in Rmpz_divmod_ui");
976 return mpz_divmod_ui(*q, *r, *n, d);
977 }
978
979 /* % int (modulus) operator */
Rmpz_fdiv_ui(mpz_t * n,unsigned long d)980 unsigned long Rmpz_fdiv_ui( mpz_t * n, unsigned long d) {
981 if(d == 0)
982 croak("Division by 0 not allowed in Rmpz_fdiv_ui");
983 return mpz_fdiv_ui(*n, d);
984 }
985
Rmpz_fdiv_q_2exp(pTHX_ mpz_t * q,mpz_t * n,SV * b)986 void Rmpz_fdiv_q_2exp(pTHX_ mpz_t * q, mpz_t * n, SV * b) {
987
988 CHECK_MP_BITCNT_T_OVERFLOW(b)
989
990 mpz_fdiv_q_2exp(*q, *n, (mp_bitcnt_t)SvUVX(b));
991 }
992
Rmpz_fdiv_r_2exp(pTHX_ mpz_t * r,mpz_t * n,SV * b)993 void Rmpz_fdiv_r_2exp(pTHX_ mpz_t * r, mpz_t * n, SV * b) {
994
995 CHECK_MP_BITCNT_T_OVERFLOW(b)
996
997 mpz_fdiv_r_2exp(*r, *n, (mp_bitcnt_t)SvUVX(b));
998 }
999
Rmpz_mod_2exp(pTHX_ mpz_t * r,mpz_t * n,SV * b)1000 void Rmpz_mod_2exp(pTHX_ mpz_t * r, mpz_t * n, SV * b) {
1001
1002 CHECK_MP_BITCNT_T_OVERFLOW(b)
1003
1004 mpz_mod_2exp(*r, *n, (mp_bitcnt_t)SvUVX(b));
1005 }
1006
Rmpz_tdiv_q(mpz_t * q,mpz_t * n,mpz_t * d)1007 void Rmpz_tdiv_q( mpz_t * q, mpz_t * n, mpz_t * d) {
1008 if(!mpz_cmp_ui(*d, 0))
1009 croak("Division by 0 not allowed in Rmpz_tdiv_q");
1010 mpz_tdiv_q(*q, *n, *d);
1011 }
1012
1013 /* % mpz-t (modulus) operator */
Rmpz_tdiv_r(mpz_t * mod,mpz_t * n,mpz_t * d)1014 void Rmpz_tdiv_r( mpz_t * mod, mpz_t * n, mpz_t * d) {
1015 if(!mpz_cmp_ui(*d, 0))
1016 croak("Division by 0 not allowed in Rmpz_tdiv_r");
1017 mpz_tdiv_r(*mod, *n, *d);
1018 }
1019
Rmpz_tdiv_qr(mpz_t * q,mpz_t * r,mpz_t * n,mpz_t * d)1020 void Rmpz_tdiv_qr( mpz_t * q, mpz_t * r, mpz_t * n, mpz_t * d) {
1021 if(!mpz_cmp_ui(*d, 0))
1022 croak("Division by 0 not allowed in Rmpz_tdiv_qr");
1023 mpz_tdiv_qr(*q, *r, *n, *d);
1024 }
1025
Rmpz_tdiv_q_ui(mpz_t * q,mpz_t * n,unsigned long d)1026 unsigned long Rmpz_tdiv_q_ui( mpz_t * q, mpz_t * n, unsigned long d) {
1027 if(d == 0)
1028 croak("Division by 0 not allowed in Rmpz_tdiv_q_ui");
1029 return mpz_tdiv_q_ui(*q, *n, d);
1030 }
1031
Rmpz_tdiv_r_ui(mpz_t * q,mpz_t * n,unsigned long d)1032 unsigned long Rmpz_tdiv_r_ui( mpz_t * q, mpz_t * n, unsigned long d) {
1033 if(d == 0)
1034 croak("Division by 0 not allowed in Rmpz_tdiv_r_ui");
1035 return mpz_tdiv_r_ui(*q, *n, d);
1036 }
1037
Rmpz_tdiv_qr_ui(mpz_t * q,mpz_t * r,mpz_t * n,unsigned long d)1038 unsigned long Rmpz_tdiv_qr_ui( mpz_t * q, mpz_t * r, mpz_t * n, unsigned long d) {
1039 if(d == 0)
1040 croak("Division by 0 not allowed in Rmpz_tdiv_qr_ui");
1041 return mpz_tdiv_qr_ui(*q, *r, *n, d);
1042 }
1043
1044 /* % int (modulus) operator */
Rmpz_tdiv_ui(mpz_t * n,unsigned long d)1045 unsigned long Rmpz_tdiv_ui( mpz_t * n, unsigned long d) {
1046 if(d == 0)
1047 croak("Division by 0 not allowed in Rmpz_tdiv_ui");
1048 return mpz_tdiv_ui(*n, d);
1049 }
1050
Rmpz_tdiv_q_2exp(pTHX_ mpz_t * q,mpz_t * n,SV * b)1051 void Rmpz_tdiv_q_2exp(pTHX_ mpz_t * q, mpz_t * n, SV * b) {
1052
1053 CHECK_MP_BITCNT_T_OVERFLOW(b)
1054
1055 mpz_tdiv_q_2exp(*q, *n, (mp_bitcnt_t)SvUVX(b));
1056 }
1057
Rmpz_tdiv_r_2exp(pTHX_ mpz_t * r,mpz_t * n,SV * b)1058 void Rmpz_tdiv_r_2exp(pTHX_ mpz_t * r, mpz_t * n, SV * b) {
1059
1060 CHECK_MP_BITCNT_T_OVERFLOW(b)
1061
1062 mpz_tdiv_r_2exp(*r, *n, (mp_bitcnt_t)SvUVX(b));
1063 }
1064
Rmpz_mod(mpz_t * r,mpz_t * n,mpz_t * d)1065 void Rmpz_mod( mpz_t * r, mpz_t * n, mpz_t * d) {
1066 if(!mpz_cmp_ui(*d, 0))
1067 croak("Division by 0 not allowed in Rmpz_mod");
1068 mpz_mod(*r, *n, *d);
1069 }
1070
Rmpz_mod_ui(mpz_t * r,mpz_t * n,unsigned long d)1071 unsigned long Rmpz_mod_ui( mpz_t * r, mpz_t * n, unsigned long d) {
1072 if(d == 0)
1073 croak("Division by 0 not allowed in Rmpz_mod_ui");
1074 return mpz_mod_ui(*r, *n, d);
1075 }
1076
Rmpz_divexact(mpz_t * dest,mpz_t * n,mpz_t * d)1077 void Rmpz_divexact(mpz_t * dest, mpz_t * n, mpz_t * d) {
1078 if(!mpz_cmp_ui(*d, 0))
1079 croak("Division by 0 not allowed in Rmpz_divexact");
1080 mpz_divexact(*dest, *n, *d );
1081 }
1082
Rmpz_divexact_ui(mpz_t * dest,mpz_t * n,unsigned long d)1083 void Rmpz_divexact_ui(mpz_t * dest, mpz_t * n, unsigned long d) {
1084 if(d == 0)
1085 croak("Division by 0 not allowed in Rmpz_divexact_ui");
1086 mpz_divexact_ui(*dest, *n, d);
1087 }
1088
Rmpz_divisible_p(mpz_t * n,mpz_t * d)1089 int Rmpz_divisible_p(mpz_t * n, mpz_t * d) {
1090 return mpz_divisible_p(*n, *d);
1091 }
1092
Rmpz_divisible_ui_p(mpz_t * n,unsigned long d)1093 int Rmpz_divisible_ui_p(mpz_t * n, unsigned long d) {
1094 return mpz_divisible_ui_p(*n, d);
1095 }
1096
Rmpz_divisible_2exp_p(pTHX_ mpz_t * n,SV * b)1097 int Rmpz_divisible_2exp_p(pTHX_ mpz_t * n, SV * b) {
1098
1099 CHECK_MP_BITCNT_T_OVERFLOW(b)
1100
1101 return mpz_divisible_2exp_p(*n, SvUVX(b));
1102 }
1103
Rmpz_congruent_p(mpz_t * n,mpz_t * c,mpz_t * d)1104 int Rmpz_congruent_p(mpz_t * n, mpz_t * c, mpz_t * d) {
1105 return mpz_congruent_p(*n, *c, *d);
1106 }
1107
Rmpz_congruent_ui_p(mpz_t * n,unsigned long c,unsigned long d)1108 int Rmpz_congruent_ui_p(mpz_t * n, unsigned long c, unsigned long d) {
1109 return mpz_congruent_ui_p(*n, c, d);
1110 }
1111
Rmpz_congruent_2exp_p(pTHX_ mpz_t * n,mpz_t * c,SV * d)1112 SV * Rmpz_congruent_2exp_p(pTHX_ mpz_t * n, mpz_t * c, SV * d) {
1113
1114 CHECK_MP_BITCNT_T_OVERFLOW(d)
1115
1116 return newSViv(mpz_congruent_2exp_p(*n, *c, SvUVX(d)));
1117 }
1118
Rmpz_powm(mpz_t * dest,mpz_t * base,mpz_t * exp,mpz_t * mod)1119 void Rmpz_powm(mpz_t * dest, mpz_t * base, mpz_t * exp, mpz_t * mod) {
1120 mpz_powm(*dest, *base, *exp, *mod);
1121 }
1122
Rmpz_powm_ui(mpz_t * dest,mpz_t * base,unsigned long exp,mpz_t * mod)1123 void Rmpz_powm_ui(mpz_t * dest, mpz_t * base, unsigned long exp, mpz_t * mod) {
1124 mpz_powm_ui(*dest, *base, exp, *mod);
1125 }
1126
Rmpz_pow_ui(mpz_t * dest,mpz_t * base,unsigned long exp)1127 void Rmpz_pow_ui(mpz_t * dest, mpz_t * base, unsigned long exp) {
1128 mpz_pow_ui(*dest, *base, exp);
1129 }
1130
Rmpz_ui_pow_ui(mpz_t * dest,unsigned long base,unsigned long exp)1131 void Rmpz_ui_pow_ui(mpz_t * dest, unsigned long base, unsigned long exp) {
1132 mpz_ui_pow_ui(*dest, base, exp);
1133 }
1134
Rmpz_root(mpz_t * r,mpz_t * n,unsigned long d)1135 int Rmpz_root(mpz_t * r, mpz_t * n, unsigned long d) {
1136 return mpz_root(*r, *n, d);
1137 }
1138
Rmpz_sqrt(mpz_t * r,mpz_t * n)1139 void Rmpz_sqrt(mpz_t * r, mpz_t * n) {
1140 mpz_sqrt(*r, *n);
1141 }
1142
Rmpz_sqrtrem(mpz_t * root,mpz_t * rem,mpz_t * src)1143 void Rmpz_sqrtrem(mpz_t * root, mpz_t * rem, mpz_t * src) {
1144 mpz_sqrtrem(*root, *rem, *src);
1145 }
1146
Rmpz_perfect_power_p(mpz_t * in)1147 int Rmpz_perfect_power_p(mpz_t * in) {
1148 return mpz_perfect_power_p(*in);
1149 }
1150
Rmpz_perfect_square_p(mpz_t * in)1151 int Rmpz_perfect_square_p(mpz_t * in) {
1152 return mpz_perfect_square_p(*in);
1153 }
1154
Rmpz_probab_prime_p(pTHX_ mpz_t * cand,SV * reps)1155 int Rmpz_probab_prime_p(pTHX_ mpz_t * cand, SV * reps) {
1156 return mpz_probab_prime_p(*cand, (int)SvIV(reps));
1157 }
1158
Rmpz_nextprime(mpz_t * prime,mpz_t * init)1159 void Rmpz_nextprime(mpz_t * prime, mpz_t * init) {
1160 mpz_nextprime(*prime, *init);
1161 }
1162
Rmpz_gcd(mpz_t * gcd,mpz_t * src1,mpz_t * src2)1163 void Rmpz_gcd(mpz_t * gcd, mpz_t * src1, mpz_t * src2) {
1164 mpz_gcd(*gcd, *src1, *src2);
1165 }
1166
1167 /* First arg can be either (the unblessed) $Math::GMPz::NULL or a
1168 * (blessed) Math::GMPz object.
1169 */
Rmpz_gcd_ui(mpz_t * gcd,mpz_t * n,unsigned long d)1170 unsigned long Rmpz_gcd_ui(mpz_t * gcd, mpz_t * n, unsigned long d) {
1171 return mpz_gcd_ui(*gcd, *n, d);
1172 }
1173
Rmpz_gcdext(mpz_t * g,mpz_t * s,mpz_t * t,mpz_t * a,mpz_t * b)1174 void Rmpz_gcdext(mpz_t * g, mpz_t * s, mpz_t * t, mpz_t * a, mpz_t * b) {
1175 mpz_gcdext(*g, *s, *t, *a, *b);
1176 }
1177
Rmpz_lcm(mpz_t * lcm,mpz_t * src1,mpz_t * src2)1178 void Rmpz_lcm(mpz_t * lcm, mpz_t * src1, mpz_t * src2) {
1179 mpz_lcm(*lcm, *src1, *src2);
1180 }
1181
Rmpz_lcm_ui(mpz_t * lcm,mpz_t * src1,unsigned long src2)1182 void Rmpz_lcm_ui(mpz_t * lcm, mpz_t * src1, unsigned long src2) {
1183 mpz_lcm_ui(*lcm, *src1, src2);
1184 }
1185
Rmpz_invert(mpz_t * inv,mpz_t * src1,mpz_t * src2)1186 int Rmpz_invert(mpz_t * inv, mpz_t * src1, mpz_t * src2) {
1187 return mpz_invert(*inv, *src1, *src2);
1188 }
1189
Rmpz_jacobi(mpz_t * a,mpz_t * b)1190 int Rmpz_jacobi(mpz_t * a, mpz_t * b) {
1191 return mpz_jacobi(*a, *b);
1192 }
1193
Rmpz_legendre(mpz_t * a,mpz_t * b)1194 int Rmpz_legendre(mpz_t * a, mpz_t * b) {
1195 return mpz_legendre(*a, *b);
1196 }
1197
Rmpz_kronecker(mpz_t * a,mpz_t * b)1198 int Rmpz_kronecker(mpz_t * a, mpz_t * b) {
1199 return mpz_kronecker(*a, *b);
1200 }
1201
Rmpz_kronecker_si(mpz_t * a,long b)1202 int Rmpz_kronecker_si(mpz_t * a, long b) {
1203 return mpz_kronecker_si(*a, b);
1204 }
1205
Rmpz_kronecker_ui(mpz_t * a,unsigned long b)1206 int Rmpz_kronecker_ui(mpz_t * a, unsigned long b) {
1207 return mpz_kronecker_ui(*a, b);
1208 }
1209
Rmpz_si_kronecker(long a,mpz_t * b)1210 int Rmpz_si_kronecker(long a, mpz_t * b) {
1211 return mpz_si_kronecker(a, *b);
1212 }
1213
Rmpz_ui_kronecker(unsigned long a,mpz_t * b)1214 int Rmpz_ui_kronecker(unsigned long a, mpz_t * b) {
1215 return mpz_ui_kronecker(a, *b);
1216 }
1217
Rmpz_remove(pTHX_ mpz_t * rem,mpz_t * src1,mpz_t * src2)1218 SV * Rmpz_remove(pTHX_ mpz_t * rem, mpz_t * src1, mpz_t * src2) {
1219 return newSVuv(mpz_remove(*rem, *src1, *src2));
1220 }
1221
Rmpz_fac_ui(mpz_t * fac,unsigned long b)1222 void Rmpz_fac_ui(mpz_t * fac, unsigned long b) {
1223 mpz_fac_ui(*fac, b);
1224 }
1225
1226 #if __GNU_MP_VERSION > 5 || (__GNU_MP_VERSION == 5 && __GNU_MP_VERSION_MINOR >= 1)
1227
Rmpz_2fac_ui(mpz_t * fac,unsigned long b)1228 void Rmpz_2fac_ui(mpz_t * fac, unsigned long b) {
1229 mpz_2fac_ui(*fac, b);
1230 }
1231
Rmpz_mfac_uiui(mpz_t * fac,unsigned long b,unsigned long c)1232 void Rmpz_mfac_uiui(mpz_t * fac, unsigned long b, unsigned long c) {
1233 mpz_mfac_uiui(*fac, b, c);
1234 }
1235
Rmpz_primorial_ui(mpz_t * fac,unsigned long b)1236 void Rmpz_primorial_ui(mpz_t * fac, unsigned long b) {
1237 mpz_primorial_ui(*fac, b);
1238 }
1239
1240 #else
1241
Rmpz_2fac_ui(mpz_t * fac,unsigned long b)1242 void Rmpz_2fac_ui(mpz_t * fac, unsigned long b) {
1243 croak("Rmpz_2fac_ui not implemented - gmp-5.1.0 (or later) is needed");
1244 }
1245
Rmpz_mfac_uiui(mpz_t * fac,unsigned long b,unsigned long c)1246 void Rmpz_mfac_uiui(mpz_t * fac, unsigned long b, unsigned long c) {
1247 croak("Rmpz_mfac_uiui not implemented - gmp-5.1.0 (or later) is needed");
1248 }
1249
Rmpz_primorial_ui(mpz_t * fac,unsigned long b)1250 void Rmpz_primorial_ui(mpz_t * fac, unsigned long b) {
1251 croak("Rmpz_primorial_ui not implemented - gmp-5.1.0 (or later) is needed");
1252 }
1253
1254 #endif
1255
Rmpz_bin_ui(mpz_t * dest,mpz_t * n,unsigned long d)1256 void Rmpz_bin_ui(mpz_t * dest, mpz_t * n, unsigned long d) {
1257 mpz_bin_ui(*dest, *n, d);
1258 }
1259
Rmpz_bin_si(mpz_t * dest,mpz_t * n,long d)1260 void Rmpz_bin_si(mpz_t * dest, mpz_t * n, long d) {
1261 signed long int t = d;
1262 if(t >= 0) mpz_bin_ui(*dest, *n, t);
1263 else {
1264 if(mpz_sgn(*n) >= 0 || mpz_cmp_si(*n, t) < 0)
1265 mpz_set_ui(*dest, 0);
1266 else
1267 mpz_bin_ui(*dest, *n, mpz_get_si(*n) - t);
1268 }
1269 }
1270
Rmpz_bin_uiui(mpz_t * dest,unsigned long n,unsigned long d)1271 void Rmpz_bin_uiui(mpz_t * dest, unsigned long n, unsigned long d) {
1272 mpz_bin_uiui(*dest, n, d);
1273 }
1274
Rmpz_fib_ui(mpz_t * dest,unsigned long b)1275 void Rmpz_fib_ui(mpz_t * dest, unsigned long b) {
1276 mpz_fib_ui(*dest, b);
1277 }
1278
Rmpz_fib2_ui(mpz_t * fn,mpz_t * fnsub1,unsigned long b)1279 void Rmpz_fib2_ui(mpz_t * fn, mpz_t * fnsub1, unsigned long b) {
1280 mpz_fib2_ui(*fn, *fnsub1, b);
1281 }
1282
Rmpz_lucnum_ui(mpz_t * dest,unsigned long b)1283 void Rmpz_lucnum_ui(mpz_t * dest, unsigned long b) {
1284 mpz_lucnum_ui(*dest, b);
1285 }
1286
Rmpz_lucnum2_ui(mpz_t * ln,mpz_t * lnsub1,unsigned long b)1287 void Rmpz_lucnum2_ui(mpz_t * ln, mpz_t * lnsub1, unsigned long b) {
1288 mpz_lucnum2_ui(*ln, *lnsub1, b);
1289 }
1290
Rmpz_cmp(mpz_t * n,mpz_t * d)1291 int Rmpz_cmp(mpz_t * n, mpz_t * d) {
1292 return mpz_cmp(*n, *d );
1293 }
1294
Rmpz_cmp_d(mpz_t * n,double d)1295 int Rmpz_cmp_d(mpz_t * n, double d) {
1296 if(d != d) croak("In Rmpz_cmp_d, cannot compare a NaN to a Math::GMPz value");
1297 return mpz_cmp_d(*n, d);
1298 }
1299
Rmpz_cmp_NV(pTHX_ mpz_t * a,SV * b)1300 int Rmpz_cmp_NV(pTHX_ mpz_t * a, SV * b) {
1301
1302 #if defined(USE_QUADMATH)
1303
1304 char * buffer;
1305 int ret, returned;
1306 __float128 buffer_size;
1307 __float128 ld;
1308 mpz_t t;
1309
1310 if(!SvNOK(b))
1311 croak("In Rmpz_cmp_NV, 2nd argument is not an NV");
1312
1313 ld = (__float128)SvNV(b) >= 0 ? floorq((__float128)SvNV(b)) : ceilq((__float128)SvNV(b));
1314 if(ld != ld) croak("In Rmpz_cmp_NV, cannot compare a NaN to a Math::GMPz value");
1315 if((ld != 0 && (ld / ld != 1))) {
1316 if(ld > 0) return -1;
1317 return 1;
1318 }
1319 buffer_size = ld < 0.0Q ? ld * -1.0Q : ld;
1320 buffer_size = ceilq(logq(buffer_size + 1) / 2.30258509299404568401799145468436418Q);
1321 Newxz(buffer, (int)buffer_size + 5, char);
1322
1323 returned = quadmath_snprintf(buffer, (size_t)buffer_size + 5, "%.0Qf", ld);
1324 if(returned < 0) croak("In Rmpz_cmp_NV, encoding error in quadmath_snprintf function");
1325 if(returned >= buffer_size + 5) croak("In Rmpz_cmp_NV, buffer given to quadmath_snprintf function was too small");
1326 mpz_init_set_str(t, buffer, 10);
1327 Safefree(buffer);
1328 ret = mpz_cmp(*a, t);
1329 mpz_clear(t);
1330
1331 if(ld == (__float128)SvNV(b)) return ret;
1332 /* else cannot be equal - ie must be less than or greater than */
1333 if(!ret) {
1334 if(ld >= 0) ret = -1;
1335 else ret = 1;
1336 }
1337
1338 return ret;
1339
1340 #elif defined(USE_LONG_DOUBLE)
1341 long double ld;
1342 int ret;
1343
1344 # if defined(NV_IS_DOUBLEDOUBLE)
1345 mpf_t f, f_trunc;
1346 mpz_t z;
1347
1348 if(!SvNOK(b))
1349 croak("In Rmpz_cmp_NV, 2nd argument is not an NV");
1350
1351 ld = SvNV(b);
1352
1353 if(ld != ld) croak("In Rmpz_cmp_NV, cannot compare a NaN to a Math::GMPz value");
1354 if((ld != 0 && (ld / ld != 1))) {
1355 if(ld > 0) return -1;
1356 return 1;
1357 }
1358
1359 mpf_init2(f, 2098);
1360 mpf_init2(f_trunc, 2098);
1361 mpz_init(z);
1362
1363 _mpf_set_dd(&f, b);
1364 mpf_trunc(f_trunc, f);
1365 mpz_set_f(z, f_trunc);
1366
1367 ret = mpf_cmp(f, f_trunc);
1368
1369 if(ret == 0) {
1370 ret = mpz_cmp(*a, z);
1371 }
1372 else if(ret > 0) {
1373 if(mpz_cmp(*a, z) <= 0) ret = -1;
1374 }
1375
1376 else {
1377 if(mpz_cmp(*a, z) >= 0) ret = 1;
1378 }
1379
1380 mpf_clear(f);
1381 mpf_clear(f_trunc);
1382 mpz_clear(z);
1383 return ret;
1384
1385 # else
1386 char * buffer;
1387 long double buffer_size;
1388 mpz_t t;
1389
1390 if(!SvNOK(b))
1391 croak("In Rmpz_cmp_NV, 2nd argument is not an NV");
1392
1393 ld = SvNV(b);
1394
1395 if(ld != ld) croak("In Rmpz_cmp_NV, cannot compare a NaN to a Math::GMPz value");
1396 if((ld != 0 && (ld / ld != 1))) {
1397 if(ld > 0) return -1;
1398 return 1;
1399 }
1400
1401 ld = ld >= 0 ? floorl((long double)SvNV(b)) : ceill((long double)SvNV(b));
1402
1403 buffer_size = ld < 0.0L ? ld * -1.0L : ld;
1404 buffer_size = ceill(logl(buffer_size + 1) / 2.30258509299404568401799145468436418L);
1405 Newxz(buffer, (int)buffer_size + 5, char);
1406
1407 if(sprintf(buffer, "%.0Lf", ld) >= (int)buffer_size + 5) croak("In Rmpz_cmp_NV, buffer overflow in sprintf function");
1408 mpz_init_set_str(t, buffer, 10);
1409 Safefree(buffer);
1410 ret = mpz_cmp(*a, t);
1411 mpz_clear(t);
1412 if(ld == (long double)SvNV(b)) return ret;
1413 /* else cannot be equal - ie must be less than or greater than */
1414 if(!ret) {
1415 if(ld >= 0) ret = -1;
1416 else ret = 1;
1417 }
1418
1419 return ret;
1420
1421 # endif
1422
1423 #else
1424
1425 if(!SvNOK(b))
1426 croak("In Rmpz_cmp_NV, 2nd argument is not an NV");
1427
1428 if((double)SvNV(b) != (double)SvNV(b))
1429 croak("In Rmpz_cmp_NV, cannot compare a NaN to a Math::GMPz value");
1430
1431 return mpz_cmp_d(*a, (double)SvNV(b));
1432
1433 #endif
1434
1435 }
1436
Rmpz_cmp_si(mpz_t * n,long d)1437 int Rmpz_cmp_si(mpz_t * n, long d) {
1438 return mpz_cmp_si(*n, d);
1439 }
1440
Rmpz_cmp_ui(mpz_t * n,unsigned long d)1441 int Rmpz_cmp_ui(mpz_t * n, unsigned long d) {
1442 return mpz_cmp_ui(*n, d);
1443 }
1444
Rmpz_cmpabs(mpz_t * n,mpz_t * d)1445 int Rmpz_cmpabs(mpz_t * n, mpz_t * d) {
1446 return mpz_cmpabs(*n, *d );
1447 }
1448
Rmpz_cmpabs_d(mpz_t * n,double d)1449 int Rmpz_cmpabs_d(mpz_t * n, double d) {
1450 return mpz_cmpabs_d(*n, d);
1451 }
1452
Rmpz_cmpabs_ui(mpz_t * n,unsigned long d)1453 int Rmpz_cmpabs_ui(mpz_t * n, unsigned long d) {
1454 return mpz_cmpabs_ui(*n, d);
1455 }
1456
Rmpz_sgn(mpz_t * n)1457 int Rmpz_sgn(mpz_t * n) {
1458 return mpz_sgn(*n);
1459 }
1460
Rmpz_and(mpz_t * dest,mpz_t * src1,mpz_t * src2)1461 void Rmpz_and(mpz_t * dest, mpz_t * src1, mpz_t * src2) {
1462 mpz_and(*dest, *src1, *src2 );
1463 }
1464
Rmpz_ior(mpz_t * dest,mpz_t * src1,mpz_t * src2)1465 void Rmpz_ior(mpz_t * dest, mpz_t * src1, mpz_t * src2) {
1466 mpz_ior(*dest, *src1, *src2 );
1467 }
1468
Rmpz_xor(mpz_t * dest,mpz_t * src1,mpz_t * src2)1469 void Rmpz_xor(mpz_t * dest, mpz_t * src1, mpz_t * src2) {
1470 mpz_xor(*dest, *src1, *src2 );
1471 }
1472
Rmpz_com(mpz_t * dest,mpz_t * src)1473 void Rmpz_com(mpz_t * dest, mpz_t * src) {
1474 mpz_com(*dest, *src );
1475 }
1476
Rmpz_popcount(pTHX_ mpz_t * in)1477 SV * Rmpz_popcount(pTHX_ mpz_t * in) {
1478 return newSVuv(mpz_popcount(*in));
1479 }
1480
Rmpz_hamdist(pTHX_ mpz_t * dest,mpz_t * src)1481 SV * Rmpz_hamdist(pTHX_ mpz_t * dest, mpz_t * src) {
1482 return newSVuv(mpz_hamdist(*dest, *src ));
1483 }
1484
Rmpz_scan0(pTHX_ mpz_t * n,SV * start_bit)1485 SV * Rmpz_scan0(pTHX_ mpz_t * n, SV * start_bit) {
1486
1487 CHECK_MP_BITCNT_T_OVERFLOW(start_bit)
1488
1489 return newSVuv(mpz_scan0(*n, (mp_bitcnt_t)SvUV(start_bit)));
1490 }
1491
Rmpz_scan1(pTHX_ mpz_t * n,SV * start_bit)1492 SV * Rmpz_scan1(pTHX_ mpz_t * n, SV * start_bit) {
1493
1494 CHECK_MP_BITCNT_T_OVERFLOW(start_bit)
1495
1496 return newSVuv(mpz_scan1(*n, (mp_bitcnt_t)SvUV(start_bit)));
1497 }
1498
Rmpz_setbit(pTHX_ mpz_t * num,SV * bit_index)1499 void Rmpz_setbit(pTHX_ mpz_t * num, SV * bit_index) {
1500
1501 CHECK_MP_BITCNT_T_OVERFLOW(bit_index)
1502
1503 mpz_setbit(*num, (mp_bitcnt_t)SvUV(bit_index));
1504 }
1505
Rmpz_clrbit(pTHX_ mpz_t * num,SV * bit_index)1506 void Rmpz_clrbit(pTHX_ mpz_t * num, SV * bit_index) {
1507
1508 CHECK_MP_BITCNT_T_OVERFLOW(bit_index)
1509
1510 mpz_clrbit(*num, (mp_bitcnt_t)SvUV(bit_index));
1511 }
1512
Rmpz_tstbit(pTHX_ mpz_t * num,SV * bit_index)1513 SV * Rmpz_tstbit(pTHX_ mpz_t * num, SV * bit_index) {
1514
1515 CHECK_MP_BITCNT_T_OVERFLOW(bit_index)
1516
1517 return newSViv(mpz_tstbit(*num, (mp_bitcnt_t)SvUV(bit_index)));
1518 }
1519
1520 /* Turn a binary string into an mpz_t */
Rmpz_import(pTHX_ mpz_t * rop,SV * count,SV * order,SV * size,SV * endian,SV * nails,SV * op)1521 void Rmpz_import(pTHX_ mpz_t * rop, SV * count, SV * order, SV * size, SV * endian, SV * nails, SV * op){
1522 int is_utf8 = 0;
1523
1524 if(SvUTF8(op) && !SvIV(get_sv("Math::GMPz::utf8_no_downgrade", 0))) {
1525 if(!SvIV(get_sv("Math::GMPz::utf8_no_warn", 0))) {
1526 warn( "%s", RMPZ_IMPORT_UTF8_WARN ); /* RMPZ_IMPORT_UTF8_WARN defined in math_gmpz_include.h */
1527 warn(" To disable this warning set $Math::GMPz::utf8_no_warn to 1.");
1528 }
1529
1530 is_utf8 = 1;
1531 if(!sv_utf8_downgrade(op, SvIV(get_sv("Math::GMPz::utf8_no_croak", 0)))) {
1532 /* downgrade has failed, and this will cause an immediate croak if *
1533 * $Math::GMPz::utf8_no_croak is false. If $Math::GMPz::utf8_no_croak *
1534 * is true && $Math::GMPz::utf8_no_fail is false, we warn as follows: */
1535
1536 if(!SvIV(get_sv("Math::GMPz::utf8_no_fail", 0))) {
1537 /* No need to check status of $Math::GMPz::utf8_no_croak. *
1538 * If we've reached here then it must be true. */
1539 warn("%s", RMPZ_IMPORT_DOWNGRADE_WARN); /*RMPZ_IMPORT_DOWNGRADE_WARN defined in math_gmpz_include.h */
1540 warn(" To disable this warning set $Math::GMPz::utf8_no_fail to 1");
1541 }
1542 }
1543 }
1544
1545 mpz_import(*rop, SvUV(count), SvIV(order), SvIV(size), SvIV(endian), SvUV(nails), SvPV_nolen(op));
1546 if(is_utf8) sv_utf8_upgrade(op);
1547 }
1548
1549 /* Return an mpz_t to a binary string */
Rmpz_export(pTHX_ SV * order,SV * size,SV * endian,SV * nails,mpz_t * op)1550 SV * Rmpz_export(pTHX_ SV * order, SV * size, SV * endian, SV * nails, mpz_t * op) {
1551 SV * outsv;
1552 char * arr;
1553 int count;
1554 int numb = (8 * SvIV(size)) - SvUV(nails);
1555
1556 count = (mpz_sizeinbase (*op, 2) + numb - 1) / numb;
1557
1558 Newxz(arr, count, char);
1559 if(arr == NULL) croak("Couldn't allocate memory in Rmpz_export");
1560
1561 mpz_export(arr, NULL, SvIV(order), SvIV(size), SvIV(endian), SvIV(nails), *op);
1562 outsv = newSVpv(arr, count);
1563 Safefree(arr);
1564 return outsv;
1565 }
1566
1567 /* Turn an array of UVs into an mpz_t */
Rmpz_import_UV(pTHX_ mpz_t * rop,SV * count,SV * order,SV * size,SV * endian,SV * nails,AV * op)1568 void Rmpz_import_UV(pTHX_ mpz_t * rop, SV * count, SV * order, SV * size, SV * endian, SV * nails, AV * op){
1569 int len, i;
1570 UV * arr;
1571
1572 len = av_len(op) + 1;
1573
1574 Newxz(arr, len, UV);
1575 if(arr == NULL) croak("Couldn't allocate memory in Rmpz_import_UV");
1576
1577 for(i = 0; i < len; i++) {
1578 arr[i] = SvUV(*(av_fetch(op, i, 0)));
1579 }
1580
1581 mpz_import(*rop, SvUV(count), SvIV(order), SvIV(size), SvIV(endian), SvUV(nails), arr);
1582
1583 Safefree(arr);
1584 }
1585
1586
1587 /* Return an mpz_t to an array of UVs */
Rmpz_export_UV(pTHX_ SV * order,SV * size,SV * endian,SV * nails,mpz_t * op)1588 void Rmpz_export_UV(pTHX_ SV * order, SV * size, SV * endian, SV * nails, mpz_t * op) {
1589 dXSARGS;
1590 UV * arr;
1591 int count, i;
1592 int numb = (8 * SvIV(size)) - SvUV(nails);
1593
1594 count = (mpz_sizeinbase (*op, 2) + numb - 1) / numb;
1595
1596 Newxz(arr, count, UV);
1597 if(arr == NULL) croak("Couldn't allocate memory in Rmpz_export_UV");
1598
1599 mpz_export(arr, NULL, SvIV(order), SvIV(size), SvIV(endian), SvIV(nails), *op);
1600
1601 sp = mark;
1602
1603 for(i = 0; i < count; i++) {
1604 XPUSHs(sv_2mortal(newSVuv(arr[i])));
1605 }
1606
1607 Safefree(arr);
1608 XSRETURN(count);
1609 }
1610
Rmpz_fits_ulong_p(mpz_t * in)1611 int Rmpz_fits_ulong_p(mpz_t * in) {
1612 return mpz_fits_ulong_p(*in);
1613 }
1614
Rmpz_fits_slong_p(mpz_t * in)1615 int Rmpz_fits_slong_p(mpz_t * in) {
1616 return mpz_fits_slong_p(*in);
1617 }
1618
Rmpz_fits_uint_p(mpz_t * in)1619 int Rmpz_fits_uint_p(mpz_t * in) {
1620 return mpz_fits_uint_p(*in);
1621 }
1622
Rmpz_fits_sint_p(mpz_t * in)1623 int Rmpz_fits_sint_p(mpz_t * in) {
1624 return mpz_fits_sint_p(*in);
1625 }
1626
Rmpz_fits_ushort_p(mpz_t * in)1627 int Rmpz_fits_ushort_p(mpz_t * in) {
1628 return mpz_fits_ushort_p(*in);
1629 }
1630
Rmpz_fits_sshort_p(mpz_t * in)1631 int Rmpz_fits_sshort_p(mpz_t * in) {
1632 return mpz_fits_sshort_p(*in);
1633 }
1634
Rmpz_odd_p(mpz_t * in)1635 int Rmpz_odd_p(mpz_t * in) {
1636 return mpz_odd_p(*in);
1637 }
1638
Rmpz_even_p(mpz_t * in)1639 int Rmpz_even_p(mpz_t * in) {
1640 return mpz_even_p(*in);
1641 }
1642
Rmpz_size(pTHX_ mpz_t * in)1643 SV * Rmpz_size(pTHX_ mpz_t * in) {
1644 return newSVuv(mpz_size(*in));
1645 }
1646
Rmpz_sizeinbase(pTHX_ mpz_t * in,int base)1647 SV * Rmpz_sizeinbase(pTHX_ mpz_t * in, int base) {
1648 if(base < 2 || base > 62) croak("Rmpz_sizeinbase handles only bases in the range 2..62");
1649 return newSVuv(mpz_sizeinbase(*in, base));
1650 }
1651
Rsieve_gmp(pTHX_ int x_arg,int a,mpz_t * number)1652 void Rsieve_gmp(pTHX_ int x_arg, int a, mpz_t *number) {
1653 dXSARGS;
1654 unsigned short *v, *addon, set[16] = {65534,65533,65531,65527,65519,65503,65471,65407,65279,65023,64511,63487,61439,57343,49151,32767};
1655 unsigned long init, leap, abits, asize, i, size, b, imax, k, x = x_arg;
1656
1657 if(sizeof(short) != 2) croak("The sieve_gmp function is unsuitable for this architecture.\nContact the author and he may do something about it.");
1658 if(a & 1) croak("max_add must be even in sieve_gmp function");
1659 if(x & 1) croak("max_prime must be even in sieve_gmp function");
1660
1661 if(!mpz_tstbit(*number, 0)) croak("candidate must be odd in sieve_gmp function");
1662
1663 abits = (a / 2) + 1;
1664
1665 if(!(abits % 16)) asize = abits / 16;
1666 else asize = (abits / 16) + 1;
1667
1668 Newz(1, addon, asize, unsigned short);
1669 if(addon == NULL) croak("1: Unable to allocate memory in sieve_gmp function");
1670
1671 for(i = 0; i < asize; ++i) addon[i] = 65535;
1672
1673 imax = sqrt(x - 1) / 2;
1674
1675 b = (x + 1) / 2;
1676
1677 if(!(b % 16)) size = b / 16;
1678 else size = (b / 16) + 1;
1679
1680 Newz(2, v, size, unsigned short);
1681 if(v == NULL) croak("2: Unable to allocate memory in sieve_gmp function");
1682
1683 for(i = 1; i < size; ++i) v[i] = 65535;
1684 v[0] = 65534;
1685
1686 for(i = 0; i <= imax; ++i) {
1687
1688 if(v[i / 16] & (1 << (i % 16))) {
1689 leap = (2 * i) + 1;
1690 k = 2 * i * (i + 1);
1691 while(k < b) {
1692 v[k / 16] &= set[k % 16];
1693 k += leap;
1694 }
1695 }
1696 }
1697
1698 size = 0;
1699 sp = mark;
1700
1701 for(i = 0; i < b; ++i) {
1702 if(v[i / 16] & (1 << (i % 16))) {
1703 leap = 2 * i + 1;
1704 init = mpz_fdiv_ui(*number, leap);
1705 if(init) {
1706 if(init & 1) init = (leap - init) / 2;
1707 else init = leap - (init / 2);
1708 }
1709 while(init < abits) {
1710 addon[init / 16] &= set[init % 16];
1711 init += leap;
1712 }
1713 }
1714 }
1715
1716 Safefree(v);
1717
1718 for(i = 0; i < abits; ++i) {
1719 if(addon[i / 16] & (1 << (i % 16))) {
1720 XPUSHs(sv_2mortal(newSViv(2 * i)));
1721 ++size;
1722 }
1723 }
1724
1725 Safefree(addon);
1726
1727 PUTBACK;
1728 XSRETURN(size);
1729
1730 }
1731
Rfermat_gmp(pTHX_ mpz_t * num,int base)1732 SV * Rfermat_gmp(pTHX_ mpz_t * num, int base){
1733 mpz_t b, num_less_1;
1734
1735 mpz_init_set_ui(b, base);
1736 mpz_init_set(num_less_1, *num);
1737 mpz_sub_ui(num_less_1, num_less_1, 1);
1738 mpz_powm(b, b, num_less_1, *num);
1739
1740 if(!mpz_cmp_si(b, 1)) {
1741 mpz_clear(b);
1742 mpz_clear(num_less_1);
1743 return newSViv(1);
1744 }
1745
1746 mpz_clear(b);
1747 mpz_clear(num_less_1);
1748 return newSViv(0);
1749 }
1750
Rrm_gmp(pTHX_ mpz_t * num,int base)1751 SV * Rrm_gmp(pTHX_ mpz_t * num, int base){
1752 mpz_t c_less, r, y, bb;
1753 unsigned long i, s = 0, b = base;
1754
1755 mpz_init(c_less);
1756 mpz_init(r);
1757 mpz_init(y);
1758
1759 mpz_sub_ui(c_less, *num, 1);
1760 mpz_set(r, c_less);
1761 mpz_init_set_ui(bb, b);
1762
1763 while(mpz_even_p(r)) {
1764 mpz_tdiv_q_2exp(r, r, 1);
1765 ++s;
1766 }
1767
1768 mpz_powm(y, bb, r, *num);
1769 mpz_clear(r);
1770 mpz_clear(bb);
1771 if(mpz_cmp_ui(y, 1) && mpz_cmp(y, c_less)) {
1772 for(i = 0; i < s; ++i) {
1773 mpz_powm_ui(y, y, 2, *num);
1774 if(!mpz_cmp_ui(y, 1)) {
1775 mpz_clear(c_less);
1776 mpz_clear(y);
1777 return 0;
1778 }
1779 if(!mpz_cmp(y, c_less)) break;
1780 }
1781 if(mpz_cmp(y, c_less)) {
1782 mpz_clear(c_less);
1783 mpz_clear(y);
1784 return newSViv(0);
1785 }
1786 }
1787
1788 mpz_clear(c_less);
1789 mpz_clear(y);
1790 return newSVuv(1);
1791 }
1792
_Rmpz_out_str(pTHX_ mpz_t * p,int base)1793 SV * _Rmpz_out_str(pTHX_ mpz_t * p, int base) {
1794 unsigned long ret;
1795 if((base > -2 && base < 2) || base < -36 || base > 62)
1796 croak("2nd argument supplied to Rmpz_out_str is out of allowable range (must be in range -36..-2, 2..62)");
1797 ret = mpz_out_str(NULL, base, *p);
1798 fflush(stdout);
1799 return newSVuv(ret);
1800 }
1801
_Rmpz_out_strS(pTHX_ mpz_t * p,SV * base,SV * suff)1802 SV * _Rmpz_out_strS(pTHX_ mpz_t * p, SV * base, SV * suff) {
1803 unsigned long ret;
1804 if((SvIV(base) > -2 && SvIV(base) < 2) || SvIV(base) < -36 || SvIV(base) > 62)
1805 croak("2nd argument supplied to Rmpz_out_str is out of allowable range (must be in range -36..-2, 2..62)");
1806 ret = mpz_out_str(NULL, SvUV(base), *p);
1807 printf("%s", SvPV_nolen(suff));
1808 fflush(stdout);
1809 return newSVuv(ret);
1810 }
1811
_Rmpz_out_strP(pTHX_ SV * pre,mpz_t * p,SV * base)1812 SV * _Rmpz_out_strP(pTHX_ SV * pre, mpz_t * p, SV * base) {
1813 unsigned long ret;
1814 if((SvIV(base) > -2 && SvIV(base) < 2) || SvIV(base) < -36 || SvIV(base) > 62)
1815 croak("3rd argument supplied to Rmpz_out_str is out of allowable range (must be in range -36..-2, 2..62)");
1816 printf("%s", SvPV_nolen(pre));
1817 ret = mpz_out_str(NULL, SvUV(base), *p);
1818 fflush(stdout);
1819 return newSVuv(ret);
1820 }
1821
_Rmpz_out_strPS(pTHX_ SV * pre,mpz_t * p,SV * base,SV * suff)1822 SV * _Rmpz_out_strPS(pTHX_ SV * pre, mpz_t * p, SV * base, SV * suff) {
1823 unsigned long ret;
1824 if((SvIV(base) > -2 && SvIV(base) < 2) || SvIV(base) < -36 || SvIV(base) > 62)
1825 croak("3rd argument supplied to Rmpz_out_str is out of allowable range (must be in range -36..-2, 2..62)");
1826 printf("%s", SvPV_nolen(pre));
1827 ret = mpz_out_str(NULL, SvUV(base), *p);
1828 printf("%s", SvPV_nolen(suff));
1829 fflush(stdout);
1830 return newSVuv(ret);
1831 }
1832
_TRmpz_out_str(pTHX_ FILE * stream,SV * base,mpz_t * p)1833 SV * _TRmpz_out_str(pTHX_ FILE * stream, SV * base, mpz_t * p) {
1834 size_t ret;
1835 if((SvIV(base) > -2 && SvIV(base) < 2) || SvIV(base) < -36 || SvIV(base) > 62)
1836 croak("2nd argument supplied to TRmpz_out_str is out of allowable range (must be in range -36..-2, 2..62)");
1837 ret = mpz_out_str(stream, (int)SvIV(base), *p);
1838 fflush(stream);
1839 return newSVuv(ret);
1840 }
1841
_TRmpz_out_strS(pTHX_ FILE * stream,SV * base,mpz_t * p,SV * suff)1842 SV * _TRmpz_out_strS(pTHX_ FILE * stream, SV * base, mpz_t * p, SV * suff) {
1843 size_t ret;
1844 if((SvIV(base) > -2 && SvIV(base) < 2) || SvIV(base) < -36 || SvIV(base) > 62)
1845 croak("2nd argument supplied to TRmpz_out_str is out of allowable range (must be in range -36..-2, 2..62)");
1846 ret = mpz_out_str(stream, (int)SvIV(base), *p);
1847 fflush(stream);
1848 fprintf(stream, "%s", SvPV_nolen(suff));
1849 fflush(stream);
1850 return newSVuv(ret);
1851 }
1852
_TRmpz_out_strP(pTHX_ SV * pre,FILE * stream,SV * base,mpz_t * p)1853 SV * _TRmpz_out_strP(pTHX_ SV * pre, FILE * stream, SV * base, mpz_t * p) {
1854 size_t ret;
1855 if((SvIV(base) > -2 && SvIV(base) < 2) || SvIV(base) < -36 || SvIV(base) > 62)
1856 croak("3rd argument supplied to TRmpz_out_str is out of allowable range (must be in range -36..-2, 2..62)");
1857 fprintf(stream, "%s", SvPV_nolen(pre));
1858 fflush(stream);
1859 ret = mpz_out_str(stream, (int)SvIV(base), *p);
1860 fflush(stream);
1861 return newSVuv(ret);
1862 }
1863
_TRmpz_out_strPS(pTHX_ SV * pre,FILE * stream,SV * base,mpz_t * p,SV * suff)1864 SV * _TRmpz_out_strPS(pTHX_ SV * pre, FILE * stream, SV * base, mpz_t * p, SV * suff) {
1865 size_t ret;
1866 if((SvIV(base) > -2 && SvIV(base) < 2) || SvIV(base) < -36 || SvIV(base) > 62)
1867 croak("3rd argument supplied to TRmpz_out_str is out of allowable range (must be in range -36..-2, 2..62)");
1868 fprintf(stream, "%s", SvPV_nolen(pre));
1869 fflush(stream);
1870 ret = mpz_out_str(stream, (int)SvIV(base), *p);
1871 fflush(stream);
1872 fprintf(stream, "%s", SvPV_nolen(suff));
1873 fflush(stream);
1874 return newSVuv(ret);
1875 }
1876
Rmpz_inp_str(pTHX_ mpz_t * p,int base)1877 SV * Rmpz_inp_str(pTHX_ mpz_t * p, int base) {
1878 size_t ret;
1879 if(base == 1 || base > 62)
1880 croak("2nd argument supplied to Rmpz_inp_str is out of allowable range (must be in range 0, 2..62)");
1881 ret = mpz_inp_str(*p, NULL, base);
1882 /* fflush(stdin); */
1883 return newSVuv(ret);
1884 }
1885
TRmpz_inp_str(pTHX_ mpz_t * p,FILE * stream,int base)1886 SV * TRmpz_inp_str(pTHX_ mpz_t * p, FILE * stream, int base) {
1887 size_t ret;
1888 if(base == 1 || base > 62)
1889 croak("4th argument supplied to TRmpz_inp_str is out of allowable range (must be in range 0, 2..62)");
1890 ret = mpz_inp_str(*p, stream, base);
1891 /* fflush(stream); */
1892 return newSVuv(ret);
1893 }
1894
eratosthenes(pTHX_ SV * x_arg)1895 void eratosthenes(pTHX_ SV * x_arg) {
1896 dXSARGS;
1897
1898 unsigned short *v, set[16] = {65534,65533,65531,65527,65519,65503,65471,65407,65279,65023,64511,63487,61439,57343,49151,32767};
1899 unsigned long leap, i, size, b, imax, k, x = SvUV(x_arg);
1900
1901 if(x & 1) croak("max_num argument must be even in eratosthenes function");
1902
1903 imax = sqrt(x - 1) / 2;
1904
1905 b = (x + 1) / 2;
1906
1907 if(!(b % 16)) size = b / 16;
1908 else size = (b / 16) + 1;
1909
1910 Newz(2, v, size, unsigned short);
1911 if(v == NULL) croak("2: Unable to allocate memory in eratosthenes function");
1912
1913 for(i = 1; i < size; ++i) v[i] = 65535;
1914 v[0] = 65534;
1915
1916 for(i = 0; i <= imax; ++i) {
1917
1918 if(v[i / 16] & (1 << (i % 16))) {
1919 leap = (2 * i) + 1;
1920 k = 2 * i * (i + 1);
1921 while(k < b) {
1922 v[k / 16] &= set[k % 16];
1923 k += leap;
1924 }
1925 }
1926 }
1927
1928 size = 1;
1929 sp = mark;
1930 XPUSHs(sv_2mortal(newSVuv(2)));
1931
1932 for(i = 0; i < b; ++i) {
1933 if(v[i / 16] & (1 << (i % 16))) {
1934 XPUSHs(sv_2mortal(newSVuv(2 * i + 1)));
1935 ++size;
1936 }
1937 }
1938
1939 Safefree(v);
1940
1941 PUTBACK;
1942 XSRETURN(size);
1943
1944 }
1945
1946
trial_div_ul(pTHX_ mpz_t * num,SV * x_arg)1947 SV * trial_div_ul(pTHX_ mpz_t * num, SV * x_arg) {
1948
1949 unsigned short *v, set[16] = {65534,65533,65531,65527,65519,65503,65471,65407,65279,65023,64511,63487,61439,57343,49151,32767};
1950 unsigned long leap, i, size, b, imax, k, x = SvUV(x_arg);
1951
1952 if(x & 1) croak("Second argument supplied to trial_div_ul must be even");
1953
1954 imax = sqrt(x - 1) / 2;
1955
1956 b = (x + 1) / 2;
1957
1958 if(!(b % 16)) size = b / 16;
1959 else size = (b / 16) + 1;
1960
1961 Newz(2, v, size, unsigned short);
1962 if(v == NULL) croak("2: Unable to allocate memory in trial_div_ul function");
1963
1964 for(i = 1; i < size; ++i) v[i] = 65535;
1965 v[0] = 65534;
1966
1967 for(i = 0; i <= imax; ++i) {
1968
1969 if(v[i / 16] & (1 << (i % 16))) {
1970 leap = (2 * i) + 1;
1971 k = 2 * i * (i + 1);
1972 while(k < b) {
1973 v[k / 16] &= set[k % 16];
1974 k += leap;
1975 }
1976 }
1977 }
1978
1979 if(mpz_divisible_ui_p(*num, 2)) {
1980 Safefree(v);
1981 return newSViv(2);
1982 }
1983
1984 for(i = 0; i < b; ++i) {
1985 if(v[i / 16] & (1 << (i % 16))) {
1986 if(mpz_divisible_ui_p(*num, 2 * i + 1)) {
1987 Safefree(v);
1988 return newSViv(2 * i + 1);
1989 }
1990 }
1991 }
1992
1993 Safefree(v);
1994
1995 return newSViv(1);
1996 }
1997
1998 /* Next 2 functions became available with GMP-4.2 */
1999
Rmpz_rootrem(mpz_t * root,mpz_t * rem,mpz_t * u,unsigned long d)2000 void Rmpz_rootrem(mpz_t * root, mpz_t * rem, mpz_t * u, unsigned long d) {
2001 mpz_rootrem(*root, *rem, *u, d);
2002 }
2003
Rmpz_combit(pTHX_ mpz_t * num,SV * bitpos)2004 void Rmpz_combit(pTHX_ mpz_t * num, SV * bitpos) {
2005
2006 CHECK_MP_BITCNT_T_OVERFLOW(bitpos)
2007
2008 mpz_combit(*num, (mp_bitcnt_t)SvUV(bitpos));
2009 }
2010
2011 /* Finish typemapping - typemap 1st arg only */
2012
overload_mul(pTHX_ SV * a,SV * b,SV * third)2013 SV * overload_mul(pTHX_ SV * a, SV * b, SV * third) {
2014 mpz_t * mpz_t_obj;
2015 SV * obj_ref, * obj;
2016 const char *h;
2017 MBI_DECLARATIONS
2018 MBI_GMP_DECLARATIONS
2019
2020 #if defined(USE_QUADMATH)
2021
2022 char * buffer;
2023 int returned;
2024 __float128 buffer_size;
2025 __float128 ld;
2026
2027 #elif defined(USE_LONG_DOUBLE)
2028
2029 char * buffer;
2030 long double buffer_size;
2031 long double ld;
2032
2033 #endif
2034
2035 if(sv_isobject(b)) h = HvNAME(SvSTASH(SvRV(b)));
2036
2037 if(!sv_isobject(b) || (strNE(h, "Math::MPFR") && strNE(h, "Math::GMPq"))) {
2038 New(1, mpz_t_obj, 1, mpz_t);
2039 if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_mul function");
2040 obj_ref = newSV(0);
2041 obj = newSVrv(obj_ref, "Math::GMPz");
2042 mpz_init(*mpz_t_obj);
2043 sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
2044 SvREADONLY_on(obj);
2045 }
2046
2047 #ifdef MATH_GMPZ_NEED_LONG_LONG_INT
2048 if(SV_IS_IOK(b)) {
2049 Rmpz_set_IV(aTHX_ mpz_t_obj, b);
2050 mpz_mul(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *mpz_t_obj);
2051 return obj_ref;
2052 }
2053 #else
2054
2055 if(SV_IS_IOK(b)) {
2056 if(SvUOK(b)) {
2057 mpz_mul_ui(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), SvUVX(b));
2058 return obj_ref;
2059 }
2060
2061 mpz_mul_si(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), SvIVX(b));
2062 return obj_ref;
2063 }
2064 #endif
2065
2066 if(SV_IS_POK(b)) {
2067 if(mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0))
2068 croak(" Invalid string (%s) supplied to Math::GMPz::overload_mul", SvPV_nolen(b));
2069 mpz_mul(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *mpz_t_obj);
2070 return obj_ref;
2071 }
2072
2073 if(SV_IS_NOK(b)) {
2074
2075 #if defined(USE_QUADMATH)
2076
2077 ld = (__float128)SvNVX(b) >= 0 ? floorq((__float128)SvNVX(b)) : ceilq((__float128)SvNVX(b));
2078 if(ld != ld) croak("In Math::GMPz::overload_mul, cannot coerce a NaN to a Math::GMPz value");
2079 if(ld != 0 && (ld / ld != 1))
2080 croak("In Math::GMPz::overload_mul, cannot coerce an Inf to a Math::GMPz value");
2081
2082 buffer_size = ld < 0.0Q ? ld * -1.0Q : ld;
2083 buffer_size = ceilq(logq(buffer_size + 1) / 2.30258509299404568401799145468436418Q);
2084
2085 Newxz(buffer, (int)buffer_size + 5, char);
2086
2087 returned = quadmath_snprintf(buffer, (size_t)buffer_size + 5, "%.0Qf", ld);
2088 if(returned < 0) croak("In Math::GMPz::overload_mul, encoding error in quadmath_snprintf function");
2089 if(returned >= buffer_size + 5) croak("In Math::GMPz::overload_mul, buffer given to quadmath_snprintf function was too small");
2090 mpz_init_set_str(*mpz_t_obj, buffer, 10);
2091 Safefree(buffer);
2092
2093 #elif defined(USE_LONG_DOUBLE)
2094
2095 ld = (long double)SvNVX(b) >= 0 ? floorl((long double)SvNVX(b)) : ceill((long double)SvNVX(b));
2096 if(ld != ld) croak("In Math::GMPz::overload_mul, cannot coerce a NaN to a Math::GMPz value");
2097 if(ld != 0 && (ld / ld != 1))
2098 croak("In Math::GMPz::overload_mul, cannot coerce an Inf to a Math::GMPz value");
2099
2100 buffer_size = ld < 0.0L ? ld * -1.0L : ld;
2101 buffer_size = ceill(logl(buffer_size + 1) / 2.30258509299404568401799145468436418L);
2102
2103 Newxz(buffer, (int)buffer_size + 5, char);
2104
2105 if(sprintf(buffer, "%.0Lf", ld) >= (int)buffer_size + 5) croak("In Math::GMPz::overload_mul, buffer overflow in sprintf function");
2106 mpz_init_set_str(*mpz_t_obj, buffer, 10);
2107 Safefree(buffer);
2108
2109 #else
2110 double d = SvNVX(b);
2111 if(d != d) croak("In Math::GMPz::overload_mul, cannot coerce a NaN to a Math::GMPz value");
2112 if(d != 0 && (d / d != 1))
2113 croak("In Math::GMPz::overload_mul, cannot coerce an Inf to a Math::GMPz value");
2114 mpz_set_d(*mpz_t_obj, d);
2115 #endif
2116 mpz_mul(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *mpz_t_obj);
2117 return obj_ref;
2118 }
2119
2120 if(sv_isobject(b)) {
2121 if(strEQ(h, "Math::GMPz")) {
2122 mpz_mul(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(b)))));
2123 return obj_ref;
2124 }
2125 if(strEQ(h, "Math::MPFR")) {
2126 _overload_callback("Math::MPFR::overload_mul", "Math::GMPz::overload_mul", newSViv(0));
2127 }
2128
2129 if(strEQ(h, "Math::BigInt")) {
2130 VALIDATE_MBI_OBJECT
2131 croak("Invalid Math::BigInt object supplied to Math::GMPz::overload_mul");
2132
2133 MBI_GMP_INSERT
2134
2135 if(mpz) {
2136 mpz_mul(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), (mpz_srcptr)mpz);
2137 if(strEQ("-", sign)) mpz_neg(*mpz_t_obj, *mpz_t_obj);
2138 return obj_ref;
2139 }
2140
2141 mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0);
2142 mpz_mul(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *mpz_t_obj);
2143 return obj_ref;
2144 }
2145 if(strEQ(h, "Math::GMPq")) {
2146 _overload_callback("Math::GMPq::overload_mul", "Math::GMPz::overload_mul", newSViv(0));
2147 }
2148 }
2149
2150 croak("Invalid argument supplied to Math::GMPz::overload_mul");
2151 }
2152
overload_add(pTHX_ SV * a,SV * b,SV * third)2153 SV * overload_add(pTHX_ SV * a, SV * b, SV * third) {
2154 mpz_t * mpz_t_obj;
2155 SV * obj_ref, * obj;
2156 const char *h;
2157 MBI_DECLARATIONS
2158 MBI_GMP_DECLARATIONS
2159
2160 #if defined(USE_QUADMATH)
2161
2162 char * buffer;
2163 int returned;
2164 __float128 buffer_size;
2165 __float128 ld;
2166
2167 #elif defined(USE_LONG_DOUBLE)
2168
2169 char * buffer;
2170 long double buffer_size;
2171 long double ld;
2172
2173 #endif
2174
2175 if(sv_isobject(b)) h = HvNAME(SvSTASH(SvRV(b)));
2176
2177 if(!sv_isobject(b) || (strNE(h, "Math::MPFR") && strNE(h, "Math::GMPq"))) {
2178 New(1, mpz_t_obj, 1, mpz_t);
2179 if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_add function");
2180 obj_ref = newSV(0);
2181 obj = newSVrv(obj_ref, "Math::GMPz");
2182 mpz_init(*mpz_t_obj);
2183 sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
2184 SvREADONLY_on(obj);
2185 }
2186
2187 #ifdef MATH_GMPZ_NEED_LONG_LONG_INT
2188 if(SV_IS_IOK(b)) {
2189 Rmpz_set_IV(aTHX_ mpz_t_obj, b);
2190 mpz_add(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *mpz_t_obj);
2191 return obj_ref;
2192 }
2193 #else
2194 if(SV_IS_IOK(b)) {
2195 if(SvUOK(b)) {
2196 mpz_add_ui(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), SvUVX(b));
2197 return obj_ref;
2198 }
2199
2200 if(SvIV(b) >= 0) {
2201 mpz_add_ui(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), SvIVX(b));
2202 return obj_ref;
2203 }
2204 mpz_sub_ui(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), SvIVX(b) * -1);
2205 return obj_ref;
2206 }
2207 #endif
2208
2209 if(SV_IS_POK(b)) {
2210 if(mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0))
2211 croak(" Invalid string (%s) supplied to Math::GMPz::overload_add", SvPV_nolen(b));
2212 mpz_add(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *mpz_t_obj);
2213 return obj_ref;
2214 }
2215
2216 if(SV_IS_NOK(b)) {
2217
2218 #if defined(USE_QUADMATH)
2219
2220 ld = (__float128)SvNVX(b) >= 0 ? floorq((__float128)SvNVX(b)) : ceilq((__float128)SvNVX(b));
2221 if(ld != ld) croak("In Math::GMPz::overload_add, cannot coerce a NaN to a Math::GMPz value");
2222 if(ld != 0 && (ld / ld != 1))
2223 croak("In Math::GMPz::overload_add, cannot coerce an Inf to a Math::GMPz value");
2224
2225 buffer_size = ld < 0.0Q ? ld * -1.0Q : ld;
2226 buffer_size = ceilq(logq(buffer_size + 1) / 2.30258509299404568401799145468436418Q);
2227
2228 Newxz(buffer, (int)buffer_size + 5, char);
2229
2230 returned = quadmath_snprintf(buffer, (size_t)buffer_size + 5, "%.0Qf", ld);
2231 if(returned < 0) croak("In Math::GMPz::overload_add, encoding error in quadmath_snprintf function");
2232 if(returned >= buffer_size + 5) croak("In Math::GMPz::overload_add, buffer given to quadmath_snprintf function was too small");
2233 mpz_init_set_str(*mpz_t_obj, buffer, 10);
2234 Safefree(buffer);
2235
2236 #elif defined(USE_LONG_DOUBLE)
2237
2238 ld = (long double)SvNVX(b) >= 0 ? floorl((long double)SvNVX(b)) : ceill((long double)SvNVX(b));
2239 if(ld != ld) croak("In Math::GMPz::overload_add, cannot coerce a NaN to a Math::GMPz value");
2240 if(ld != 0 && (ld / ld != 1))
2241 croak("In Math::GMPz::overload_add, cannot coerce an Inf to a Math::GMPz value");
2242
2243 buffer_size = ld < 0.0L ? ld * -1.0L : ld;
2244 buffer_size = ceill(logl(buffer_size + 1) / 2.30258509299404568401799145468436418L);
2245
2246 Newxz(buffer, (int)buffer_size + 5, char);
2247
2248 if(sprintf(buffer, "%.0Lf", ld) >= (int)buffer_size + 5) croak("In Math::GMPz::overload_add, buffer overflow in sprintf function");
2249 mpz_init_set_str(*mpz_t_obj, buffer, 10);
2250 Safefree(buffer);
2251 #else
2252 double d = SvNVX(b);
2253 if(d != d) croak("In Math::GMPz::overload_add, cannot coerce a NaN to a Math::GMPz value");
2254 if(d != 0 && (d / d != 1))
2255 croak("In Math::GMPz::overload_add, cannot coerce an Inf to a Math::GMPz value");
2256 mpz_set_d(*mpz_t_obj, d);
2257 #endif
2258 mpz_add(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *mpz_t_obj);
2259 return obj_ref;
2260 }
2261
2262 if(sv_isobject(b)) {
2263 if(strEQ(h, "Math::GMPz")) {
2264 mpz_add(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(b)))));
2265 return obj_ref;
2266 }
2267 if(strEQ(h, "Math::MPFR")) {
2268 _overload_callback("Math::MPFR::overload_add", "Math::GMPz::overload_add", newSViv(0));
2269 }
2270
2271 if(strEQ(h, "Math::BigInt")) {
2272 VALIDATE_MBI_OBJECT
2273 croak("Invalid Math::BigInt object supplied to Math::GMPz::overload_add");
2274
2275 MBI_GMP_INSERT
2276
2277 if(mpz) {
2278 if(strEQ("-", sign)) {
2279 mpz_sub(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), (mpz_srcptr)mpz);
2280 return obj_ref;
2281 }
2282
2283 mpz_add(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), (mpz_srcptr)mpz);
2284 return obj_ref;
2285 }
2286
2287 mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0);
2288 mpz_add(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *mpz_t_obj);
2289 return obj_ref;
2290 }
2291 if(strEQ(h, "Math::GMPq")) {
2292 _overload_callback("Math::GMPq::overload_add", "Math::GMPz::overload_add", newSViv(0));
2293 }
2294 }
2295
2296 croak("Invalid argument supplied to Math::GMPz::overload_add function");
2297
2298 }
2299
overload_sub(pTHX_ SV * a,SV * b,SV * third)2300 SV * overload_sub(pTHX_ SV * a, SV * b, SV * third) {
2301 mpz_t * mpz_t_obj;
2302 SV * obj_ref, * obj;
2303 const char *h;
2304 MBI_DECLARATIONS
2305 MBI_GMP_DECLARATIONS
2306
2307 #if defined(USE_QUADMATH)
2308
2309 char * buffer;
2310 int returned;
2311 __float128 buffer_size;
2312 __float128 ld;
2313
2314 #elif defined(USE_LONG_DOUBLE)
2315
2316 char * buffer;
2317 long double buffer_size;
2318 long double ld;
2319
2320 #endif
2321
2322 if(sv_isobject(b)) h = HvNAME(SvSTASH(SvRV(b)));
2323
2324 if(!sv_isobject(b) || (strNE(h, "Math::MPFR") && strNE(h, "Math::GMPq"))) {
2325 New(1, mpz_t_obj, 1, mpz_t);
2326 if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_sub function");
2327 obj_ref = newSV(0);
2328 obj = newSVrv(obj_ref, "Math::GMPz");
2329 mpz_init(*mpz_t_obj);
2330 sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
2331 SvREADONLY_on(obj);
2332 }
2333
2334
2335 #ifdef MATH_GMPZ_NEED_LONG_LONG_INT
2336 if(SV_IS_IOK(b)) {
2337 Rmpz_set_IV(aTHX_ mpz_t_obj, b);
2338 if(third == &PL_sv_yes) mpz_sub(*mpz_t_obj, *mpz_t_obj, *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))));
2339 else mpz_sub(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *mpz_t_obj);
2340 return obj_ref;
2341 }
2342 #else
2343 if(SV_IS_IOK(b)) {
2344 if(SvUOK(b)) {
2345 if(third == &PL_sv_yes) {
2346 mpz_ui_sub(*mpz_t_obj, SvUVX(b), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))));
2347 return obj_ref;
2348 }
2349 mpz_sub_ui(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), SvUVX(b));
2350 return obj_ref;
2351 }
2352
2353 if(SvIV(b) >= 0) {
2354 if(third == &PL_sv_yes) {
2355 mpz_ui_sub(*mpz_t_obj, SvIVX(b), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))));
2356 return obj_ref;
2357 }
2358 mpz_sub_ui(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), SvIVX(b));
2359 return obj_ref;
2360 }
2361 mpz_add_ui(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), SvIVX(b) * -1);
2362 if(third == &PL_sv_yes) mpz_neg(*mpz_t_obj, *mpz_t_obj);
2363 return obj_ref;
2364 }
2365 #endif
2366
2367 if(SV_IS_POK(b)) {
2368 if(mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0))
2369 croak(" Invalid string (%s) supplied to Math::GMPz::overload_sub", SvPV_nolen(b));
2370 if(third == &PL_sv_yes) mpz_sub(*mpz_t_obj, *mpz_t_obj, *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))));
2371 else mpz_sub(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *mpz_t_obj);
2372 return obj_ref;
2373 }
2374
2375 if(SV_IS_NOK(b)) {
2376
2377 #if defined(USE_QUADMATH)
2378
2379 ld = (__float128)SvNVX(b) >= 0 ? floorq((__float128)SvNVX(b)) : ceilq((__float128)SvNVX(b));
2380 if(ld != ld) croak("In Math::GMPz::overload_sub, cannot coerce a NaN to a Math::GMPz value");
2381 if(ld != 0 && (ld / ld != 1))
2382 croak("In Math::GMPz::overload_sub, cannot coerce an Inf to a Math::GMPz value");
2383
2384 buffer_size = ld < 0.0Q ? ld * -1.0Q : ld;
2385 buffer_size = ceilq(logq(buffer_size + 1) / 2.30258509299404568401799145468436418Q);
2386
2387 Newxz(buffer, (int)buffer_size + 5, char);
2388
2389 returned = quadmath_snprintf(buffer, (size_t)buffer_size + 5, "%.0Qf", ld);
2390 if(returned < 0) croak("In Math::GMPz::overload_sub, encoding error in quadmath_snprintf function");
2391 if(returned >= buffer_size + 5) croak("In Math::GMPz::overload_sub, buffer given to quadmath_snprintf function was too small");
2392 mpz_init_set_str(*mpz_t_obj, buffer, 10);
2393 Safefree(buffer);
2394
2395 #elif defined(USE_LONG_DOUBLE)
2396
2397 ld = (long double)SvNVX(b) >= 0 ? floorl((long double)SvNVX(b)) : ceill((long double)SvNVX(b));
2398 if(ld != ld) croak("In Math::GMPz::overload_sub, cannot coerce a NaN to a Math::GMPz value");
2399 if(ld != 0 && (ld / ld != 1))
2400 croak("In Math::GMPz::overload_sub, cannot coerce an Inf to a Math::GMPz value");
2401
2402 buffer_size = ld < 0.0L ? ld * -1.0L : ld;
2403 buffer_size = ceill(logl(buffer_size + 1) / 2.30258509299404568401799145468436418L);
2404
2405 Newxz(buffer, (int)buffer_size + 5, char);
2406
2407 if(sprintf(buffer, "%.0Lf", ld) >= (int)buffer_size + 5) croak("In Math::GMPz::overload_sub, buffer overflow in sprintf function");
2408 mpz_init_set_str(*mpz_t_obj, buffer, 10);
2409 Safefree(buffer);
2410 #else
2411 double d = SvNVX(b);
2412 if(d != d) croak("In Math::GMPz::overload_sub, cannot coerce a NaN to a Math::GMPz value");
2413 if(d != 0 && (d / d != 1))
2414 croak("In Math::GMPz::overload_sub, cannot coerce an Inf to a Math::GMPz value");
2415 mpz_set_d(*mpz_t_obj, SvNVX(b));
2416 #endif
2417 if(third == &PL_sv_yes) mpz_sub(*mpz_t_obj, *mpz_t_obj, *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))));
2418 else mpz_sub(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *mpz_t_obj);
2419 return obj_ref;
2420 }
2421
2422 if(sv_isobject(b)) {
2423 if(strEQ(h, "Math::GMPz")) {
2424 mpz_sub(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(b)))));
2425 return obj_ref;
2426 }
2427 if(strEQ(h, "Math::MPFR")) {
2428 _overload_callback("Math::MPFR::overload_sub", "Math::GMPz::overload_sub", &PL_sv_yes);
2429 }
2430
2431 if(strEQ(h, "Math::BigInt")) {
2432 VALIDATE_MBI_OBJECT
2433 croak("Invalid Math::BigInt object supplied to Math::GMPz::overload_sub");
2434
2435 MBI_GMP_INSERT
2436
2437 if(mpz) {
2438 if(strEQ("-", sign)) {
2439 mpz_add(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), (mpz_srcptr)mpz);
2440 return obj_ref;
2441 }
2442
2443 mpz_sub(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), (mpz_srcptr)mpz);
2444 return obj_ref;
2445 }
2446
2447 mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0);
2448 mpz_sub(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *mpz_t_obj);
2449 return obj_ref;
2450 }
2451 if(strEQ(h, "Math::GMPq")) {
2452 _overload_callback("Math::GMPq::overload_sub", "Math::GMPz::overload_sub", &PL_sv_yes);
2453 }
2454 }
2455
2456 croak("Invalid argument supplied to Math::GMPz::overload_sub function");
2457
2458 }
2459
overload_div(pTHX_ SV * a,SV * b,SV * third)2460 SV * overload_div(pTHX_ SV * a, SV * b, SV * third) {
2461 mpz_t * mpz_t_obj;
2462 SV * obj_ref, * obj;
2463 const char *h;
2464 MBI_DECLARATIONS
2465 MBI_GMP_DECLARATIONS
2466
2467 #if defined(USE_QUADMATH)
2468
2469 char * buffer;
2470 int returned;
2471 __float128 buffer_size;
2472 __float128 ld;
2473
2474 #elif defined(USE_LONG_DOUBLE)
2475
2476 char * buffer;
2477 long double buffer_size;
2478 long double ld;
2479
2480 #endif
2481
2482 if(sv_isobject(b)) h = HvNAME(SvSTASH(SvRV(b)));
2483
2484 if(!sv_isobject(b) || (strNE(h, "Math::MPFR") && strNE(h, "Math::GMPq"))) {
2485 New(1, mpz_t_obj, 1, mpz_t);
2486 if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_div function");
2487 obj_ref = newSV(0);
2488 obj = newSVrv(obj_ref, "Math::GMPz");
2489 mpz_init(*mpz_t_obj);
2490 sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
2491 SvREADONLY_on(obj);
2492 }
2493
2494 #ifdef MATH_GMPZ_NEED_LONG_LONG_INT
2495 if(SV_IS_IOK(b)) {
2496 Rmpz_set_IV(aTHX_ mpz_t_obj, b);
2497 if(third == &PL_sv_yes) Rmpz_tdiv_q(mpz_t_obj, mpz_t_obj, INT2PTR(mpz_t *, SvIVX(SvRV(a))));
2498 else Rmpz_tdiv_q(mpz_t_obj, INT2PTR(mpz_t *, SvIVX(SvRV(a))), mpz_t_obj);
2499 return obj_ref;
2500 }
2501 #else
2502 if(SV_IS_IOK(b)) {
2503 if(SvUOK(b)) {
2504 if(third == &PL_sv_yes) {
2505 mpz_set_ui(*mpz_t_obj, SvUVX(b));
2506 Rmpz_tdiv_q(mpz_t_obj, mpz_t_obj, INT2PTR(mpz_t *, SvIVX(SvRV(a))));
2507 return obj_ref;
2508 }
2509 Rmpz_tdiv_q_ui(mpz_t_obj, INT2PTR(mpz_t *, SvIVX(SvRV(a))), SvUVX(b));
2510 return obj_ref;
2511 }
2512
2513 if(SvIVX(b) >= 0) {
2514 if(third == &PL_sv_yes) {
2515 mpz_set_si(*mpz_t_obj, SvIVX(b));
2516 Rmpz_tdiv_q(mpz_t_obj, mpz_t_obj, INT2PTR(mpz_t *, SvIVX(SvRV(a))));
2517 return obj_ref;
2518 }
2519 Rmpz_tdiv_q_ui(mpz_t_obj, INT2PTR(mpz_t *, SvIVX(SvRV(a))), SvIVX(b));
2520 return obj_ref;
2521 }
2522
2523 if(third == &PL_sv_yes) {
2524 mpz_set_si(*mpz_t_obj, SvIVX(b));
2525 Rmpz_tdiv_q(mpz_t_obj, mpz_t_obj, INT2PTR(mpz_t *, SvIVX(SvRV(a))));
2526 return obj_ref;
2527 }
2528
2529 Rmpz_tdiv_q_ui(mpz_t_obj, INT2PTR(mpz_t *, SvIVX(SvRV(a))), SvIVX(b) * -1);
2530 mpz_neg(*mpz_t_obj, *mpz_t_obj);
2531 return obj_ref;
2532 }
2533 #endif
2534
2535 if(SV_IS_POK(b)) {
2536 if(mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0))
2537 croak(" Invalid string (%s) supplied to Math::GMPz::overload_div", SvPV_nolen(b));
2538 if(third == &PL_sv_yes) Rmpz_tdiv_q(mpz_t_obj, mpz_t_obj, INT2PTR(mpz_t *, SvIVX(SvRV(a))));
2539 else Rmpz_tdiv_q(mpz_t_obj, INT2PTR(mpz_t *, SvIVX(SvRV(a))), mpz_t_obj);
2540 return obj_ref;
2541 }
2542
2543 if(SV_IS_NOK(b)) {
2544
2545 #if defined(USE_QUADMATH)
2546
2547 ld = (__float128)SvNVX(b) >= 0 ? floorq((__float128)SvNVX(b)) : ceilq((__float128)SvNVX(b));
2548 if(ld != ld) croak("In Math::GMPz::overload_div, cannot coerce a NaN to a Math::GMPz value");
2549 if(ld != 0 && (ld / ld != 1))
2550 croak("In Math::GMPz::overload_div, cannot coerce an Inf to a Math::GMPz value");
2551
2552 buffer_size = ld < 0.0Q ? ld * -1.0Q : ld;
2553 buffer_size = ceilq(logq(buffer_size + 1) / 2.30258509299404568401799145468436418Q);
2554
2555 Newxz(buffer, (int)buffer_size + 5, char);
2556
2557 returned = quadmath_snprintf(buffer, (size_t)buffer_size + 5, "%.0Qf", ld);
2558 if(returned < 0) croak("In Math::GMPz::overload_div, encoding error in quadmath_snprintf function");
2559 if(returned >= buffer_size + 5) croak("In Math::GMPz::overload_div, buffer given to quadmath_snprintf function was too small");
2560 mpz_init_set_str(*mpz_t_obj, buffer, 10);
2561 Safefree(buffer);
2562
2563 #elif defined(USE_LONG_DOUBLE)
2564
2565 ld = (long double)SvNVX(b) >= 0 ? floorl((long double)SvNVX(b)) : ceill((long double)SvNVX(b));
2566 if(ld != ld) croak("In Math::GMPz::overload_div, cannot coerce a NaN to a Math::GMPz value");
2567 if(ld != 0 && (ld / ld != 1))
2568 croak("In Math::GMPz::overload_div, cannot coerce an Inf to a Math::GMPz value");
2569
2570 buffer_size = ld < 0.0L ? ld * -1.0L : ld;
2571 buffer_size = ceill(logl(buffer_size + 1) / 2.30258509299404568401799145468436418L);
2572
2573 Newxz(buffer, (int)buffer_size + 5, char);
2574
2575 if(sprintf(buffer, "%.0Lf", ld) >= (int)buffer_size + 5) croak("In Math::GMPz::overload_div, buffer overflow in sprintf function");
2576 mpz_init_set_str(*mpz_t_obj, buffer, 10);
2577 Safefree(buffer);
2578 #else
2579 double d = SvNVX(b);
2580 if(d != d) croak("In Math::GMPz::overload_div, cannot coerce a NaN to a Math::GMPz value");
2581 if(d != 0 && (d / d != 1))
2582 croak("In Math::GMPz::overload_div, cannot coerce an Inf to a Math::GMPz value");
2583 mpz_set_d(*mpz_t_obj, d);
2584 #endif
2585 if(third == &PL_sv_yes) Rmpz_tdiv_q(mpz_t_obj, mpz_t_obj, INT2PTR(mpz_t *, SvIVX(SvRV(a))));
2586 else Rmpz_tdiv_q(mpz_t_obj, INT2PTR(mpz_t *, SvIVX(SvRV(a))), mpz_t_obj);
2587 return obj_ref;
2588 }
2589
2590 if(sv_isobject(b)) {
2591 if(strEQ(h, "Math::GMPz")) {
2592 Rmpz_tdiv_q(mpz_t_obj, INT2PTR(mpz_t *, SvIVX(SvRV(a))), INT2PTR(mpz_t *, SvIVX(SvRV(b))));
2593 return obj_ref;
2594 }
2595 if(strEQ(h, "Math::MPFR")) {
2596 _overload_callback("Math::MPFR::overload_div", "Math::GMPz::overload_div", &PL_sv_yes);
2597 }
2598
2599 if(strEQ(h, "Math::BigInt")) {
2600 VALIDATE_MBI_OBJECT
2601 croak("Invalid Math::BigInt object supplied to Math::GMPz::overload_div");
2602
2603 MBI_GMP_INSERT
2604
2605 if(mpz) {
2606 mpz_tdiv_q(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), (mpz_srcptr)mpz);
2607 if(strEQ("-", sign)) mpz_neg(*mpz_t_obj, *mpz_t_obj);
2608 return obj_ref;
2609 }
2610
2611 mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0);
2612 Rmpz_tdiv_q(mpz_t_obj, INT2PTR(mpz_t *, SvIVX(SvRV(a))), mpz_t_obj);
2613 return obj_ref;
2614 }
2615 if(strEQ(h, "Math::GMPq")) {
2616 _overload_callback("Math::GMPq::overload_div", "Math::GMPz::overload_div", &PL_sv_yes);
2617 }
2618 }
2619
2620 croak("Invalid argument supplied to Math::GMPz::overload_div function");
2621
2622 }
2623
overload_mod(pTHX_ mpz_t * a,SV * b,SV * third)2624 SV * overload_mod (pTHX_ mpz_t * a, SV * b, SV * third) {
2625 mpz_t *mpz_t_obj;
2626 SV * obj_ref, * obj;
2627 MBI_DECLARATIONS
2628 MBI_GMP_DECLARATIONS
2629
2630 #if defined(USE_QUADMATH)
2631
2632 char * buffer;
2633 int returned;
2634 __float128 buffer_size;
2635 __float128 ld;
2636
2637 #elif defined(USE_LONG_DOUBLE)
2638
2639 char * buffer;
2640 long double buffer_size;
2641 long double ld;
2642
2643 #endif
2644
2645 New(1, mpz_t_obj, 1, mpz_t);
2646 if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_mod function");
2647 obj_ref = newSV(0);
2648 obj = newSVrv(obj_ref, "Math::GMPz");
2649 mpz_init(*mpz_t_obj);
2650 sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
2651 SvREADONLY_on(obj);
2652
2653 #ifdef MATH_GMPZ_NEED_LONG_LONG_INT
2654 if(SV_IS_IOK(b)) {
2655 Rmpz_set_IV(aTHX_ mpz_t_obj, b);
2656 if(third == &PL_sv_yes) {
2657 mpz_mod(*mpz_t_obj, *mpz_t_obj, *a);
2658 return obj_ref;
2659 }
2660 mpz_mod(*mpz_t_obj, *a, *mpz_t_obj);
2661 return obj_ref;
2662 }
2663 #else
2664 if(SV_IS_IOK(b)) {
2665 if(SvUOK(b)) {
2666 if(third == &PL_sv_yes) {
2667 mpz_set_ui(*mpz_t_obj, SvUVX(b));
2668 mpz_mod(*mpz_t_obj, *mpz_t_obj, *a);
2669 return obj_ref;
2670 }
2671 mpz_mod_ui(*mpz_t_obj, *a, SvUVX(b));
2672 return obj_ref;
2673 }
2674
2675 mpz_set_si(*mpz_t_obj, SvIVX(b));
2676 if(third == &PL_sv_yes) {
2677 mpz_mod(*mpz_t_obj, *mpz_t_obj, *a);
2678 return obj_ref;
2679 }
2680 mpz_mod(*mpz_t_obj, *a, *mpz_t_obj);
2681 return obj_ref;
2682 }
2683 #endif
2684
2685 if(SV_IS_POK(b)) {
2686 if(mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0))
2687 croak(" Invalid string (%s) supplied to Math::GMPz::overload_mod", SvPV_nolen(b));
2688 if(third == &PL_sv_yes) {
2689 mpz_mod(*mpz_t_obj, *mpz_t_obj, *a);
2690 return obj_ref;
2691 }
2692 mpz_mod(*mpz_t_obj, *a, *mpz_t_obj);
2693 return obj_ref;
2694 }
2695
2696 if(SV_IS_NOK(b)) {
2697
2698 #if defined(USE_QUADMATH)
2699
2700 ld = (__float128)SvNVX(b) >= 0 ? floorq((__float128)SvNVX(b)) : ceilq((__float128)SvNVX(b));
2701 if(ld != ld) croak("In Math::GMPz::overload_mod, cannot coerce a NaN to a Math::GMPz value");
2702 if(ld != 0 && (ld / ld != 1))
2703 croak("In Math::GMPz::overload_mod, cannot coerce an Inf to a Math::GMPz value");
2704
2705 buffer_size = ld < 0.0Q ? ld * -1.0Q : ld;
2706 buffer_size = ceilq(logq(buffer_size + 1) / 2.30258509299404568401799145468436418Q);
2707
2708 Newxz(buffer, (int)buffer_size + 5, char);
2709
2710 returned = quadmath_snprintf(buffer, (size_t)buffer_size + 5, "%.0Qf", ld);
2711 if(returned < 0) croak("In Math::GMPz::overload_mod, encoding error in quadmath_snprintf function");
2712 if(returned >= buffer_size + 5) croak("In Math::GMPz::overload_mod, buffer given to quadmath_snprintf function was too small");
2713 mpz_init_set_str(*mpz_t_obj, buffer, 10);
2714 Safefree(buffer);
2715
2716 #elif defined(USE_LONG_DOUBLE)
2717
2718 ld = (long double)SvNVX(b) >= 0 ? floorl((long double)SvNVX(b)) : ceill((long double)SvNVX(b));
2719 if(ld != ld) croak("In Math::GMPz::overload_mod, cannot coerce a NaN to a Math::GMPz value");
2720 if(ld != 0 && (ld / ld != 1))
2721 croak("In Math::GMPz::overload_mod, cannot coerce an Inf to a Math::GMPz value");
2722
2723 buffer_size = ld < 0.0L ? ld * -1.0L : ld;
2724 buffer_size = ceill(logl(buffer_size + 1) / 2.30258509299404568401799145468436418L);
2725
2726 Newxz(buffer, (int)buffer_size + 5, char);
2727
2728 if(sprintf(buffer, "%.0Lf", ld) >= (int)buffer_size + 5) croak("In Math::GMPz::overload_mod, buffer overflow in sprintf function");
2729 mpz_init_set_str(*mpz_t_obj, buffer, 10);
2730 Safefree(buffer);
2731 #else
2732 double d = SvNVX(b);
2733 if(d != d) croak("In Math::GMPz::overload_mod, cannot coerce a NaN to a Math::GMPz value");
2734 if(d != 0 && (d / d != 1))
2735 croak("In Math::GMPz::overload_mod, cannot coerce an Inf to a Math::GMPz value");
2736 mpz_set_d(*mpz_t_obj, d);
2737 #endif
2738 if(third == &PL_sv_yes) {
2739 mpz_mod(*mpz_t_obj, *mpz_t_obj, *a);
2740 return obj_ref;
2741 }
2742 mpz_mod(*mpz_t_obj, *a, *mpz_t_obj);
2743 return obj_ref;
2744 }
2745
2746 if(sv_isobject(b)) {
2747 const char *h = HvNAME(SvSTASH(SvRV(b)));
2748 if(strEQ(h, "Math::GMPz")) {
2749 mpz_mod(*mpz_t_obj, *a, *(INT2PTR(mpz_t *, SvIVX(SvRV(b)))));
2750 return obj_ref;
2751 }
2752 if(strEQ(h, "Math::BigInt")) {
2753 VALIDATE_MBI_OBJECT
2754 croak("Invalid Math::BigInt object supplied to Math::GMPz::overload_mod");
2755
2756 MBI_GMP_INSERT
2757
2758 if(mpz) {
2759 mpz_mod(*mpz_t_obj, *a, (mpz_srcptr)mpz);
2760 /* if(strEQ("-", sign)) ...... sign of divisor has no bearing on mod */
2761 return obj_ref;
2762 }
2763
2764 mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0);
2765 mpz_mod(*mpz_t_obj, *a, *mpz_t_obj);
2766 return obj_ref;
2767 }
2768 }
2769
2770 croak("Invalid argument supplied to Math::GMPz::overload_mod function");
2771 }
2772
overload_string(pTHX_ mpz_t * p,SV * second,SV * third)2773 SV * overload_string(pTHX_ mpz_t * p, SV * second, SV * third) {
2774 char * out;
2775 SV * outsv;
2776
2777 New(2, out, mpz_sizeinbase(*p, 10) + 3, char);
2778 if(out == NULL) croak("Failed to allocate memory in overload_string function");
2779
2780 mpz_get_str(out, 10, *p);
2781 outsv = newSVpv(out, 0);
2782 Safefree(out);
2783 return outsv;
2784 }
2785
overload_copy(pTHX_ mpz_t * p,SV * second,SV * third)2786 SV * overload_copy(pTHX_ mpz_t * p, SV * second, SV * third) {
2787 mpz_t * mpz_t_obj;
2788 SV * obj_ref, * obj;
2789
2790 New(1, mpz_t_obj, 1, mpz_t);
2791 if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_copy function");
2792 obj_ref = newSV(0);
2793 obj = newSVrv(obj_ref, "Math::GMPz");
2794
2795 mpz_init_set(*mpz_t_obj, *p);
2796 sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
2797 SvREADONLY_on(obj);
2798 return obj_ref;
2799 }
2800
overload_abs(pTHX_ mpz_t * p,SV * second,SV * third)2801 SV * overload_abs(pTHX_ mpz_t * p, SV * second, SV * third) {
2802 mpz_t * mpz_t_obj;
2803 SV * obj_ref, * obj;
2804
2805 New(1, mpz_t_obj, 1, mpz_t);
2806 if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_abs function");
2807 obj_ref = newSV(0);
2808 obj = newSVrv(obj_ref, "Math::GMPz");
2809 mpz_init(*mpz_t_obj);
2810
2811 mpz_abs(*mpz_t_obj, *p);
2812 sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
2813 SvREADONLY_on(obj);
2814 return obj_ref;
2815 }
2816
overload_lshift(pTHX_ mpz_t * a,SV * b,SV * third)2817 SV * overload_lshift(pTHX_ mpz_t * a, SV * b, SV * third) {
2818 mpz_t * mpz_t_obj;
2819 SV * obj_ref, * obj;
2820
2821 CHECK_MP_BITCNT_T_OVERFLOW(b)
2822
2823 New(1, mpz_t_obj, 1, mpz_t);
2824 if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_lshift function");
2825 obj_ref = newSV(0);
2826 obj = newSVrv(obj_ref, "Math::GMPz");
2827 mpz_init(*mpz_t_obj);
2828
2829 if(SV_IS_IOK(b)) {
2830 if(SvUOK(b)) {
2831 mpz_mul_2exp(*mpz_t_obj, *a, (mp_bitcnt_t)SvUV(b));
2832 sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
2833 SvREADONLY_on(obj);
2834 return obj_ref;
2835 }
2836
2837 if(SvIV(b) < 0) croak("Invalid argument supplied to Math::GMPz::overload_lshift");
2838 mpz_mul_2exp(*mpz_t_obj, *a, SvUV(b));
2839 sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
2840 SvREADONLY_on(obj);
2841 return obj_ref;
2842 }
2843
2844 croak("Invalid argument supplied to Math::GMPz::overload_lshift");
2845 }
2846
overload_rshift(pTHX_ mpz_t * a,SV * b,SV * third)2847 SV * overload_rshift(pTHX_ mpz_t * a, SV * b, SV * third) {
2848 mpz_t * mpz_t_obj;
2849 SV * obj_ref, * obj;
2850
2851 CHECK_MP_BITCNT_T_OVERFLOW(b)
2852
2853 New(1, mpz_t_obj, 1, mpz_t);
2854 if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_rshift function");
2855 obj_ref = newSV(0);
2856 obj = newSVrv(obj_ref, "Math::GMPz");
2857 mpz_init(*mpz_t_obj);
2858
2859 if(SV_IS_IOK(b)) {
2860 if(SvUOK(b)) {
2861 mpz_tdiv_q_2exp(*mpz_t_obj, *a, (mp_bitcnt_t)SvUVX(b));
2862 sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
2863 SvREADONLY_on(obj);
2864 return obj_ref;
2865 }
2866
2867 if(SvIV(b) < 0) croak("Invalid argument supplied to Math::GMPz::overload_rshift");
2868 mpz_tdiv_q_2exp(*mpz_t_obj, *a, (mp_bitcnt_t)SvUVX(b));
2869 sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
2870 SvREADONLY_on(obj);
2871 return obj_ref;
2872 }
2873
2874 croak("Invalid argument supplied to Math::GMPz::overload_rshift");
2875 }
2876
overload_pow(pTHX_ SV * a,SV * b,SV * third)2877 SV * overload_pow(pTHX_ SV * a, SV * b, SV * third) {
2878 mpz_t * mpz_t_obj;
2879 SV * obj_ref, * obj;
2880 unsigned long int ui = 0;
2881
2882 if(mpz_fits_uint_p(*(INT2PTR(mpz_t *, SvIVX(SvRV(a))))))
2883 ui = mpz_get_ui(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))));
2884
2885 if(!sv_isobject(b)) {
2886 New(1, mpz_t_obj, 1, mpz_t);
2887 if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_pow function");
2888 obj_ref = newSV(0);
2889 obj = newSVrv(obj_ref, "Math::GMPz");
2890 mpz_init(*mpz_t_obj);
2891 sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
2892 SvREADONLY_on(obj);
2893 }
2894
2895 if(SV_IS_IOK(b)) {
2896 if(SvUOK(b)) {
2897 if(third == &PL_sv_yes) {
2898 if(ui) {
2899 mpz_ui_pow_ui(*mpz_t_obj, SvUVX(b), ui);
2900 return obj_ref;
2901 }
2902 croak("Exponent does not fit into unsigned long int in Math::GMPz::overload_pow");
2903 }
2904 mpz_pow_ui(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))) , SvUVX(b));
2905 return obj_ref;
2906 }
2907
2908 if(SvIVX(b) < 0) croak("Negative argument supplied to Math::GMPz::overload_pow");
2909 if(third == &PL_sv_yes) {
2910 if(ui) {
2911 mpz_ui_pow_ui(*mpz_t_obj, SvUVX(b), ui);
2912 return obj_ref;
2913 }
2914 croak("Exponent does not fit into unsigned long int in Math::GMPz::overload_pow");
2915 }
2916 mpz_pow_ui(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), SvUVX(b));
2917 return obj_ref;
2918 }
2919
2920 if(sv_isobject(b)) {
2921 const char *h = HvNAME(SvSTASH(SvRV(b)));
2922 if(strEQ(h, "Math::GMPz")) {
2923 if(mpz_fits_uint_p(*(INT2PTR(mpz_t *, SvIVX(SvRV(b)))))) {
2924 New(1, mpz_t_obj, 1, mpz_t);
2925 if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_pow function");
2926 obj_ref = newSV(0);
2927 obj = newSVrv(obj_ref, "Math::GMPz");
2928 mpz_init(*mpz_t_obj);
2929 sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
2930 SvREADONLY_on(obj);
2931 ui = mpz_get_ui(*(INT2PTR(mpz_t *, SvIVX(SvRV(b)))));
2932 mpz_pow_ui(*mpz_t_obj, *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), ui);
2933 return obj_ref;
2934 }
2935 }
2936 if(strEQ(h, "Math::MPFR")) {
2937 _overload_callback("Math::MPFR::overload_pow", "Math::GMPz:overload_pow", &PL_sv_yes);
2938 }
2939 }
2940
2941 croak("Invalid argument supplied to Math::GMPz::overload_pow. Exponent must fit into unsigned long (or be a Math::MPFR object)");
2942 }
2943
overload_sqrt(pTHX_ mpz_t * p,SV * second,SV * third)2944 SV * overload_sqrt(pTHX_ mpz_t * p, SV * second, SV * third) {
2945 mpz_t * mpz_t_obj;
2946 SV * obj_ref, * obj;
2947
2948 New(1, mpz_t_obj, 1, mpz_t);
2949 if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_sqrt function");
2950 obj_ref = newSV(0);
2951 obj = newSVrv(obj_ref, "Math::GMPz");
2952 mpz_init(*mpz_t_obj);
2953
2954 if(mpz_cmp_ui(*p, 0) < 0) croak("Negative value supplied as argument to overload_sqrt");
2955 mpz_sqrt(*mpz_t_obj, *p);
2956 sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
2957 SvREADONLY_on(obj);
2958 return obj_ref;
2959 }
2960
overload_and(pTHX_ mpz_t * a,SV * b,SV * third,...)2961 SV * overload_and(pTHX_ mpz_t * a, SV * b, SV * third, ...) {
2962 mpz_t * mpz_t_obj;
2963 SV * obj_ref, * obj;
2964 MBI_DECLARATIONS
2965 MBI_GMP_DECLARATIONS
2966
2967 #if defined(USE_QUADMATH)
2968
2969 char * buffer;
2970 int returned;
2971 __float128 buffer_size;
2972 __float128 ld;
2973
2974 #elif defined(USE_LONG_DOUBLE)
2975
2976 char * buffer;
2977 long double buffer_size;
2978 long double ld;
2979
2980 #endif
2981
2982 New(1, mpz_t_obj, 1, mpz_t);
2983 if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_and function");
2984 obj_ref = newSV(0);
2985 obj = newSVrv(obj_ref, "Math::GMPz");
2986 mpz_init(*mpz_t_obj);
2987 sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
2988 SvREADONLY_on(obj);
2989
2990 #ifdef MATH_GMPZ_NEED_LONG_LONG_INT
2991 if(SV_IS_IOK(b)) {
2992 Rmpz_set_IV(aTHX_ mpz_t_obj, b);
2993 mpz_and(*mpz_t_obj, *a, *mpz_t_obj);
2994 return obj_ref;
2995 }
2996 #else
2997 if(SV_IS_IOK(b)) {
2998 if(SvUOK(b)) {
2999 mpz_set_ui(*mpz_t_obj, SvUVX(b));
3000 mpz_and(*mpz_t_obj, *a, *mpz_t_obj);
3001 return obj_ref;
3002 }
3003
3004 mpz_set_si(*mpz_t_obj, SvIVX(b));
3005 mpz_and(*mpz_t_obj, *a, *mpz_t_obj);
3006 return obj_ref;
3007 }
3008 #endif
3009
3010 if(SV_IS_POK(b)) {
3011 if(mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0))
3012 croak("Invalid string (%s) supplied to Math::GMPz::overload_and", SvPV_nolen(b));
3013 mpz_and(*mpz_t_obj, *a, *mpz_t_obj);
3014 return obj_ref;
3015 }
3016
3017 if(SV_IS_NOK(b)) {
3018
3019 #if defined(USE_QUADMATH)
3020
3021 ld = (__float128)SvNVX(b) >= 0 ? floorq((__float128)SvNVX(b)) : ceilq((__float128)SvNVX(b));
3022 if(ld != ld) croak("In Math::GMPz::overload_and, cannot coerce a NaN to a Math::GMPz value");
3023 if(ld != 0 && (ld / ld != 1))
3024 croak("In Math::GMPz::overload_and, cannot coerce an Inf to a Math::GMPz value");
3025
3026 buffer_size = ld < 0.0Q ? ld * -1.0Q : ld;
3027 buffer_size = ceilq(logq(buffer_size + 1) / 2.30258509299404568401799145468436418Q);
3028
3029 Newxz(buffer, (int)buffer_size + 5, char);
3030
3031 returned = quadmath_snprintf(buffer, (size_t)buffer_size + 5, "%.0Qf", ld);
3032 if(returned < 0) croak("In Math::GMPz::overload_and, encoding error in quadmath_snprintf function");
3033 if(returned >= buffer_size + 5) croak("In Math::GMPz::overload_and, buffer given to quadmath_snprintf function was too small");
3034 mpz_init_set_str(*mpz_t_obj, buffer, 10);
3035 Safefree(buffer);
3036
3037 #elif defined(USE_LONG_DOUBLE)
3038
3039 ld = (long double)SvNVX(b) >= 0 ? floorl((long double)SvNVX(b)) : ceill((long double)SvNVX(b));
3040 if(ld != ld) croak("In Math::GMPz::overload_and, cannot coerce a NaN to a Math::GMPz value");
3041 if(ld != 0 && (ld / ld != 1))
3042 croak("In Math::GMPz::overload_and, cannot coerce an Inf to a Math::GMPz value");
3043
3044 buffer_size = ld < 0.0L ? ld * -1.0L : ld;
3045 buffer_size = ceill(logl(buffer_size + 1) / 2.30258509299404568401799145468436418L);
3046
3047 Newxz(buffer, (int)buffer_size + 5, char);
3048
3049 if(sprintf(buffer, "%.0Lf", ld) >= (int)buffer_size + 5) croak("In Math::GMPz::overload_and, buffer overflow in sprintf function");
3050 mpz_init_set_str(*mpz_t_obj, buffer, 10);
3051 Safefree(buffer);
3052 #else
3053 double d = SvNVX(b);
3054 if(d != d) croak("In Math::GMPz::overload_and, cannot coerce a NaN to a Math::GMPz value");
3055 if(d != 0 && (d / d != 1))
3056 croak("In Math::GMPz::overload_and, cannot coerce an Inf to a Math::GMPz value");
3057 mpz_set_d(*mpz_t_obj, d);
3058 #endif
3059 mpz_and(*mpz_t_obj, *a, *mpz_t_obj);
3060 return obj_ref;
3061 }
3062
3063 if(sv_isobject(b)) {
3064 const char *h = HvNAME(SvSTASH(SvRV(b)));
3065 if(strEQ(h, "Math::GMPz")) {
3066 mpz_and(*mpz_t_obj, *a, *(INT2PTR(mpz_t *, SvIVX(SvRV(b)))));
3067 return obj_ref;
3068 }
3069 if(strEQ(h, "Math::BigInt")) {
3070 VALIDATE_MBI_OBJECT
3071 croak("Invalid Math::BigInt object supplied to Math::GMPz::overload_and");
3072
3073 MBI_GMP_INSERT
3074
3075 if(mpz) {
3076 if(strEQ("-", sign)) {
3077 mpz_neg((mpz_ptr)mpz, (mpz_srcptr)mpz);
3078 mpz_and(*mpz_t_obj, *a, (mpz_srcptr)mpz);
3079 mpz_neg((mpz_ptr)mpz, (mpz_srcptr)mpz); /* restore to original */
3080 return obj_ref;
3081 }
3082
3083 mpz_and(*mpz_t_obj, *a, (mpz_srcptr)mpz);
3084 return obj_ref;
3085 }
3086
3087 mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0);
3088 mpz_and(*mpz_t_obj, *a, *mpz_t_obj);
3089 return obj_ref;
3090 }
3091 }
3092
3093 croak("Invalid argument supplied to Math::GMPz::overload_and");
3094 }
3095
overload_ior(pTHX_ mpz_t * a,SV * b,SV * third,...)3096 SV * overload_ior(pTHX_ mpz_t * a, SV * b, SV * third, ...) {
3097 mpz_t * mpz_t_obj;
3098 SV * obj_ref, * obj;
3099 MBI_DECLARATIONS
3100 MBI_GMP_DECLARATIONS
3101
3102 #if defined(USE_QUADMATH)
3103
3104 char * buffer;
3105 int returned;
3106 __float128 buffer_size;
3107 __float128 ld;
3108
3109 #elif defined(USE_LONG_DOUBLE)
3110
3111 char * buffer;
3112 long double buffer_size;
3113 long double ld;
3114
3115 #endif
3116
3117 New(1, mpz_t_obj, 1, mpz_t);
3118 if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_ior function");
3119 obj_ref = newSV(0);
3120 obj = newSVrv(obj_ref, "Math::GMPz");
3121 mpz_init(*mpz_t_obj);
3122 sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
3123 SvREADONLY_on(obj);
3124
3125 #ifdef MATH_GMPZ_NEED_LONG_LONG_INT
3126 if(SV_IS_IOK(b)) {
3127 Rmpz_set_IV(aTHX_ mpz_t_obj, b);
3128 mpz_ior(*mpz_t_obj, *a, *mpz_t_obj);
3129 return obj_ref;
3130 }
3131 #else
3132 if(SV_IS_IOK(b)) {
3133 if(SvUOK(b)) {
3134 mpz_set_ui(*mpz_t_obj, SvUVX(b));
3135 mpz_ior(*mpz_t_obj, *a, *mpz_t_obj);
3136 return obj_ref;
3137 }
3138
3139 mpz_set_si(*mpz_t_obj, SvIVX(b));
3140 mpz_ior(*mpz_t_obj, *a, *mpz_t_obj);
3141 return obj_ref;
3142 }
3143 #endif
3144
3145 if(SV_IS_POK(b)) {
3146 if(mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0))
3147 croak("Invalid string (%s) supplied to Math::GMPz::overload_ior", SvPV_nolen(b));
3148 mpz_ior(*mpz_t_obj, *a, *mpz_t_obj);
3149 return obj_ref;
3150 }
3151
3152 if(SV_IS_NOK(b)) {
3153
3154 #if defined(USE_QUADMATH)
3155
3156 ld = (__float128)SvNVX(b) >= 0 ? floorq((__float128)SvNVX(b)) : ceilq((__float128)SvNVX(b));
3157 if(ld != ld) croak("In Math::GMPz::overload_ior, cannot coerce a NaN to a Math::GMPz value");
3158 if(ld != 0 && (ld / ld != 1))
3159 croak("In Math::GMPz::overload_ior, cannot coerce an Inf to a Math::GMPz value");
3160
3161 buffer_size = ld < 0.0Q ? ld * -1.0Q : ld;
3162 buffer_size = ceilq(logq(buffer_size + 1) / 2.30258509299404568401799145468436418Q);
3163
3164 Newxz(buffer, (int)buffer_size + 5, char);
3165
3166 returned = quadmath_snprintf(buffer, (size_t)buffer_size + 5, "%.0Qf", ld);
3167 if(returned < 0) croak("In Math::GMPz::overload_ior, encoding error in quadmath_snprintf function");
3168 if(returned >= buffer_size + 5) croak("In Math::GMPz::overload_ior, buffer given to quadmath_snprintf function was too small");
3169 mpz_init_set_str(*mpz_t_obj, buffer, 10);
3170 Safefree(buffer);
3171
3172 #elif defined(USE_LONG_DOUBLE)
3173
3174 ld = (long double)SvNVX(b) >= 0 ? floorl((long double)SvNVX(b)) : ceill((long double)SvNVX(b));
3175 if(ld != ld) croak("In Math::GMPz::overload_ior, cannot coerce a NaN to a Math::GMPz value");
3176 if(ld != 0 && (ld / ld != 1))
3177 croak("In Math::GMPz::overload_ior, cannot coerce an Inf to a Math::GMPz value");
3178
3179 buffer_size = ld < 0.0L ? ld * -1.0L : ld;
3180 buffer_size = ceill(logl(buffer_size + 1) / 2.30258509299404568401799145468436418L);
3181
3182 Newxz(buffer, (int)buffer_size + 5, char);
3183
3184 if(sprintf(buffer, "%.0Lf", ld) >= (int)buffer_size + 5) croak("In Math::GMPz::overload_ior, buffer overflow in sprintf function");
3185 mpz_init_set_str(*mpz_t_obj, buffer, 10);
3186 Safefree(buffer);
3187 #else
3188 double d = SvNVX(b);
3189 if(d != d) croak("In Math::GMPz::overload_ior, cannot coerce a NaN to a Math::GMPz value");
3190 if(d != 0 && (d / d != 1))
3191 croak("In Math::GMPz::overload_ior, cannot coerce an Inf to a Math::GMPz value");
3192 mpz_set_d(*mpz_t_obj, d);
3193 #endif
3194 mpz_ior(*mpz_t_obj, *a, *mpz_t_obj);
3195 return obj_ref;
3196 }
3197
3198 if(sv_isobject(b)) {
3199 const char *h = HvNAME(SvSTASH(SvRV(b)));
3200 if(strEQ(h, "Math::GMPz")) {
3201 mpz_ior(*mpz_t_obj, *a, *(INT2PTR(mpz_t *, SvIVX(SvRV(b)))));
3202 return obj_ref;
3203 }
3204 if(strEQ(h, "Math::BigInt")) {
3205 VALIDATE_MBI_OBJECT
3206 croak("Invalid Math::BigInt object supplied to Math::GMPz::overload_ior");
3207
3208 MBI_GMP_INSERT
3209
3210 if(mpz) {
3211 if(strEQ("-", sign)) {
3212 mpz_neg((mpz_ptr)mpz, (mpz_srcptr)mpz);
3213 mpz_ior(*mpz_t_obj, *a, (mpz_srcptr)mpz);
3214 mpz_neg((mpz_ptr)mpz, (mpz_srcptr)mpz); /* restore to original */
3215 return obj_ref;
3216 }
3217
3218 mpz_ior(*mpz_t_obj, *a, (mpz_srcptr)mpz);
3219 return obj_ref;
3220 }
3221
3222 mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0);
3223 mpz_ior(*mpz_t_obj, *a, *mpz_t_obj);
3224 return obj_ref;
3225 }
3226 }
3227
3228 croak("Invalid argument supplied to Math::GMPz::overload_ior");
3229 }
3230
overload_xor(pTHX_ mpz_t * a,SV * b,SV * third,...)3231 SV * overload_xor(pTHX_ mpz_t * a, SV * b, SV * third, ...) {
3232 mpz_t * mpz_t_obj;
3233 SV * obj_ref, * obj;
3234 MBI_DECLARATIONS
3235 MBI_GMP_DECLARATIONS
3236
3237 #if defined(USE_QUADMATH)
3238
3239 char * buffer;
3240 int returned;
3241 __float128 buffer_size;
3242 __float128 ld;
3243
3244 #elif defined(USE_LONG_DOUBLE)
3245
3246 char * buffer;
3247 long double buffer_size;
3248 long double ld;
3249
3250 #endif
3251
3252 New(1, mpz_t_obj, 1, mpz_t);
3253 if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_xor function");
3254 obj_ref = newSV(0);
3255 obj = newSVrv(obj_ref, "Math::GMPz");
3256 mpz_init(*mpz_t_obj);
3257 sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
3258 SvREADONLY_on(obj);
3259
3260 #ifdef MATH_GMPZ_NEED_LONG_LONG_INT
3261 if(SV_IS_IOK(b)) {
3262 Rmpz_set_IV(aTHX_ mpz_t_obj, b);
3263 mpz_xor(*mpz_t_obj, *a, *mpz_t_obj);
3264 return obj_ref;
3265 }
3266 #else
3267 if(SV_IS_IOK(b)) {
3268 if(SvUOK(b)) {
3269 mpz_set_ui(*mpz_t_obj, SvUVX(b));
3270 mpz_xor(*mpz_t_obj, *a, *mpz_t_obj);
3271 return obj_ref;
3272 }
3273
3274 mpz_set_si(*mpz_t_obj, SvIVX(b));
3275 mpz_xor(*mpz_t_obj, *a, *mpz_t_obj);
3276 return obj_ref;
3277 }
3278 #endif
3279
3280 if(SV_IS_POK(b)) {
3281 if(mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0))
3282 croak("Invalid string (%s) supplied to Math::GMPz::overload_xor", SvPV_nolen(b));
3283 mpz_xor(*mpz_t_obj, *a, *mpz_t_obj);
3284 return obj_ref;
3285 }
3286
3287 if(SV_IS_NOK(b)) {
3288
3289 #if defined(USE_QUADMATH)
3290
3291 ld = (__float128)SvNVX(b) >= 0 ? floorq((__float128)SvNVX(b)) : ceilq((__float128)SvNVX(b));
3292 if(ld != ld) croak("In Math::GMPz::overload_xor, cannot coerce a NaN to a Math::GMPz value");
3293 if(ld != 0 && (ld / ld != 1))
3294 croak("In Math::GMPz::overload_xor, cannot coerce an Inf to a Math::GMPz value");
3295
3296 buffer_size = ld < 0.0Q ? ld * -1.0Q : ld;
3297 buffer_size = ceilq(logq(buffer_size + 1) / 2.30258509299404568401799145468436418Q);
3298
3299 Newxz(buffer, (int)buffer_size + 5, char);
3300
3301 returned = quadmath_snprintf(buffer, (size_t)buffer_size + 5, "%.0Qf", ld);
3302 if(returned < 0) croak("In Math::GMPz::overload_xor, encoding error in quadmath_snprintf function");
3303 if(returned >= buffer_size + 5) croak("In Math::GMPz::overload_xor, buffer given to quadmath_snprintf function was too small");
3304 mpz_init_set_str(*mpz_t_obj, buffer, 10);
3305 Safefree(buffer);
3306
3307 #elif defined(USE_LONG_DOUBLE)
3308
3309 ld = (long double)SvNVX(b) >= 0 ? floorl((long double)SvNVX(b)) : ceill((long double)SvNVX(b));
3310 if(ld != ld) croak("In Math::GMPz::overload_xor, cannot coerce a NaN to a Math::GMPz value");
3311 if(ld != 0 && (ld / ld != 1))
3312 croak("In Math::GMPz::overload_xor, cannot coerce an Inf to a Math::GMPz value");
3313
3314 buffer_size = ld < 0.0L ? ld * -1.0L : ld;
3315 buffer_size = ceill(logl(buffer_size + 1) / 2.30258509299404568401799145468436418L);
3316
3317 Newxz(buffer, (int)buffer_size + 5, char);
3318
3319 if(sprintf(buffer, "%.0Lf", ld) >= (int)buffer_size + 5) croak("In Math::GMPz::overload_xor, buffer overflow in sprintf function");
3320 mpz_init_set_str(*mpz_t_obj, buffer, 10);
3321 Safefree(buffer);
3322 #else
3323 double d = SvNVX(b);
3324 if(d != d) croak("In Math::GMPz::overload_xor, cannot coerce a NaN to a Math::GMPz value");
3325 if(d != 0 && (d / d != 1))
3326 croak("In Math::GMPz::overload_xor, cannot coerce an Inf to a Math::GMPz value");
3327 mpz_set_d(*mpz_t_obj, d);
3328 #endif
3329 mpz_xor(*mpz_t_obj, *a, *mpz_t_obj);
3330 return obj_ref;
3331 }
3332
3333 if(sv_isobject(b)) {
3334 const char *h = HvNAME(SvSTASH(SvRV(b)));
3335 if(strEQ(h, "Math::GMPz")) {
3336 mpz_xor(*mpz_t_obj, *a, *(INT2PTR(mpz_t *, SvIVX(SvRV(b)))));
3337 return obj_ref;
3338 }
3339 if(strEQ(h, "Math::BigInt")) {
3340 VALIDATE_MBI_OBJECT
3341 croak("Invalid Math::BigInt object supplied to Math::GMPz::overload_xor");
3342
3343 MBI_GMP_INSERT
3344
3345 if(mpz) {
3346 if(strEQ("-", sign)) {
3347 mpz_neg((mpz_ptr)mpz, (mpz_srcptr)mpz);
3348 mpz_xor(*mpz_t_obj, *a, (mpz_srcptr)mpz);
3349 mpz_neg((mpz_ptr)mpz, (mpz_srcptr)mpz); /* restore to original */
3350 return obj_ref;
3351 }
3352
3353 mpz_xor(*mpz_t_obj, *a, (mpz_srcptr)mpz);
3354 return obj_ref;
3355 }
3356
3357 mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0);
3358 mpz_xor(*mpz_t_obj, *a, *mpz_t_obj);
3359 return obj_ref;
3360 }
3361 }
3362
3363 croak("Invalid argument supplied to Math::GMPz::overload_xor");
3364 }
3365
overload_com(pTHX_ mpz_t * p,SV * second,SV * third)3366 SV * overload_com(pTHX_ mpz_t * p, SV * second, SV * third) {
3367 mpz_t * mpz_t_obj;
3368 SV * obj_ref, * obj;
3369
3370 New(1, mpz_t_obj, 1, mpz_t);
3371 if(mpz_t_obj == NULL) croak("Failed to allocate memory in overload_com function");
3372 obj_ref = newSV(0);
3373 obj = newSVrv(obj_ref, "Math::GMPz");
3374 mpz_init(*mpz_t_obj);
3375
3376 mpz_com(*mpz_t_obj, *p);
3377 sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
3378 SvREADONLY_on(obj);
3379 return obj_ref;
3380 }
3381
my_cmp_z(mpq_t * p,mpz_t * z)3382 int my_cmp_z(mpq_t * p, mpz_t *z) {
3383 int ret;
3384 mpz_t temp;
3385
3386 mpz_init_set(temp, *z);
3387 mpz_mul(temp, temp, mpq_denref(*p));
3388 ret = mpz_cmp(mpq_numref(*p), temp);
3389 mpz_clear(temp);
3390 return ret;
3391 }
3392
overload_gt(pTHX_ mpz_t * a,SV * b,SV * third)3393 SV * overload_gt(pTHX_ mpz_t * a, SV * b, SV * third) {
3394 int ret;
3395 mpz_t t;
3396 MBI_DECLARATIONS
3397 MBI_GMP_DECLARATIONS
3398
3399 if(SV_IS_IOK(b)) {
3400 ret = Rmpz_cmp_IV(aTHX_ a, b);
3401 if(third == &PL_sv_yes) ret *= -1;
3402 if(ret > 0) return newSViv(1);
3403 return newSViv(0);
3404 }
3405
3406
3407 if(SV_IS_POK(b)) {
3408 ret = _is_infstring(SvPV_nolen(b));
3409 if(ret) {
3410 if(ret > 0) return newSViv(0);
3411 return newSViv(1);
3412 }
3413
3414 if(mpz_init_set_str(t, SvPV_nolen(b), 0))
3415 croak("Invalid string (%s) supplied to Math::GMPz::overload_gt", SvPV_nolen(b));
3416 ret = mpz_cmp(*a, t);
3417 mpz_clear(t);
3418 if(third == &PL_sv_yes) ret *= -1;
3419 if(ret > 0) return newSViv(1);
3420 return newSViv(0);
3421 }
3422
3423 if(SV_IS_NOK(b)) {
3424 ret = Rmpz_cmp_NV(aTHX_ a, b);
3425 if(third == &PL_sv_yes) ret *= -1;
3426 if(ret > 0) return newSViv(1);
3427 return newSViv(0);
3428 }
3429
3430 if(sv_isobject(b)) {
3431 const char *h = HvNAME(SvSTASH(SvRV(b)));
3432 if(strEQ(h, "Math::GMPz")) {
3433 ret = mpz_cmp(*a, *(INT2PTR(mpz_t *, SvIVX(SvRV(b)))));
3434 if(ret > 0) return newSViv(1);
3435 return newSViv(0);
3436 }
3437
3438 if(strEQ(h, "Math::GMPq")) {
3439 #if __GNU_MP_RELEASE < 60099
3440 ret = my_cmp_z(INT2PTR(mpq_t *, SvIVX(SvRV(b))), a);
3441 if(ret < 0) return newSViv(1);
3442 return newSViv(0);
3443 #else
3444 ret = mpq_cmp_z(*(INT2PTR(mpq_t *, SvIVX(SvRV(b)))), *a);
3445 if(ret < 0) return newSViv(1);
3446 return newSViv(0);
3447 #endif
3448 }
3449
3450 if(strEQ(h, "Math::BigInt")) {
3451 VALIDATE_MBI_OBJECT
3452 croak("Invalid Math::BigInt object supplied to Math::GMPz::overload_gt");
3453
3454 MBI_GMP_INSERT
3455
3456 if(mpz) {
3457 if(strEQ("-", sign)) {
3458 mpz_neg((mpz_ptr)mpz, (mpz_srcptr)mpz);
3459 ret = mpz_cmp(*a, (mpz_srcptr)mpz);
3460 mpz_neg((mpz_ptr)mpz, (mpz_srcptr)mpz); /* restore to original */
3461 if(ret > 0) return newSViv(1);
3462 return newSViv(0);
3463 }
3464
3465 ret = mpz_cmp(*a, (mpz_srcptr)mpz);
3466 if(ret > 0) return newSViv(1);
3467 return newSViv(0);
3468 }
3469
3470 mpz_init_set_str(t, SvPV_nolen(b), 0);
3471 ret = mpz_cmp(*a, t);
3472 mpz_clear(t);
3473 /* if(third == &PL_sv_yes) ret *= -1; */
3474 if(ret > 0) return newSViv(1);
3475 return newSViv(0);
3476 }
3477 }
3478
3479 croak("Invalid argument supplied to Math::GMPz::overload_gt");
3480 }
3481
overload_gte(pTHX_ mpz_t * a,SV * b,SV * third)3482 SV * overload_gte(pTHX_ mpz_t * a, SV * b, SV * third) {
3483 int ret;
3484 mpz_t t;
3485 MBI_DECLARATIONS
3486 MBI_GMP_DECLARATIONS
3487
3488 if(SV_IS_IOK(b)) {
3489 ret = Rmpz_cmp_IV(aTHX_ a, b);
3490 if(third == &PL_sv_yes) ret *= -1;
3491 if(ret >= 0) return newSViv(1);
3492 return newSViv(0);
3493 }
3494
3495 if(SV_IS_POK(b)) {
3496 ret = _is_infstring(SvPV_nolen(b));
3497 if(ret) {
3498 if(ret > 0) return newSViv(0);
3499 return newSViv(1);
3500 }
3501
3502 if(mpz_init_set_str(t, SvPV_nolen(b), 0))
3503 croak("Invalid string (%s) supplied to Math::GMPz::overload_gte", SvPV_nolen(b));
3504 ret = mpz_cmp(*a, t);
3505 mpz_clear(t);
3506 if(third == &PL_sv_yes) ret *= -1;
3507 if(ret >= 0) return newSViv(1);
3508 return newSViv(0);
3509 }
3510
3511 if(SV_IS_NOK(b)) {
3512 ret = Rmpz_cmp_NV(aTHX_ a, b);
3513 if(third == &PL_sv_yes) ret *= -1;
3514 if(ret >= 0) return newSViv(1);
3515 return newSViv(0);
3516 }
3517
3518 if(sv_isobject(b)) {
3519 const char *h = HvNAME(SvSTASH(SvRV(b)));
3520 if(strEQ(h, "Math::GMPz")) {
3521 ret = mpz_cmp(*a, *(INT2PTR(mpz_t *, SvIVX(SvRV(b)))));
3522 if(ret >= 0) return newSViv(1);
3523 return newSViv(0);
3524 }
3525
3526 if(strEQ(h, "Math::GMPq")) {
3527 #if __GNU_MP_RELEASE < 60099
3528 ret = my_cmp_z(INT2PTR(mpq_t *, SvIVX(SvRV(b))), a);
3529 if(ret <= 0) return newSViv(1);
3530 return newSViv(0);
3531 #else
3532 ret = mpq_cmp_z(*(INT2PTR(mpq_t *, SvIVX(SvRV(b)))), *a);
3533 if(ret <= 0) return newSViv(1);
3534 return newSViv(0);
3535 #endif
3536 }
3537
3538 if(strEQ(h, "Math::BigInt")) {
3539 VALIDATE_MBI_OBJECT
3540 croak("Invalid Math::BigInt object supplied to Math::GMPz::overload_gte");
3541
3542 MBI_GMP_INSERT
3543
3544 if(mpz) {
3545 if(strEQ("-", sign)) {
3546 mpz_neg((mpz_ptr)mpz, (mpz_srcptr)mpz);
3547 ret = mpz_cmp(*a, (mpz_srcptr)mpz);
3548 mpz_neg((mpz_ptr)mpz, (mpz_srcptr)mpz); /* restore to original */
3549 if(ret >= 0) return newSViv(1);
3550 return newSViv(0);
3551 }
3552
3553 ret = mpz_cmp(*a, (mpz_srcptr)mpz);
3554 if(ret >= 0) return newSViv(1);
3555 return newSViv(0);
3556 }
3557
3558 mpz_init_set_str(t, SvPV_nolen(b), 0);
3559 ret = mpz_cmp(*a, t);
3560 mpz_clear(t);
3561 /* if(third == &PL_sv_yes) ret *= -1; */
3562 if(ret >= 0) return newSViv(1);
3563 return newSViv(0);
3564 }
3565 }
3566
3567 croak("Invalid argument supplied to Math::GMPz::overload_gte");
3568 }
3569
overload_lt(pTHX_ mpz_t * a,SV * b,SV * third)3570 SV * overload_lt(pTHX_ mpz_t * a, SV * b, SV * third) {
3571 int ret;
3572 mpz_t t;
3573 MBI_DECLARATIONS
3574 MBI_GMP_DECLARATIONS
3575
3576 if(SV_IS_IOK(b)) {
3577 ret = Rmpz_cmp_IV(aTHX_ a, b);
3578 if(third == &PL_sv_yes) ret *= -1;
3579 if(ret < 0) return newSViv(1);
3580 return newSViv(0);
3581 }
3582
3583 if(SV_IS_POK(b)) {
3584 ret = _is_infstring(SvPV_nolen(b));
3585 if(ret) {
3586 if(ret > 0) return newSViv(1);
3587 return newSViv(0);
3588 }
3589
3590 if(mpz_init_set_str(t, SvPV_nolen(b), 0))
3591 croak("Invalid string (%s) supplied to Math::GMPz::overload_lt", SvPV_nolen(b));
3592 ret = mpz_cmp(*a, t);
3593 mpz_clear(t);
3594 if(third == &PL_sv_yes) ret *= -1;
3595 if(ret < 0) return newSViv(1);
3596 return newSViv(0);
3597 }
3598
3599 if(SV_IS_NOK(b)) {
3600 ret = Rmpz_cmp_NV(aTHX_ a, b);
3601 if(third == &PL_sv_yes) ret *= -1;
3602 if(ret < 0) return newSViv(1);
3603 return newSViv(0);
3604 }
3605
3606 if(sv_isobject(b)) {
3607 const char *h = HvNAME(SvSTASH(SvRV(b)));
3608 if(strEQ(h, "Math::GMPz")) {
3609 ret = mpz_cmp(*a, *(INT2PTR(mpz_t *, SvIVX(SvRV(b)))));
3610 if(ret < 0) return newSViv(1);
3611 return newSViv(0);
3612 }
3613
3614 if(strEQ(h, "Math::GMPq")) {
3615 #if __GNU_MP_RELEASE < 60099
3616 ret = my_cmp_z(INT2PTR(mpq_t *, SvIVX(SvRV(b))), a);
3617 if(ret > 0) return newSViv(1);
3618 return newSViv(0);
3619 #else
3620 ret = mpq_cmp_z(*(INT2PTR(mpq_t *, SvIVX(SvRV(b)))), *a);
3621 if(ret > 0) return newSViv(1);
3622 return newSViv(0);
3623 #endif
3624 }
3625
3626 if(strEQ(h, "Math::BigInt")) {
3627 VALIDATE_MBI_OBJECT
3628 croak("Invalid Math::BigInt object supplied to Math::GMPz::overload_lt");
3629
3630 MBI_GMP_INSERT
3631
3632 if(mpz) {
3633 if(strEQ("-", sign)) {
3634 mpz_neg((mpz_ptr)mpz, (mpz_srcptr)mpz);
3635 ret = mpz_cmp(*a, (mpz_srcptr)mpz);
3636 mpz_neg((mpz_ptr)mpz, (mpz_srcptr)mpz); /* restore to original */
3637 if(ret < 0) return newSViv(1);
3638 return newSViv(0);
3639 }
3640
3641 ret = mpz_cmp(*a, (mpz_srcptr)mpz);
3642 if(ret < 0) return newSViv(1);
3643 return newSViv(0);
3644 }
3645
3646 mpz_init_set_str(t, SvPV_nolen(b), 0);
3647 ret = mpz_cmp(*a, t);
3648 mpz_clear(t);
3649 /* if(third == &PL_sv_yes) ret *= -1; */
3650 if(ret < 0) return newSViv(1);
3651 return newSViv(0);
3652 }
3653 }
3654
3655 croak("Invalid argument supplied to Math::GMPz::overload_lt");
3656 }
3657
overload_lte(pTHX_ mpz_t * a,SV * b,SV * third)3658 SV * overload_lte(pTHX_ mpz_t * a, SV * b, SV * third) {
3659 int ret;
3660 mpz_t t;
3661 MBI_DECLARATIONS
3662 MBI_GMP_DECLARATIONS
3663
3664 if(SV_IS_IOK(b)) {
3665 ret = Rmpz_cmp_IV(aTHX_ a, b);
3666 if(third == &PL_sv_yes) ret *= -1;
3667 if(ret <= 0) return newSViv(1);
3668 return newSViv(0);
3669 }
3670
3671 if(SV_IS_POK(b)) {
3672 ret = _is_infstring(SvPV_nolen(b));
3673 if(ret) {
3674 if(ret > 0) return newSViv(1);
3675 return newSViv(0);
3676 }
3677
3678 if(mpz_init_set_str(t, SvPV_nolen(b), 0))
3679 croak("Invalid string (%s) supplied to Math::GMPz::overload_lte", SvPV_nolen(b));
3680 ret = mpz_cmp(*a, t);
3681 mpz_clear(t);
3682 if(third == &PL_sv_yes) ret *= -1;
3683 if(ret <= 0) return newSViv(1);
3684 return newSViv(0);
3685 }
3686
3687 if(SV_IS_NOK(b)) {
3688 ret = Rmpz_cmp_NV(aTHX_ a, b);
3689 if(third == &PL_sv_yes) ret *= -1;
3690 if(ret <= 0) return newSViv(1);
3691 return newSViv(0);
3692 }
3693
3694 if(sv_isobject(b)) {
3695 const char *h = HvNAME(SvSTASH(SvRV(b)));
3696 if(strEQ(h, "Math::GMPz")) {
3697 ret = mpz_cmp(*a, *(INT2PTR(mpz_t *, SvIVX(SvRV(b)))));
3698 if(ret <= 0) return newSViv(1);
3699 return newSViv(0);
3700 }
3701
3702 if(strEQ(h, "Math::GMPq")) {
3703 #if __GNU_MP_RELEASE < 60099
3704 ret = my_cmp_z(INT2PTR(mpq_t *, SvIVX(SvRV(b))), a);
3705 if(ret >= 0) return newSViv(1);
3706 return newSViv(0);
3707 #else
3708 ret = mpq_cmp_z(*(INT2PTR(mpq_t *, SvIVX(SvRV(b)))), *a);
3709 if(ret >= 0) return newSViv(1);
3710 return newSViv(0);
3711 #endif
3712 }
3713
3714 if(strEQ(h, "Math::BigInt")) {
3715 VALIDATE_MBI_OBJECT
3716 croak("Invalid Math::BigInt object supplied to Math::GMPz::overload_lte");
3717
3718 MBI_GMP_INSERT
3719
3720 if(mpz) {
3721 if(strEQ("-", sign)) {
3722 mpz_neg((mpz_ptr)mpz, (mpz_srcptr)mpz);
3723 ret = mpz_cmp(*a, (mpz_srcptr)mpz);
3724 mpz_neg((mpz_ptr)mpz, (mpz_srcptr)mpz); /* restore to original */
3725 if(ret <= 0) return newSViv(1);
3726 return newSViv(0);
3727 }
3728
3729 ret = mpz_cmp(*a, (mpz_srcptr)mpz);
3730 if(ret <= 0) return newSViv(1);
3731 return newSViv(0);
3732 }
3733
3734 mpz_init_set_str(t, SvPV_nolen(b), 0);
3735 ret = mpz_cmp(*a, t);
3736 mpz_clear(t);
3737 /* if(third == &PL_sv_yes) ret *= -1; */
3738 if(ret <= 0) return newSViv(1);
3739 return newSViv(0);
3740 }
3741 }
3742
3743 croak("Invalid argument supplied to Math::GMPz::overload_lte");
3744 }
3745
overload_spaceship(pTHX_ mpz_t * a,SV * b,SV * third)3746 SV * overload_spaceship(pTHX_ mpz_t * a, SV * b, SV * third) {
3747 int ret;
3748 mpz_t t;
3749 MBI_DECLARATIONS
3750 MBI_GMP_DECLARATIONS
3751
3752 if(SV_IS_IOK(b)) {
3753 ret = Rmpz_cmp_IV(aTHX_ a, b);
3754 if(third == &PL_sv_yes) ret *= -1;
3755 return newSViv(ret);
3756 }
3757
3758 if(SV_IS_POK(b)) {
3759 ret = _is_infstring(SvPV_nolen(b));
3760 if(ret) return newSViv(ret * -1);
3761
3762 if(mpz_init_set_str(t, SvPV_nolen(b), 0))
3763 croak("Invalid string (%s) supplied to Math::GMPz::overload_spaceship", SvPV_nolen(b));
3764 ret = mpz_cmp(*a, t);
3765 mpz_clear(t);
3766 if(third == &PL_sv_yes) ret *= -1;
3767 return newSViv(ret);
3768 }
3769
3770 if(SV_IS_NOK(b)) {
3771 ret = Rmpz_cmp_NV(aTHX_ a, b);
3772 if(third == &PL_sv_yes) ret *= -1;
3773 return newSViv(ret);
3774 }
3775
3776 if(sv_isobject(b)) {
3777 const char *h = HvNAME(SvSTASH(SvRV(b)));
3778 if(strEQ(h, "Math::GMPz")) {
3779 ret = mpz_cmp(*a, *(INT2PTR(mpz_t *, SvIVX(SvRV(b)))));
3780 return newSViv(ret);
3781 }
3782
3783 if(strEQ(h, "Math::GMPq")) {
3784 #if __GNU_MP_RELEASE < 60099
3785 ret = my_cmp_z(INT2PTR(mpq_t *, SvIVX(SvRV(b))), a);
3786 return newSViv(ret * -1);
3787 #else
3788 ret = mpq_cmp_z(*(INT2PTR(mpq_t *, SvIVX(SvRV(b)))), *a);
3789 return newSViv(ret * -1);
3790 #endif
3791 }
3792
3793 if(strEQ(h, "Math::BigInt")) {
3794 VALIDATE_MBI_OBJECT
3795 croak("Invalid Math::BigInt object supplied to Math::GMPz::overload_spaceship");
3796
3797 MBI_GMP_INSERT
3798
3799 if(mpz) {
3800 if(strEQ("-", sign)) {
3801 mpz_neg((mpz_ptr)mpz, (mpz_srcptr)mpz);
3802 ret = mpz_cmp(*a, (mpz_srcptr)mpz);
3803 mpz_neg((mpz_ptr)mpz, (mpz_srcptr)mpz); /* restore to original */
3804 return newSViv(ret);
3805 }
3806
3807 ret = mpz_cmp(*a, (mpz_srcptr)mpz);
3808 return newSViv(ret);
3809 }
3810
3811 mpz_init_set_str(t, SvPV_nolen(b), 0);
3812 ret = mpz_cmp(*a, t);
3813 mpz_clear(t);
3814 /* if(third == &PL_sv_yes) ret *= -1; */
3815 return newSViv(ret);
3816 }
3817 }
3818
3819 croak("Invalid argument supplied to Math::GMPz::overload_spaceship");
3820 }
3821
overload_equiv(pTHX_ mpz_t * a,SV * b,SV * third)3822 SV * overload_equiv(pTHX_ mpz_t * a, SV * b, SV * third) {
3823 int ret = 0;
3824 mpz_t t;
3825 MBI_DECLARATIONS
3826 MBI_GMP_DECLARATIONS
3827
3828 if(SV_IS_IOK(b)) {
3829 ret = Rmpz_cmp_IV(aTHX_ a, b);
3830 if(ret == 0) return newSViv(1);
3831 return newSViv(0);
3832 }
3833
3834 if(SV_IS_POK(b)) {
3835 if(_is_infstring(SvPV_nolen(b))) return newSViv(0);
3836 if(mpz_init_set_str(t, SvPV_nolen(b), 0))
3837 croak("Invalid string (%s) supplied to Math::GMPz::overload_equiv", SvPV_nolen(b));
3838 ret = mpz_cmp(*a, t);
3839 mpz_clear(t);
3840 if(ret == 0) return newSViv(1);
3841 return newSViv(0);
3842 }
3843
3844 if(SV_IS_NOK(b)) { /* do not use the NV if POK is set */
3845 ret = Rmpz_cmp_NV(aTHX_ a, b);
3846 if(ret == 0) return newSViv(1);
3847 return newSViv(0);
3848 }
3849
3850 if(sv_isobject(b)) {
3851 const char *h = HvNAME(SvSTASH(SvRV(b)));
3852 if(strEQ(h, "Math::GMPz")) {
3853 ret = mpz_cmp(*a, *(INT2PTR(mpz_t *, SvIVX(SvRV(b)))));
3854 if(ret == 0) return newSViv(1);
3855 return newSViv(0);
3856 }
3857
3858 if(strEQ(h, "Math::GMPq")) {
3859 #if __GNU_MP_RELEASE < 60099
3860 ret = my_cmp_z(INT2PTR(mpq_t *, SvIVX(SvRV(b))), a);
3861 if(ret == 0) return newSViv(1);
3862 return newSViv(0);
3863 #else
3864 ret = mpq_cmp_z(*(INT2PTR(mpq_t *, SvIVX(SvRV(b)))), *a);
3865 if(ret == 0) return newSViv(1);
3866 return newSViv(0);
3867 #endif
3868 }
3869
3870 if(strEQ(h, "Math::BigInt")) {
3871 VALIDATE_MBI_OBJECT
3872 croak("Invalid Math::BigInt object supplied to Math::GMPz::overload_equiv");
3873
3874 MBI_GMP_INSERT
3875
3876 if(mpz) {
3877 if(strEQ("-", sign)) {
3878 mpz_neg((mpz_ptr)mpz, (mpz_srcptr)mpz);
3879 ret = mpz_cmp(*a, (mpz_srcptr)mpz);
3880 mpz_neg((mpz_ptr)mpz, (mpz_srcptr)mpz); /* restore to original */
3881 if(ret == 0) return newSViv(1);
3882 return newSViv(0);
3883 }
3884
3885 ret = mpz_cmp(*a, (mpz_srcptr)mpz);
3886 if(ret == 0) return newSViv(1);
3887 return newSViv(0);
3888 }
3889
3890 mpz_init_set_str(t, SvPV_nolen(b), 0);
3891 ret = mpz_cmp(*a, t);
3892 mpz_clear(t);
3893 if(ret == 0) return newSViv(1);
3894 return newSViv(0);
3895 }
3896 }
3897
3898 croak("Invalid argument supplied to Math::GMPz::overload_equiv");
3899 }
3900
overload_not_equiv(pTHX_ mpz_t * a,SV * b,SV * third)3901 SV * overload_not_equiv(pTHX_ mpz_t * a, SV * b, SV * third) {
3902 int ret = 0;
3903 mpz_t t;
3904 MBI_DECLARATIONS
3905 MBI_GMP_DECLARATIONS
3906
3907 if(SV_IS_IOK(b)) {
3908 ret = Rmpz_cmp_IV(aTHX_ a, b);
3909 if(ret != 0) return newSViv(1);
3910 return newSViv(0);
3911 }
3912
3913 if(SV_IS_POK(b)) {
3914 if(_is_infstring(SvPV_nolen(b))) return newSViv(1);
3915 if(mpz_init_set_str(t, SvPV_nolen(b), 0))
3916 croak("Invalid string (%s) supplied to Math::GMPz::overload_not_equiv", SvPV_nolen(b));
3917 ret = mpz_cmp(*a, t);
3918 mpz_clear(t);
3919 if(ret != 0) return newSViv(1);
3920 return newSViv(0);
3921 }
3922
3923 if(SV_IS_NOK(b)) { /* do not use the NV if POK is set */
3924 ret = Rmpz_cmp_NV(aTHX_ a, b);
3925 if(ret != 0) return newSViv(1);
3926 return newSViv(0);
3927 }
3928
3929 if(sv_isobject(b)) {
3930 const char *h = HvNAME(SvSTASH(SvRV(b)));
3931 if(strEQ(h, "Math::GMPz")) {
3932 ret = mpz_cmp(*a, *(INT2PTR(mpz_t *, SvIVX(SvRV(b)))));
3933 if(ret != 0) return newSViv(1);
3934 return newSViv(0);
3935 }
3936
3937 if(strEQ(h, "Math::GMPq")) {
3938 #if __GNU_MP_RELEASE < 60099
3939 ret = my_cmp_z(INT2PTR(mpq_t *, SvIVX(SvRV(b))), a);
3940 if(ret != 0) return newSViv(1);
3941 return newSViv(0);
3942 #else
3943 ret = mpq_cmp_z(*(INT2PTR(mpq_t *, SvIVX(SvRV(b)))), *a);
3944 if(ret != 0) return newSViv(1);
3945 return newSViv(0);
3946 #endif
3947 }
3948
3949 if(strEQ(h, "Math::BigInt")) {
3950 VALIDATE_MBI_OBJECT
3951 croak("Invalid Math::BigInt object supplied to Math::GMPz::overload_not_equiv");
3952
3953 MBI_GMP_INSERT
3954
3955 if(mpz) {
3956 if(strEQ("-", sign)) {
3957 mpz_neg((mpz_ptr)mpz, (mpz_srcptr)mpz);
3958 ret = mpz_cmp(*a, (mpz_srcptr)mpz);
3959 mpz_neg((mpz_ptr)mpz, (mpz_srcptr)mpz); /* restore to original */
3960 if(ret != 0) return newSViv(1);
3961 return newSViv(0);
3962 }
3963
3964 ret = mpz_cmp(*a, (mpz_srcptr)mpz);
3965 if(ret != 0) return newSViv(1);
3966 return newSViv(0);
3967 }
3968
3969 mpz_init_set_str(t, SvPV_nolen(b), 0);
3970 ret = mpz_cmp(*a, t);
3971 mpz_clear(t);
3972 if(ret != 0) return newSViv(1);
3973 return newSViv(0);
3974 }
3975 }
3976
3977 croak("Invalid argument supplied to Math::GMPz::overload_not_equiv");
3978 }
3979
overload_not(pTHX_ mpz_t * a,SV * second,SV * third)3980 SV * overload_not(pTHX_ mpz_t * a, SV * second, SV * third) {
3981 if(mpz_cmp_ui(*a, 0)) return newSViv(0);
3982 return newSViv(1);
3983 }
3984
3985 /* Finish typemapping */
3986
overload_xor_eq(pTHX_ SV * a,SV * b,SV * third,...)3987 SV * overload_xor_eq(pTHX_ SV * a, SV * b, SV * third, ...) {
3988 mpz_t t;
3989 MBI_DECLARATIONS
3990 MBI_GMP_DECLARATIONS
3991
3992 #if defined(USE_QUADMATH)
3993
3994 char * buffer;
3995 int returned;
3996 __float128 buffer_size;
3997 __float128 ld;
3998
3999 #elif defined(USE_LONG_DOUBLE)
4000
4001 char * buffer;
4002 long double buffer_size;
4003 long double ld;
4004
4005 #endif
4006
4007 SvREFCNT_inc(a);
4008
4009 #ifdef MATH_GMPZ_NEED_LONG_LONG_INT
4010 if(SV_IS_IOK(b)) {
4011 if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
4012 SvREFCNT_dec(a);
4013 croak("Invalid string (%s)supplied to Math::GMPz::overload_xor_eq", SvPV_nolen(b));
4014 }
4015 mpz_xor(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), t);
4016 mpz_clear(t);
4017 return a;
4018 }
4019 #else
4020 if(SV_IS_IOK(b)) {
4021 if(SvUOK(b)) {
4022 mpz_init_set_ui(t, SvUVX(b));
4023 mpz_xor(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), t);
4024 mpz_clear(t);
4025 return a;
4026 }
4027
4028 mpz_init_set_si(t, SvIVX(b));
4029 mpz_xor(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), t);
4030 mpz_clear(t);
4031 return a;
4032 }
4033 #endif
4034
4035 if(SV_IS_POK(b)) {
4036 if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
4037 SvREFCNT_dec(a);
4038 croak("Invalid string (%s) supplied to Math::GMPz::overload_xor_eq", SvPV_nolen(b));
4039 }
4040 mpz_xor(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), t);
4041 mpz_clear(t);
4042 return a;
4043 }
4044
4045 if(SV_IS_NOK(b)) {
4046
4047 #if defined(USE_QUADMATH)
4048
4049 ld = (__float128)SvNVX(b) >= 0 ? floorq((__float128)SvNVX(b)) : ceilq((__float128)SvNVX(b));
4050 if(ld != ld) {
4051 SvREFCNT_dec(a);
4052 croak("In Math::GMPz::overload_xor_eq, cannot coerce a NaN to a Math::GMPz value");
4053 }
4054 if(ld != 0 && (ld / ld != 1)) {
4055 SvREFCNT_dec(a);
4056 croak("In Math::GMPz::overload_xor_eq, cannot coerce an Inf to a Math::GMPz value");
4057 }
4058
4059 buffer_size = ld < 0.0Q ? ld * -1.0Q : ld;
4060 buffer_size = ceilq(logq(buffer_size + 1) / 2.30258509299404568401799145468436418Q);
4061
4062 Newxz(buffer, (int)buffer_size + 5, char);
4063
4064 returned = quadmath_snprintf(buffer, (size_t)buffer_size + 5, "%.0Qf", ld);
4065 if(returned < 0) {
4066 SvREFCNT_dec(a);
4067 croak("In Math::GMPz::overload_xor_eq, encoding error in quadmath_snprintf function");
4068 }
4069 if(returned >= buffer_size + 5) {
4070 SvREFCNT_dec(a);
4071 croak("In Math::GMPz::overload_xor_eq, buffer given to quadmath_snprintf function was too small");
4072 }
4073 mpz_init_set_str(t, buffer, 10);
4074 Safefree(buffer);
4075
4076 #elif defined(USE_LONG_DOUBLE)
4077
4078 ld = (long double)SvNVX(b) >= 0 ? floorl((long double)SvNVX(b)) : ceill((long double)SvNVX(b));
4079 if(ld != ld) {
4080 SvREFCNT_dec(a);
4081 croak("In Math::GMPz::overload_xor_eq, cannot coerce a NaN to a Math::GMPz value");
4082 }
4083 if(ld != 0 && (ld / ld != 1)) {
4084 SvREFCNT_dec(a);
4085 croak("In Math::GMPz::overload_xor_eq, cannot coerce an Inf to a Math::GMPz value");
4086 }
4087
4088 buffer_size = ld < 0.0L ? ld * -1.0L : ld;
4089 buffer_size = ceill(logl(buffer_size + 1) / 2.30258509299404568401799145468436418L);
4090
4091 Newxz(buffer, (int)buffer_size + 5, char);
4092
4093 if(sprintf(buffer, "%.0Lf", ld) >= (int)buffer_size + 5) {
4094 SvREFCNT_dec(a);
4095 croak("In Math::GMPz::overload_xor_eq, buffer overflow in sprintf function");
4096 }
4097 mpz_init_set_str(t, buffer, 10);
4098 Safefree(buffer);
4099 #else
4100 double d = SvNVX(b);
4101 if(d != d) {
4102 SvREFCNT_dec(a);
4103 croak("In Math::GMPz::overload_xor_eq, cannot coerce a NaN to a Math::GMPz value");
4104 }
4105 if(d != 0 && (d / d != 1)) {
4106 SvREFCNT_dec(a);
4107 croak("In Math::GMPz::overload_xor_eq, cannot coerce an Inf to a Math::GMPz value");
4108 }
4109 mpz_init_set_d(t, d);
4110 #endif
4111 mpz_xor(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), t);
4112 mpz_clear(t);
4113 return a;
4114 }
4115
4116
4117 if(sv_isobject(b)) {
4118 const char *h = HvNAME(SvSTASH(SvRV(b)));
4119 if(strEQ(h, "Math::GMPz")) {
4120 mpz_xor(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(b)))));
4121 return a;
4122 }
4123
4124 if(strEQ(h, "Math::BigInt")) {
4125 VALIDATE_MBI_OBJECT {
4126 SvREFCNT_dec(a);
4127 croak("Invalid Math::BigInt object supplied to Math::GMPz::overload_xor_eq");
4128 }
4129
4130 MBI_GMP_INSERT
4131
4132 if(mpz) {
4133 if(strEQ("-", sign)) {
4134 mpz_neg((mpz_ptr)mpz, (mpz_srcptr)mpz);
4135 mpz_xor(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), (mpz_srcptr)mpz);
4136 mpz_neg((mpz_ptr)mpz, (mpz_srcptr)mpz); /* restore to original */
4137 return a;
4138 }
4139
4140 mpz_xor(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), (mpz_srcptr)mpz);
4141 return a;
4142 }
4143
4144 mpz_init_set_str(t, SvPV_nolen(b), 0);
4145 mpz_xor(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), t);
4146 mpz_clear(t);
4147 return a;
4148 }
4149 }
4150
4151 SvREFCNT_dec(a);
4152 croak("Invalid argument supplied to Math::GMPz::overload_xor_eq");
4153 }
4154
overload_ior_eq(pTHX_ SV * a,SV * b,SV * third,...)4155 SV * overload_ior_eq(pTHX_ SV * a, SV * b, SV * third, ...) {
4156 mpz_t t;
4157 MBI_DECLARATIONS
4158 MBI_GMP_DECLARATIONS
4159
4160 #if defined(USE_QUADMATH)
4161
4162 char * buffer;
4163 int returned;
4164 __float128 buffer_size;
4165 __float128 ld;
4166
4167 #elif defined(USE_LONG_DOUBLE)
4168
4169 char * buffer;
4170 long double buffer_size;
4171 long double ld;
4172
4173 #endif
4174
4175 SvREFCNT_inc(a);
4176
4177 #ifdef MATH_GMPZ_NEED_LONG_LONG_INT
4178 if(SV_IS_IOK(b)) {
4179 if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
4180 SvREFCNT_dec(a);
4181 croak("Invalid string (%s) supplied to Math::GMPz::overload_ior_eq", SvPV_nolen(b));
4182 }
4183 mpz_ior(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), t);
4184 mpz_clear(t);
4185 return a;
4186 }
4187 #else
4188 if(SV_IS_IOK(b)) {
4189 if(SvUOK(b)) {
4190 mpz_init_set_ui(t, SvUVX(b));
4191 mpz_ior(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), t);
4192 mpz_clear(t);
4193 return a;
4194 }
4195
4196 mpz_init_set_si(t, SvIVX(b));
4197 mpz_ior(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), t);
4198 mpz_clear(t);
4199 return a;
4200 }
4201 #endif
4202
4203 if(SV_IS_POK(b)) {
4204 if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
4205 SvREFCNT_dec(a);
4206 croak("Invalid string (%s) supplied to Math::GMPz::overload_ior_eq", SvPV_nolen(b));
4207 }
4208 mpz_ior(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), t);
4209 mpz_clear(t);
4210 return a;
4211 }
4212
4213 if(SV_IS_NOK(b)) {
4214
4215 #if defined(USE_QUADMATH)
4216
4217 ld = (__float128)SvNVX(b) >= 0 ? floorq((__float128)SvNVX(b)) : ceilq((__float128)SvNVX(b));
4218 if(ld != ld) {
4219 SvREFCNT_dec(a);
4220 croak("In Math::GMPz::overload_ior_eq, cannot coerce a NaN to a Math::GMPz value");
4221 }
4222 if(ld != 0 && (ld / ld != 1)) {
4223 SvREFCNT_dec(a);
4224 croak("In Math::GMPz::overload_ior_eq, cannot coerce an Inf to a Math::GMPz value");
4225 }
4226
4227 buffer_size = ld < 0.0Q ? ld * -1.0Q : ld;
4228 buffer_size = ceilq(logq(buffer_size + 1) / 2.30258509299404568401799145468436418Q);
4229
4230 Newxz(buffer, (int)buffer_size + 5, char);
4231
4232 returned = quadmath_snprintf(buffer, (size_t)buffer_size + 5, "%.0Qf", ld);
4233 if(returned < 0) {
4234 SvREFCNT_dec(a);
4235 croak("In Math::GMPz::overload_ior_eq, encoding error in quadmath_snprintf function");
4236 }
4237 if(returned >= buffer_size + 5) {
4238 SvREFCNT_dec(a);
4239 croak("In Math::GMPz::overload_ior_eq, buffer given to quadmath_snprintf function was too small");
4240 }
4241 mpz_init_set_str(t, buffer, 10);
4242 Safefree(buffer);
4243
4244 #elif defined(USE_LONG_DOUBLE)
4245
4246 ld = (long double)SvNVX(b) >= 0 ? floorl((long double)SvNVX(b)) : ceill((long double)SvNVX(b));
4247 if(ld != ld) {
4248 SvREFCNT_dec(a);
4249 croak("In Math::GMPz::overload_ior_eq, cannot coerce a NaN to a Math::GMPz value");
4250 }
4251 if(ld != 0 && (ld / ld != 1)) {
4252 SvREFCNT_dec(a);
4253 croak("In Math::GMPz::overload_ior_eq, cannot coerce an Inf to a Math::GMPz value");
4254 }
4255
4256 buffer_size = ld < 0.0L ? ld * -1.0L : ld;
4257 buffer_size = ceill(logl(buffer_size + 1) / 2.30258509299404568401799145468436418L);
4258
4259 Newxz(buffer, (int)buffer_size + 5, char);
4260
4261 if(sprintf(buffer, "%.0Lf", ld) >= (int)buffer_size + 5) {
4262 SvREFCNT_dec(a);
4263 croak("In Math::GMPz::overload_ior_eq, buffer overflow in sprintf function");
4264 }
4265 mpz_init_set_str(t, buffer, 10);
4266 Safefree(buffer);
4267 #else
4268 double d = SvNVX(b);
4269 if(d != d) {
4270 SvREFCNT_dec(a);
4271 croak("In Math::GMPz::overload_ior_eq, cannot coerce a NaN to a Math::GMPz value");
4272 }
4273 if(d != 0 && (d / d != 1)) {
4274 SvREFCNT_dec(a);
4275 croak("In Math::GMPz::overload_ior_eq, cannot coerce an Inf to a Math::GMPz value");
4276 }
4277 mpz_init_set_d(t, d);
4278 #endif
4279 mpz_ior(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), t);
4280 mpz_clear(t);
4281 return a;
4282 }
4283
4284 if(sv_isobject(b)) {
4285 const char *h = HvNAME(SvSTASH(SvRV(b)));
4286 if(strEQ(h, "Math::GMPz")) {
4287 mpz_ior(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(b)))));
4288 return a;
4289 }
4290
4291 if(strEQ(h, "Math::BigInt")) {
4292 VALIDATE_MBI_OBJECT {
4293 SvREFCNT_dec(a);
4294 croak("Invalid Math::BigInt object supplied to Math::GMPz::overload_ior_eq");
4295 }
4296
4297 MBI_GMP_INSERT
4298
4299 if(mpz) {
4300 if(strEQ("-", sign)) {
4301 mpz_neg((mpz_ptr)mpz, (mpz_srcptr)mpz);
4302 mpz_ior(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), (mpz_srcptr)mpz);
4303 mpz_neg((mpz_ptr)mpz, (mpz_srcptr)mpz); /* restore to original */
4304 return a;
4305 }
4306
4307 mpz_ior(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), (mpz_srcptr)mpz);
4308 return a;
4309 }
4310
4311 mpz_init_set_str(t, SvPV_nolen(b), 0);
4312 mpz_ior(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), t);
4313 mpz_clear(t);
4314 return a;
4315 }
4316 }
4317
4318 SvREFCNT_dec(a);
4319 croak("Invalid argument supplied to Math::GMPz::overload_ior_eq");
4320 }
4321
overload_and_eq(pTHX_ SV * a,SV * b,SV * third,...)4322 SV * overload_and_eq(pTHX_ SV * a, SV * b, SV * third, ...) {
4323 mpz_t t;
4324 MBI_DECLARATIONS
4325 MBI_GMP_DECLARATIONS
4326
4327 #if defined(USE_QUADMATH)
4328
4329 char * buffer;
4330 int returned;
4331 __float128 buffer_size;
4332 __float128 ld;
4333
4334 #elif defined(USE_LONG_DOUBLE)
4335
4336 char * buffer;
4337 long double buffer_size;
4338 long double ld;
4339
4340 #endif
4341
4342 SvREFCNT_inc(a);
4343
4344 #ifdef MATH_GMPZ_NEED_LONG_LONG_INT
4345 if(SV_IS_IOK(b)) {
4346 if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
4347 SvREFCNT_dec(a);
4348 croak("Invalid string (%s) supplied to Math::GMPz::overload_and_eq", SvPV_nolen(b));
4349 }
4350 mpz_and(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), t);
4351 mpz_clear(t);
4352 return a;
4353 }
4354 #else
4355 if(SV_IS_IOK(b)) {
4356 if(SvUOK(b)) {
4357 mpz_init_set_ui(t, SvUVX(b));
4358 mpz_and(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), t);
4359 mpz_clear(t);
4360 return a;
4361 }
4362
4363 mpz_init_set_si(t, SvIVX(b));
4364 mpz_and(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), t);
4365 mpz_clear(t);
4366 return a;
4367 }
4368 #endif
4369
4370 if(SV_IS_POK(b)) {
4371 if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
4372 SvREFCNT_dec(a);
4373 croak("Invalid string (%s) supplied to Math::GMPz::overload_and_eq", SvPV_nolen(b));
4374 }
4375 mpz_and(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), t);
4376 mpz_clear(t);
4377 return a;
4378 }
4379
4380 if(SV_IS_NOK(b)) {
4381
4382 #if defined(USE_QUADMATH)
4383
4384 ld = (__float128)SvNVX(b) >= 0 ? floorq((__float128)SvNVX(b)) : ceilq((__float128)SvNVX(b));
4385 if(ld != ld) {
4386 SvREFCNT_dec(a);
4387 croak("In Math::GMPz::overload_and_eq, cannot coerce a NaN to a Math::GMPz value");
4388 }
4389 if(ld != 0 && (ld / ld != 1)) {
4390 SvREFCNT_dec(a);
4391 croak("In Math::GMPz::overload_and_eq, cannot coerce an Inf to a Math::GMPz value");
4392 }
4393
4394 buffer_size = ld < 0.0Q ? ld * -1.0Q : ld;
4395 buffer_size = ceilq(logq(buffer_size + 1) / 2.30258509299404568401799145468436418Q);
4396
4397 Newxz(buffer, (int)buffer_size + 5, char);
4398
4399 returned = quadmath_snprintf(buffer, (size_t)buffer_size + 5, "%.0Qf", ld);
4400 if(returned < 0) {
4401 SvREFCNT_dec(a);
4402 croak("In Math::GMPz::overload_and_eq, encoding error in quadmath_snprintf function");
4403 }
4404 if(returned >= buffer_size + 5) {
4405 SvREFCNT_dec(a);
4406 croak("In Math::GMPz::overload_and_eq, buffer given to quadmath_snprintf function was too small");
4407 }
4408 mpz_init_set_str(t, buffer, 10);
4409 Safefree(buffer);
4410
4411 #elif defined(USE_LONG_DOUBLE)
4412
4413 ld = (long double)SvNVX(b) >= 0 ? floorl((long double)SvNVX(b)) : ceill((long double)SvNVX(b));
4414 if(ld != ld) {
4415 SvREFCNT_dec(a);
4416 croak("In Math::GMPz::overload_and_eq, cannot coerce a NaN to a Math::GMPz value");
4417 }
4418 if(ld != 0 && (ld / ld != 1)) {
4419 SvREFCNT_dec(a);
4420 croak("In Math::GMPz::overload_and_eq, cannot coerce an Inf to a Math::GMPz value");
4421 }
4422
4423 buffer_size = ld < 0.0L ? ld * -1.0L : ld;
4424 buffer_size = ceill(logl(buffer_size + 1) / 2.30258509299404568401799145468436418L);
4425
4426 Newxz(buffer, (int)buffer_size + 5, char);
4427
4428 if(sprintf(buffer, "%.0Lf", ld) >= (int)buffer_size + 5) {
4429 SvREFCNT_dec(a);
4430 croak("In Math::GMPz::overload_and_eq, buffer overflow in sprintf function");
4431 }
4432 mpz_init_set_str(t, buffer, 10);
4433 Safefree(buffer);
4434 #else
4435 double d = SvNVX(b);
4436 if(d != d) {
4437 SvREFCNT_dec(a);
4438 croak("In Math::GMPz::overload_and_eq, cannot coerce a NaN to a Math::GMPz value");
4439 }
4440 if(d != 0 && (d / d != 1)) {
4441 SvREFCNT_dec(a);
4442 croak("In Math::GMPz::overload_and_eq, cannot coerce an Inf to a Math::GMPz value");
4443 }
4444 mpz_init_set_d(t, d);
4445 #endif
4446 mpz_and(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), t);
4447 mpz_clear(t);
4448 return a;
4449 }
4450
4451 if(sv_isobject(b)) {
4452 const char *h = HvNAME(SvSTASH(SvRV(b)));
4453 if(strEQ(h, "Math::GMPz")) {
4454 mpz_and(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(b)))));
4455 return a;
4456 }
4457
4458 if(strEQ(h, "Math::BigInt")) {
4459 VALIDATE_MBI_OBJECT {
4460 SvREFCNT_dec(a);
4461 croak("Invalid Math::BigInt object supplied to Math::GMPz::overload_and_eq");
4462 }
4463
4464 MBI_GMP_INSERT
4465
4466 if(mpz) {
4467 if(strEQ("-", sign)) {
4468 mpz_neg((mpz_ptr)mpz, (mpz_srcptr)mpz);
4469 mpz_and(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), (mpz_srcptr)mpz);
4470 mpz_neg((mpz_ptr)mpz, (mpz_srcptr)mpz); /* restore to original */
4471 return a;
4472 }
4473
4474 mpz_and(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), (mpz_srcptr)mpz);
4475 return a;
4476 }
4477
4478 mpz_init_set_str(t, SvPV_nolen(b), 0);
4479 mpz_and(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), t);
4480 mpz_clear(t);
4481 return a;
4482 }
4483 }
4484
4485 SvREFCNT_dec(a);
4486 croak("Invalid argument supplied to Math::GMPz::overload_and_eq");
4487 }
4488
overload_pow_eq(pTHX_ SV * a,SV * b,SV * third)4489 SV * overload_pow_eq(pTHX_ SV * a, SV * b, SV * third) {
4490 SvREFCNT_inc(a);
4491
4492 if(SV_IS_IOK(b)) {
4493 if(SvUOK(b)) {
4494 mpz_pow_ui(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), SvUVX(b));
4495 return a;
4496 }
4497
4498 if(SvIVX(b) < 0) {
4499 SvREFCNT_dec(a);
4500 croak("Negative argument supplied to Math::GMPz::overload_pow_eq");
4501 }
4502 mpz_pow_ui(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), SvUVX(b));
4503 return a;
4504 }
4505
4506 if(sv_isobject(b)) {
4507 const char *h = HvNAME(SvSTASH(SvRV(b)));
4508 if(strEQ(h, "Math::GMPz")) {
4509 if(mpz_fits_uint_p(*(INT2PTR(mpz_t *, SvIVX(SvRV(b)))))) {
4510 mpz_pow_ui(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))),
4511 *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))),
4512 mpz_get_ui(*(INT2PTR(mpz_t *, SvIVX(SvRV(b))))));
4513 return a;
4514 }
4515 }
4516 }
4517
4518 SvREFCNT_dec(a);
4519 croak("Invalid argument supplied to Math::GMPz::overload_pow_eq. Exponent must fit into an unsigned long");
4520 }
4521
overload_rshift_eq(pTHX_ SV * a,SV * b,SV * third)4522 SV * overload_rshift_eq(pTHX_ SV * a, SV * b, SV * third) {
4523
4524 CHECK_MP_BITCNT_T_OVERFLOW(b)
4525
4526 SvREFCNT_inc(a);
4527
4528 if(SV_IS_IOK(b)) {
4529 if(SvUOK(b)) {
4530 mpz_tdiv_q_2exp(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), (mp_bitcnt_t)SvUVX(b));
4531 return a;
4532 }
4533
4534 if(SvIV(b) < 0) {
4535 SvREFCNT_dec(a);
4536 croak("Invalid argument supplied to Math::GMPz::overload_rshift_eq");
4537 }
4538 mpz_tdiv_q_2exp(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), (mp_bitcnt_t)SvUVX(b));
4539 return a;
4540 }
4541
4542 SvREFCNT_dec(a);
4543 croak("Invalid argument supplied to Math::GMPz::overload_rshift_eq");
4544 }
4545
overload_lshift_eq(pTHX_ SV * a,SV * b,SV * third)4546 SV * overload_lshift_eq(pTHX_ SV * a, SV * b, SV * third) {
4547
4548 CHECK_MP_BITCNT_T_OVERFLOW(b)
4549
4550 SvREFCNT_inc(a);
4551
4552 if(SV_IS_IOK(b)) {
4553 if(SvUOK(b)) {
4554 mpz_mul_2exp(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), (mp_bitcnt_t)SvUV(b));
4555 return a;
4556 }
4557
4558 if(SvIV(b) < 0) {
4559 SvREFCNT_dec(a);
4560 croak("Invalid argument supplied to Math::GMPz::overload_lshift_eq");
4561 }
4562 mpz_mul_2exp(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), (mp_bitcnt_t)SvUV(b));
4563 return a;
4564 }
4565
4566 SvREFCNT_dec(a);
4567 croak("Invalid argument supplied to Math::GMPz::overload_lshift_eq");
4568 }
4569
overload_inc(pTHX_ SV * p,SV * second,SV * third)4570 SV * overload_inc(pTHX_ SV * p, SV * second, SV * third) {
4571 SvREFCNT_inc(p);
4572 mpz_add_ui(*(INT2PTR(mpz_t *, SvIVX(SvRV(p)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(p)))), 1);
4573 return p;
4574 }
4575
overload_dec(pTHX_ SV * p,SV * second,SV * third)4576 SV * overload_dec(pTHX_ SV * p, SV * second, SV * third) {
4577 SvREFCNT_inc(p);
4578 mpz_sub_ui(*(INT2PTR(mpz_t *, SvIVX(SvRV(p)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(p)))), 1);
4579 return p;
4580 }
4581
overload_mod_eq(pTHX_ SV * a,SV * b,SV * third)4582 SV * overload_mod_eq(pTHX_ SV * a, SV * b, SV * third) {
4583 mpz_t t;
4584 MBI_DECLARATIONS
4585 MBI_GMP_DECLARATIONS
4586
4587 #if defined(USE_QUADMATH)
4588
4589 char * buffer;
4590 int returned;
4591 __float128 buffer_size;
4592 __float128 ld;
4593
4594 #elif defined(USE_LONG_DOUBLE)
4595
4596 char * buffer;
4597 long double buffer_size;
4598 long double ld;
4599
4600 #endif
4601
4602 SvREFCNT_inc(a);
4603
4604 #ifdef MATH_GMPZ_NEED_LONG_LONG_INT
4605 if(SV_IS_IOK(b)) {
4606 if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
4607 SvREFCNT_dec(a);
4608 croak("Invalid string (%s) supplied to Math::GMPz::overload_mod_eq", SvPV_nolen(b));
4609 }
4610 mpz_mod(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), t);
4611 mpz_clear(t);
4612 return a;
4613 }
4614 #else
4615 if(SV_IS_IOK(b)) {
4616 if(SvUOK(b)) {
4617 mpz_mod_ui(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), SvUVX(b));
4618 return a;
4619 }
4620
4621 if(SvIV(b) > 0) {
4622 mpz_mod_ui(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), SvUVX(b));
4623 return a;
4624 }
4625 mpz_init_set_si(t, SvIVX(b)); /* was SvNV(b) ?? */
4626 mpz_mod(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), t);
4627 mpz_clear(t);
4628 return a;
4629 }
4630 #endif
4631
4632 if(SV_IS_POK(b)) {
4633 if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
4634 SvREFCNT_dec(a);
4635 croak("Invalid string (%s) supplied to Math::GMPz::overload_mod_eq", SvPV_nolen(b));
4636 }
4637 mpz_mod(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), t);
4638 mpz_clear(t);
4639 return a;
4640 }
4641
4642 if(SV_IS_NOK(b)) {
4643
4644 #if defined(USE_QUADMATH)
4645
4646 ld = (__float128)SvNVX(b) >= 0 ? floorq((__float128)SvNVX(b)) : ceilq((__float128)SvNVX(b));
4647 if(ld != ld) {
4648 SvREFCNT_dec(a);
4649 croak("In Math::GMPz::overload_mod_eq, cannot coerce a NaN to a Math::GMPz value");
4650 }
4651 if(ld != 0 && (ld / ld != 1)) {
4652 SvREFCNT_dec(a);
4653 croak("In Math::GMPz::overload_mod_eq, cannot coerce an Inf to a Math::GMPz value");
4654 }
4655
4656 buffer_size = ld < 0.0Q ? ld * -1.0Q : ld;
4657 buffer_size = ceilq(logq(buffer_size + 1) / 2.30258509299404568401799145468436418Q);
4658
4659 Newxz(buffer, (int)buffer_size + 5, char);
4660
4661 returned = quadmath_snprintf(buffer, (size_t)buffer_size + 5, "%.0Qf", ld);
4662 if(returned < 0) {
4663 SvREFCNT_dec(a);
4664 croak("In Math::GMPz::overload_mod_eq, encoding error in quadmath_snprintf function");
4665 }
4666 if(returned >= buffer_size + 5) {
4667 SvREFCNT_dec(a);
4668 croak("In Math::GMPz::overload_mod_eq, buffer given to quadmath_snprintf function was too small");
4669 }
4670 mpz_init_set_str(t, buffer, 10);
4671 Safefree(buffer);
4672
4673 #elif defined(USE_LONG_DOUBLE)
4674
4675 ld = (long double)SvNVX(b) >= 0 ? floorl((long double)SvNVX(b)) : ceill((long double)SvNVX(b));
4676 if(ld != ld) {
4677 SvREFCNT_dec(a);
4678 croak("In Math::GMPz::overload_mod_eq, cannot coerce a NaN to a Math::GMPz value");
4679 }
4680 if(ld != 0 && (ld / ld != 1)) {
4681 SvREFCNT_dec(a);
4682 croak("In Math::GMPz::overload_mod_eq, cannot coerce an Inf to a Math::GMPz value");
4683 }
4684
4685 buffer_size = ld < 0.0L ? ld * -1.0L : ld;
4686 buffer_size = ceill(logl(buffer_size + 1) / 2.30258509299404568401799145468436418L);
4687
4688 Newxz(buffer, (int)buffer_size + 5, char);
4689
4690 if(sprintf(buffer, "%.0Lf", ld) >= (int)buffer_size + 5) {
4691 SvREFCNT_dec(a);
4692 croak("In Math::GMPz::overload_mod_eq, buffer overflow in sprintf function");
4693 }
4694 mpz_init_set_str(t, buffer, 10);
4695 Safefree(buffer);
4696 #else
4697 double d = SvNVX(b);
4698 if(d != d) {
4699 SvREFCNT_dec(a);
4700 croak("In Math::GMPz::overload_mod_eq, cannot coerce a NaN to a Math::GMPz value");
4701 }
4702 if(d != 0 && (d / d != 1)) {
4703 SvREFCNT_dec(a);
4704 croak("In Math::GMPz::overload_mod_eq, cannot coerce an Inf to a Math::GMPz value");
4705 }
4706 mpz_init_set_d(t, d);
4707 #endif
4708 mpz_mod(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), t);
4709 mpz_clear(t);
4710 return a;
4711 }
4712
4713 if(sv_isobject(b)) {
4714 const char *h = HvNAME(SvSTASH(SvRV(b)));
4715 if(strEQ(h, "Math::GMPz")) {
4716 mpz_mod(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(b)))));
4717 return a;
4718 }
4719
4720 if(strEQ(h, "Math::BigInt")) {
4721 VALIDATE_MBI_OBJECT {
4722 SvREFCNT_dec(a);
4723 croak("Invalid Math::BigInt object supplied to Math::GMPz::overload_mod_eq");
4724 }
4725
4726 MBI_GMP_INSERT
4727
4728 if(mpz) {
4729 /* if(strEQ("-", sign)) ...... not an issue for the divisor in a mod operation */
4730 mpz_mod(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), (mpz_srcptr)mpz);
4731 return a;
4732 }
4733
4734 mpz_init_set_str(t, SvPV_nolen(b), 0);
4735 mpz_mod(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), t);
4736 mpz_clear(t);
4737 return a;
4738 }
4739 }
4740
4741 SvREFCNT_dec(a);
4742 croak("Invalid argument supplied to Math::GMPz::overload_mod_eq");
4743 }
4744
get_refcnt(pTHX_ SV * s)4745 SV * get_refcnt(pTHX_ SV * s) {
4746 return newSVuv(SvREFCNT(s));
4747 }
4748
overload_div_eq(pTHX_ SV * a,SV * b,SV * third)4749 SV * overload_div_eq(pTHX_ SV * a, SV * b, SV * third) {
4750 mpz_t t;
4751 MBI_DECLARATIONS
4752 MBI_GMP_DECLARATIONS
4753
4754 #if defined(USE_QUADMATH)
4755
4756 char * buffer;
4757 int returned;
4758 __float128 buffer_size;
4759 __float128 ld;
4760
4761 #elif defined(USE_LONG_DOUBLE)
4762
4763 char * buffer;
4764 long double buffer_size;
4765 long double ld;
4766
4767 #endif
4768
4769 SvREFCNT_inc(a);
4770
4771 #ifdef MATH_GMPZ_NEED_LONG_LONG_INT
4772 if(SV_IS_IOK(b)) {
4773 if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
4774 SvREFCNT_dec(a);
4775 croak("Invalid string (%s) supplied to Math::GMPz::overload_div_eq", SvPV_nolen(b));
4776 }
4777 mpz_tdiv_q(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), t);
4778 mpz_clear(t);
4779 return a;
4780 }
4781 #else
4782 if(SV_IS_IOK(b)) {
4783 if(SvUOK(b)) {
4784 mpz_tdiv_q_ui(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), SvUVX(b));
4785 return a;
4786 }
4787
4788 if(SvIV(b) >= 0) {
4789 mpz_tdiv_q_ui(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), SvIVX(b));
4790 return a;
4791 }
4792 mpz_tdiv_q_ui(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), SvIVX(b) * -1);
4793 mpz_neg(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))));
4794 return a;
4795 }
4796 #endif
4797
4798 if(SV_IS_POK(b)) {
4799 if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
4800 SvREFCNT_dec(a);
4801 croak("Invalid string (%s) supplied to Math::GMPz::overload_div_eq", SvPV_nolen(b));
4802 }
4803 mpz_tdiv_q(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), t);
4804 mpz_clear(t);
4805 return a;
4806 }
4807
4808 if(SV_IS_NOK(b)) {
4809
4810 #if defined(USE_QUADMATH)
4811
4812 ld = (__float128)SvNVX(b) >= 0 ? floorq((__float128)SvNVX(b)) : ceilq((__float128)SvNVX(b));
4813 if(ld != ld) {
4814 SvREFCNT_dec(a);
4815 croak("In Math::GMPz::overload_div_eq, cannot coerce a NaN to a Math::GMPz value");
4816 }
4817 if(ld != 0 && (ld / ld != 1)) {
4818 SvREFCNT_dec(a);
4819 croak("In Math::GMPz::overload_div_eq, cannot coerce an Inf to a Math::GMPz value");
4820 }
4821
4822 buffer_size = ld < 0.0Q ? ld * -1.0Q : ld;
4823 buffer_size = ceilq(logq(buffer_size + 1) / 2.30258509299404568401799145468436418Q);
4824
4825 Newxz(buffer, (int)buffer_size + 5, char);
4826
4827 returned = quadmath_snprintf(buffer, (size_t)buffer_size + 5, "%.0Qf", ld);
4828 if(returned < 0) {
4829 SvREFCNT_dec(a);
4830 croak("In Math::GMPz::overload_div_eq, encoding error in quadmath_snprintf function");
4831 }
4832 if(returned >= buffer_size + 5) {
4833 SvREFCNT_dec(a);
4834 croak("In Math::GMPz::overload_div_eq, buffer given to quadmath_snprintf function was too small");
4835 }
4836 mpz_init_set_str(t, buffer, 10);
4837 Safefree(buffer);
4838
4839 #elif defined(USE_LONG_DOUBLE)
4840
4841 ld = (long double)SvNVX(b) >= 0 ? floorl((long double)SvNVX(b)) : ceill((long double)SvNVX(b));
4842 if(ld != ld) {
4843 SvREFCNT_dec(a);
4844 croak("In Math::GMPz::overload_div_eq, cannot coerce a NaN to a Math::GMPz value");
4845 }
4846 if(ld != 0 && (ld / ld != 1)) {
4847 SvREFCNT_dec(a);
4848 croak("In Math::GMPz::overload_div_eq, cannot coerce an Inf to a Math::GMPz value");
4849 }
4850
4851 buffer_size = ld < 0.0L ? ld * -1.0L : ld;
4852 buffer_size = ceill(logl(buffer_size + 1) / 2.30258509299404568401799145468436418L);
4853
4854 Newxz(buffer, (int)buffer_size + 5, char);
4855
4856 if(sprintf(buffer, "%.0Lf", ld) >= (int)buffer_size + 5) {
4857 SvREFCNT_dec(a);
4858 croak("In Math::GMPz::overload_div_eq, buffer overflow in sprintf function");
4859 }
4860 mpz_init_set_str(t, buffer, 10);
4861 Safefree(buffer);
4862 #else
4863 double d = SvNVX(b);
4864 if(d != d) {
4865 SvREFCNT_dec(a);
4866 croak("In Math::GMPz::overload_div_eq, cannot coerce a NaN to a Math::GMPz value");
4867 }
4868 if(d != 0 && (d / d != 1)) {
4869 SvREFCNT_dec(a);
4870 croak("In Math::GMPz::overload_div_eq, cannot coerce an Inf to a Math::GMPz value");
4871 }
4872 mpz_init_set_d(t, d);
4873 #endif
4874 mpz_tdiv_q(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), t);
4875 mpz_clear(t);
4876 return a;
4877 }
4878
4879 if(sv_isobject(b)) {
4880 const char *h = HvNAME(SvSTASH(SvRV(b)));
4881 if(strEQ(h, "Math::GMPz")) {
4882 mpz_tdiv_q(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(b)))));
4883 return a;
4884 }
4885
4886 if(strEQ(h, "Math::BigInt")) {
4887 VALIDATE_MBI_OBJECT {
4888 SvREFCNT_dec(a);
4889 croak("Invalid Math::BigInt object supplied to Math::GMPz::overload_div_eq");
4890 }
4891
4892 MBI_GMP_INSERT
4893
4894 if(mpz) {
4895 mpz_tdiv_q(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), (mpz_srcptr)mpz);
4896 if(strEQ("-", sign)) mpz_neg(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))));
4897 return a;
4898 }
4899
4900 mpz_init_set_str(t, SvPV_nolen(b), 0);
4901 mpz_tdiv_q(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), t);
4902 mpz_clear(t);
4903 return a;
4904 }
4905 }
4906
4907 SvREFCNT_dec(a);
4908 croak("Invalid argument supplied to Math::GMPz::overload_div_eq function");
4909
4910 }
4911
overload_sub_eq(pTHX_ SV * a,SV * b,SV * third)4912 SV * overload_sub_eq(pTHX_ SV * a, SV * b, SV * third) {
4913 mpz_t t;
4914 MBI_DECLARATIONS
4915 MBI_GMP_DECLARATIONS
4916
4917 #if defined(USE_QUADMATH)
4918
4919 char * buffer;
4920 int returned;
4921 __float128 buffer_size;
4922 __float128 ld;
4923
4924 #elif defined(USE_LONG_DOUBLE)
4925
4926 char * buffer;
4927 long double buffer_size;
4928 long double ld;
4929
4930 #endif
4931
4932 SvREFCNT_inc(a);
4933
4934 #ifdef MATH_GMPZ_NEED_LONG_LONG_INT
4935 if(SV_IS_IOK(b)) {
4936 if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
4937 SvREFCNT_dec(a);
4938 croak("Invalid string (%s) supplied to Math::GMPz::overload_sub_eq", SvPV_nolen(b));
4939 }
4940 mpz_sub(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), t);
4941 mpz_clear(t);
4942 return a;
4943 }
4944 #else
4945 if(SV_IS_IOK(b)) {
4946 if(SvUOK(b)) {
4947 mpz_sub_ui(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), SvUVX(b));
4948 return a;
4949 }
4950
4951 if(SvIV(b) >= 0) {
4952 mpz_sub_ui(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), SvIVX(b));
4953 return a;
4954 }
4955 mpz_add_ui(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), SvIVX(b) * -1);
4956 return a;
4957 }
4958 #endif
4959
4960 if(SV_IS_POK(b)) {
4961 if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
4962 SvREFCNT_dec(a);
4963 croak("Invalid string (%s) supplied to Math::GMPz::overload_sub_eq", SvPV_nolen(b));
4964 }
4965 mpz_sub(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), t);
4966 mpz_clear(t);
4967 return a;
4968 }
4969
4970 if(SV_IS_NOK(b)) {
4971
4972 #if defined(USE_QUADMATH)
4973
4974 ld = (__float128)SvNVX(b) >= 0 ? floorq((__float128)SvNVX(b)) : ceilq((__float128)SvNVX(b));
4975 if(ld != ld) {
4976 SvREFCNT_dec(a);
4977 croak("In Math::GMPz::overload_sub_eq, cannot coerce a NaN to a Math::GMPz value");
4978 }
4979 if(ld != 0 && (ld / ld != 1)) {
4980 SvREFCNT_dec(a);
4981 croak("In Math::GMPz::overload_sub_eq, cannot coerce an Inf to a Math::GMPz value");
4982 }
4983
4984 buffer_size = ld < 0.0Q ? ld * -1.0Q : ld;
4985 buffer_size = ceilq(logq(buffer_size + 1) / 2.30258509299404568401799145468436418Q);
4986
4987 Newxz(buffer, (int)buffer_size + 5, char);
4988
4989 returned = quadmath_snprintf(buffer, (size_t)buffer_size + 5, "%.0Qf", ld);
4990 if(returned < 0) {
4991 SvREFCNT_dec(a);
4992 croak("In Math::GMPz::overload_sub_eq, encoding error in quadmath_snprintf function");
4993 }
4994 if(returned >= buffer_size + 5) {
4995 SvREFCNT_dec(a);
4996 croak("In Math::GMPz::overload_sub_eq, buffer given to quadmath_snprintf function was too small");
4997 }
4998 mpz_init_set_str(t, buffer, 10);
4999 Safefree(buffer);
5000
5001 #elif defined(USE_LONG_DOUBLE)
5002
5003 ld = (long double)SvNVX(b) >= 0 ? floorl((long double)SvNVX(b)) : ceill((long double)SvNVX(b));
5004 if(ld != ld) {
5005 SvREFCNT_dec(a);
5006 croak("In Math::GMPz::overload_sub_eq, cannot coerce a NaN to a Math::GMPz value");
5007 }
5008 if(ld != 0 && (ld / ld != 1)) {
5009 SvREFCNT_dec(a);
5010 croak("In Math::GMPz::overload_sub_eq, cannot coerce an Inf to a Math::GMPz value");
5011 }
5012
5013 buffer_size = ld < 0.0L ? ld * -1.0L : ld;
5014 buffer_size = ceill(logl(buffer_size + 1) / 2.30258509299404568401799145468436418L);
5015
5016 Newxz(buffer, (int)buffer_size + 5, char);
5017
5018 if(sprintf(buffer, "%.0Lf", ld) >= (int)buffer_size + 5) {
5019 SvREFCNT_dec(a);
5020 croak("In Math::GMPz::overload_sub_eq, buffer overflow in sprintf function");
5021 }
5022 mpz_init_set_str(t, buffer, 10);
5023 Safefree(buffer);
5024 #else
5025 double d = SvNVX(b);
5026 if(d != d) {
5027 SvREFCNT_dec(a);
5028 croak("In Math::GMPz::overload_sub_eq, cannot coerce a NaN to a Math::GMPz value");
5029 }
5030 if(d != 0 && (d / d != 1)) {
5031 SvREFCNT_dec(a);
5032 croak("In Math::GMPz::overload_sub_eq, cannot coerce an Inf to a Math::GMPz value");
5033 }
5034 mpz_init_set_d(t, d);
5035 #endif
5036 mpz_sub(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), t);
5037 mpz_clear(t);
5038 return a;
5039 }
5040
5041 if(sv_isobject(b)) {
5042 const char *h = HvNAME(SvSTASH(SvRV(b)));
5043 if(strEQ(h, "Math::GMPz")) {
5044 mpz_sub(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(b)))));
5045 return a;
5046 }
5047
5048 if(strEQ(h, "Math::BigInt")) {
5049 VALIDATE_MBI_OBJECT {
5050 SvREFCNT_dec(a);
5051 croak("Invalid Math::BigInt object supplied to Math::GMPz::overload_sub_eq");
5052 }
5053
5054 MBI_GMP_INSERT
5055
5056 if(mpz) {
5057 if(strEQ("-", sign)) {
5058 mpz_add(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), (mpz_srcptr)mpz);
5059 return a;
5060 }
5061
5062 mpz_sub(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), (mpz_srcptr)mpz);
5063 return a;
5064 }
5065
5066 mpz_init_set_str(t, SvPV_nolen(b), 0);
5067 mpz_sub(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), t);
5068 mpz_clear(t);
5069 return a;
5070 }
5071 }
5072
5073 SvREFCNT_dec(a);
5074 croak("Invalid argument supplied to Math::GMPz::overload_sub_eq function");
5075
5076 }
5077
overload_add_eq(pTHX_ SV * a,SV * b,SV * third)5078 SV * overload_add_eq(pTHX_ SV * a, SV * b, SV * third) {
5079 mpz_t t;
5080 MBI_DECLARATIONS
5081 MBI_GMP_DECLARATIONS
5082
5083 #if defined(USE_QUADMATH)
5084
5085 char * buffer;
5086 int returned;
5087 __float128 buffer_size;
5088 __float128 ld;
5089
5090 #elif defined(USE_LONG_DOUBLE)
5091
5092 char * buffer;
5093 long double buffer_size;
5094 long double ld;
5095
5096 #endif
5097
5098 SvREFCNT_inc(a);
5099
5100 #ifdef MATH_GMPZ_NEED_LONG_LONG_INT
5101 if(SV_IS_IOK(b)) {
5102 if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
5103 SvREFCNT_dec(a);
5104 croak("Invalid string (%s) supplied to Math::GMPz::overload_add_eq", SvPV_nolen(b));
5105 }
5106 mpz_add(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), t);
5107 mpz_clear(t);
5108 return a;
5109 }
5110 #else
5111 if(SV_IS_IOK(b)) {
5112 if(SvUOK(b)) {
5113 mpz_add_ui(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), SvUVX(b));
5114 return a;
5115 }
5116
5117
5118 if(SvIV(b) >= 0) {
5119 mpz_add_ui(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), SvIVX(b));
5120 return a;
5121 }
5122 mpz_sub_ui(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), SvIVX(b) * -1);
5123 return a;
5124 }
5125 #endif
5126
5127 if(SV_IS_POK(b)) {
5128 if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
5129 SvREFCNT_dec(a);
5130 croak("Invalid string (%s) supplied to Math::GMPz::overload_add_eq", SvPV_nolen(b));
5131 }
5132 mpz_add(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), t);
5133 mpz_clear(t);
5134 return a;
5135 }
5136
5137 if(SV_IS_NOK(b)) {
5138
5139 #if defined(USE_QUADMATH)
5140
5141 ld = (__float128)SvNVX(b) >= 0 ? floorq((__float128)SvNVX(b)) : ceilq((__float128)SvNVX(b));
5142 if(ld != ld) {
5143 SvREFCNT_dec(a);
5144 croak("In Math::GMPz::overload_add_eq, cannot coerce a NaN to a Math::GMPz value");
5145 }
5146 if(ld != 0 && (ld / ld != 1)) {
5147 SvREFCNT_dec(a);
5148 croak("In Math::GMPz::overload_add_eq, cannot coerce an Inf to a Math::GMPz value");
5149 }
5150
5151 buffer_size = ld < 0.0Q ? ld * -1.0Q : ld;
5152 buffer_size = ceilq(logq(buffer_size + 1) / 2.30258509299404568401799145468436418Q);
5153
5154 Newxz(buffer, (int)buffer_size + 5, char);
5155
5156 returned = quadmath_snprintf(buffer, (size_t)buffer_size + 5, "%.0Qf", ld);
5157 if(returned < 0) {
5158 SvREFCNT_dec(a);
5159 croak("In Math::GMPz::overload_add_eq, encoding error in quadmath_snprintf function");
5160 }
5161 if(returned >= buffer_size + 5) {
5162 SvREFCNT_dec(a);
5163 croak("In Math::GMPz::overload_add_eq, buffer given to quadmath_snprintf function was too small");
5164 }
5165 mpz_init_set_str(t, buffer, 10);
5166 Safefree(buffer);
5167
5168 #elif defined(USE_LONG_DOUBLE)
5169
5170 ld = (long double)SvNVX(b) >= 0 ? floorl((long double)SvNVX(b)) : ceill((long double)SvNVX(b));
5171 if(ld != ld) {
5172 SvREFCNT_dec(a);
5173 croak("In Math::GMPz::overload_add_eq, cannot coerce a NaN to a Math::GMPz value");
5174 }
5175 if(ld != 0 && (ld / ld != 1)) {
5176 SvREFCNT_dec(a);
5177 croak("In Math::GMPz::overload_add_eq, cannot coerce an Inf to a Math::GMPz value");
5178 }
5179
5180 buffer_size = ld < 0.0L ? ld * -1.0L : ld;
5181 buffer_size = ceill(logl(buffer_size + 1) / 2.30258509299404568401799145468436418L);
5182
5183 Newxz(buffer, (int)buffer_size + 5, char);
5184
5185 if(sprintf(buffer, "%.0Lf", ld) >= (int)buffer_size + 5) {
5186 SvREFCNT_dec(a);
5187 croak("In Math::GMPz::overload_add_eq, buffer overflow in sprintf function");
5188 }
5189 mpz_init_set_str(t, buffer, 10);
5190 Safefree(buffer);
5191 #else
5192 double d = SvNVX(b);
5193 if(d != d) {
5194 SvREFCNT_dec(a);
5195 croak("In Math::GMPz::overload_add_eq, cannot coerce a NaN to a Math::GMPz value");
5196 }
5197 if(d != 0 && (d / d != 1)) {
5198 SvREFCNT_dec(a);
5199 croak("In Math::GMPz::overload_add_eq, cannot coerce an Inf to a Math::GMPz value");
5200 }
5201 mpz_init_set_d(t, d);
5202 #endif
5203 mpz_add(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), t);
5204 mpz_clear(t);
5205 return a;
5206 }
5207
5208 if(sv_isobject(b)) {
5209 const char *h = HvNAME(SvSTASH(SvRV(b)));
5210 if(strEQ(h, "Math::GMPz")) {
5211 mpz_add(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(b)))));
5212 return a;
5213 }
5214
5215 if(strEQ(h, "Math::BigInt")) {
5216 VALIDATE_MBI_OBJECT {
5217 SvREFCNT_dec(a);
5218 croak("Invalid Math::BigInt object supplied to Math::GMPz::overload_add_eq");
5219 }
5220
5221 MBI_GMP_INSERT
5222
5223 if(mpz) {
5224 if(strEQ("-", sign)) {
5225 mpz_sub(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), (mpz_srcptr)mpz);
5226 return a;
5227 }
5228
5229 mpz_add(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), (mpz_srcptr)mpz);
5230 return a;
5231 }
5232
5233 mpz_init_set_str(t, SvPV_nolen(b), 0);
5234 mpz_add(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), t);
5235 mpz_clear(t);
5236 return a;
5237 }
5238 }
5239
5240 SvREFCNT_dec(a);
5241 croak("Invalid argument supplied to Math::GMPz::overload_add_eq function");
5242
5243 }
5244
overload_mul_eq(pTHX_ SV * a,SV * b,SV * third)5245 SV * overload_mul_eq(pTHX_ SV * a, SV * b, SV * third) {
5246 mpz_t t;
5247 MBI_DECLARATIONS
5248 MBI_GMP_DECLARATIONS
5249
5250 #if defined(USE_QUADMATH)
5251
5252 char * buffer;
5253 int returned;
5254 __float128 buffer_size;
5255 __float128 ld;
5256
5257 #elif defined(USE_LONG_DOUBLE)
5258
5259 char * buffer;
5260 long double buffer_size;
5261 long double ld;
5262
5263 #endif
5264
5265 SvREFCNT_inc(a);
5266
5267 #ifdef MATH_GMPZ_NEED_LONG_LONG_INT
5268 if(SV_IS_IOK(b)) {
5269 if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
5270 SvREFCNT_dec(a);
5271 croak(" Invalid string (%s) supplied to Math::GMPz::overload_mul_eq", SvPV_nolen(b));
5272 }
5273 mpz_mul(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), t);
5274 mpz_clear(t);
5275 return a;
5276 }
5277 #else
5278 if(SV_IS_IOK(b)) {
5279 if(SvUOK(b)) {
5280 mpz_mul_ui(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), SvUVX(b));
5281 return a;
5282 }
5283
5284 mpz_mul_si(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), SvIVX(b));
5285 return a;
5286 }
5287 #endif
5288
5289 if(SV_IS_POK(b)) {
5290 if(mpz_init_set_str(t, SvPV_nolen(b), 0)) {
5291 SvREFCNT_dec(a);
5292 croak(" Invalid string (%s) supplied to Math::GMPz::overload_mul_eq", SvPV_nolen(b));
5293 }
5294 mpz_mul(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), t);
5295 mpz_clear(t);
5296 return a;
5297 }
5298
5299 if(SV_IS_NOK(b)) {
5300
5301 #if defined(USE_QUADMATH)
5302
5303 ld = (__float128)SvNVX(b) >= 0 ? floorq((__float128)SvNVX(b)) : ceilq((__float128)SvNVX(b));
5304 if(ld != ld) {
5305 SvREFCNT_dec(a);
5306 croak("In Math::GMPz::overload_mul_eq, cannot coerce a NaN to a Math::GMPz value");
5307 }
5308 if(ld != 0 && (ld / ld != 1)) {
5309 SvREFCNT_dec(a);
5310 croak("In Math::GMPz::overload_mul_eq, cannot coerce an Inf to a Math::GMPz value");
5311 }
5312
5313 buffer_size = ld < 0.0Q ? ld * -1.0Q : ld;
5314 buffer_size = ceilq(logq(buffer_size + 1) / 2.30258509299404568401799145468436418Q);
5315
5316 Newxz(buffer, (int)buffer_size + 5, char);
5317
5318 returned = quadmath_snprintf(buffer, (size_t)buffer_size + 5, "%.0Qf", ld);
5319 if(returned < 0) {
5320 SvREFCNT_dec(a);
5321 croak("In Math::GMPz::overload_mul_eq, encoding error in quadmath_snprintf function");
5322 }
5323 if(returned >= buffer_size + 5) {
5324 SvREFCNT_dec(a);
5325 croak("In Math::GMPz::overload_mul_eq, buffer given to quadmath_snprintf function was too small");
5326 }
5327 mpz_init_set_str(t, buffer, 10);
5328 Safefree(buffer);
5329
5330 #elif defined(USE_LONG_DOUBLE)
5331
5332 ld = (long double)SvNVX(b) >= 0 ? floorl((long double)SvNVX(b)) : ceill((long double)SvNVX(b));
5333 if(ld != ld) {
5334 SvREFCNT_dec(a);
5335 croak("In Math::GMPz::overload_mul_eq, cannot coerce a NaN to a Math::GMPz value");
5336 }
5337 if(ld != 0 && (ld / ld != 1)) {
5338 SvREFCNT_dec(a);
5339 croak("In Math::GMPz::overload_mul_eq, cannot coerce an Inf to a Math::GMPz value");
5340 }
5341
5342 buffer_size = ld < 0.0L ? ld * -1.0L : ld;
5343 buffer_size = ceill(logl(buffer_size + 1) / 2.30258509299404568401799145468436418L);
5344
5345 Newxz(buffer, (int)buffer_size + 5, char);
5346
5347 if(sprintf(buffer, "%.0Lf", ld) >= (int)buffer_size + 5) {
5348 SvREFCNT_dec(a);
5349 croak("In Math::GMPz::overload_mul_eq, buffer overflow in sprintf function");
5350 }
5351 mpz_init_set_str(t, buffer, 10);
5352 Safefree(buffer);
5353 #else
5354 double d = SvNVX(b);
5355 if(d != d) {
5356 SvREFCNT_dec(a);
5357 croak("In Math::GMPz::overload_mul_eq, cannot coerce a NaN to a Math::GMPz value");
5358 }
5359 if(d != 0 && (d / d != 1)) {
5360 SvREFCNT_dec(a);
5361 croak("In Math::GMPz::overload_mul_eq, cannot coerce an Inf to a Math::GMPz value");
5362 }
5363 mpz_init_set_d(t, d);
5364 #endif
5365 mpz_mul(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), t);
5366 mpz_clear(t);
5367 return a;
5368 }
5369
5370 if(sv_isobject(b)) {
5371 const char *h = HvNAME(SvSTASH(SvRV(b)));
5372 if(strEQ(h, "Math::GMPz")) {
5373 mpz_mul(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(b)))));
5374 return a;
5375 }
5376
5377 if(strEQ(h, "Math::BigInt")) {
5378 VALIDATE_MBI_OBJECT {
5379 SvREFCNT_dec(a);
5380 croak("Invalid Math::BigInt object supplied to Math::GMPz::overload_mul_eq");
5381 }
5382
5383 MBI_GMP_INSERT
5384
5385 if(mpz) {
5386 mpz_mul(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), (mpz_srcptr)mpz);
5387 if(strEQ("-", sign)) mpz_neg(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))));
5388 return a;
5389 }
5390
5391 mpz_init_set_str(t, SvPV_nolen(b), 0);
5392 mpz_mul(*(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), *(INT2PTR(mpz_t *, SvIVX(SvRV(a)))), t);
5393 mpz_clear(t);
5394 return a;
5395 }
5396 }
5397
5398 SvREFCNT_dec(a);
5399 croak("Invalid argument supplied to Math::GMPz::overload_mul_eq");
5400 }
5401
5402
5403
eratosthenes_string(pTHX_ SV * x_arg)5404 SV * eratosthenes_string(pTHX_ SV * x_arg) {
5405
5406 unsigned char *v, set[8] = {254,253,251,247,239,223,191,127};
5407 unsigned long leap, i, size, b, imax, k, x = (unsigned long)SvUV(x_arg);
5408 SV * ret;
5409
5410 if(x & 1) croak("max_num argument must be even in eratosthenes_string");
5411
5412 imax = sqrt(x - 1) / 2;
5413
5414 b = (x + 1) / 2;
5415
5416 if(!(b % 8)) size = b / 8;
5417 else size = (b / 8) + 1;
5418
5419 ret = NEWSV(0, size);
5420
5421 for(i = 1; i < size; ++i) SvPVX(ret)[i] = 255;
5422 SvPVX(ret)[0] = 254;
5423
5424 for(i = 0; i <= imax; ++i) {
5425
5426 if(SvPVX(ret)[i / 8] & (1 << (i % 8))) {
5427 leap = (2 * i) + 1;
5428 k = 2 * i * (i + 1);
5429 while(k < b) {
5430 SvPVX(ret)[k / 8] &= set[k % 8];
5431 k += leap;
5432 }
5433 }
5434 }
5435
5436 SvPOK_on(ret);
5437 SvCUR_set(ret, size);
5438 *SvEND(ret) = 0;
5439
5440 return ret;
5441
5442 }
5443
gmp_v(pTHX)5444 SV * gmp_v(pTHX) {
5445 #if __GNU_MP_VERSION >= 4
5446 return newSVpv(gmp_version, 0);
5447 #else
5448 warn("From Math::GMPz::gmp_v function: 'gmp_version' is not implemented - returning '0'");
5449 return newSVpv("0", 0);
5450 #endif
5451 }
5452
wrap_gmp_printf(pTHX_ SV * a,SV * b)5453 SV * wrap_gmp_printf(pTHX_ SV * a, SV * b) {
5454 int ret;
5455 if(sv_isobject(b)) {
5456 const char *h = HvNAME(SvSTASH(SvRV(b)));
5457 if(strEQ(h, "Math::GMPz") ||
5458 strEQ(h, "Math::GMP") ||
5459 strEQ(h, "GMP::Mpz")) {
5460 ret = gmp_printf(SvPV_nolen(a), *(INT2PTR(mpz_t *, SvIVX(SvRV(b)))));
5461 fflush(stdout);
5462 return newSViv(ret);
5463 }
5464 if(strEQ(h, "Math::GMPq") ||
5465 strEQ(h, "GMP::Mpq")) {
5466 ret = gmp_printf(SvPV_nolen(a), *(INT2PTR(mpq_t *, SvIVX(SvRV(b)))));
5467 fflush(stdout);
5468 return newSViv(ret);
5469 }
5470 if(strEQ(h, "Math::GMPf") ||
5471 strEQ(h, "GMP::Mpf")) {
5472 ret = gmp_printf(SvPV_nolen(a), *(INT2PTR(mpf_t *, SvIVX(SvRV(b)))));
5473 fflush(stdout);
5474 return newSViv(ret);
5475 }
5476
5477 croak("Unrecognised object supplied as argument to Rmpz_printf");
5478 }
5479
5480 if(SV_IS_IOK(b)) {
5481 if(SvUOK(b)) {
5482 ret = gmp_printf(SvPV_nolen(a), SvUVX(b));
5483 fflush(stdout);
5484 return newSViv(ret);
5485 }
5486
5487 ret = gmp_printf(SvPV_nolen(a), SvIVX(b));
5488 fflush(stdout);
5489 return newSViv(ret);
5490 }
5491
5492 if(SV_IS_POK(b)) {
5493 ret = gmp_printf(SvPV_nolen(a), SvPV_nolen(b));
5494 fflush(stdout);
5495 return newSViv(ret);
5496 }
5497
5498 if(SV_IS_NOK(b)) {
5499 ret = gmp_printf(SvPV_nolen(a), SvNVX(b));
5500 fflush(stdout);
5501 return newSViv(ret);
5502 }
5503
5504 croak("Unrecognised type supplied as argument to Rmpz_printf");
5505 }
5506
wrap_gmp_fprintf(pTHX_ FILE * stream,SV * a,SV * b)5507 SV * wrap_gmp_fprintf(pTHX_ FILE * stream, SV * a, SV * b) {
5508 int ret;
5509 if(sv_isobject(b)) {
5510 const char *h = HvNAME(SvSTASH(SvRV(b)));
5511 if(strEQ(h, "Math::GMPz") ||
5512 strEQ(h, "Math::GMP") ||
5513 strEQ(h, "GMP::Mpz")) {
5514 ret = gmp_fprintf(stream, SvPV_nolen(a), *(INT2PTR(mpz_t *, SvIVX(SvRV(b)))));
5515 fflush(stream);
5516 return newSViv(ret);
5517 }
5518 if(strEQ(h, "Math::GMPq") ||
5519 strEQ(h, "GMP::Mpq")) {
5520 ret = gmp_fprintf(stream, SvPV_nolen(a), *(INT2PTR(mpq_t *, SvIVX(SvRV(b)))));
5521 fflush(stream);
5522 return newSViv(ret);
5523 }
5524 if(strEQ(h, "Math::GMPf") ||
5525 strEQ(h, "GMP::Mpf")) {
5526 ret = gmp_fprintf(stream, SvPV_nolen(a), *(INT2PTR(mpf_t *, SvIVX(SvRV(b)))));
5527 fflush(stream);
5528 return newSViv(ret);
5529 }
5530
5531 else croak("Unrecognised object supplied as argument to Rmpz_fprintf");
5532 }
5533
5534 if(SV_IS_IOK(b)) {
5535 if(SvUOK(b)) {
5536 ret = gmp_fprintf(stream, SvPV_nolen(a), SvUVX(b));
5537 fflush(stream);
5538 return newSViv(ret);
5539 }
5540
5541 ret = gmp_fprintf(stream, SvPV_nolen(a), SvIVX(b));
5542 fflush(stream);
5543 return newSViv(ret);
5544 }
5545
5546 if(SV_IS_POK(b)) {
5547 ret = gmp_fprintf(stream, SvPV_nolen(a), SvPV_nolen(b));
5548 fflush(stream);
5549 return newSViv(ret);
5550 }
5551
5552 if(SV_IS_NOK(b)) {
5553 ret = gmp_fprintf(stream, SvPV_nolen(a), SvNVX(b));
5554 fflush(stream);
5555 return newSViv(ret);
5556 }
5557
5558 croak("Unrecognised type supplied as argument to Rmpz_fprintf");
5559 }
5560
wrap_gmp_sprintf(pTHX_ SV * s,SV * a,SV * b,int buflen)5561 SV * wrap_gmp_sprintf(pTHX_ SV * s, SV * a, SV * b, int buflen) {
5562 int ret;
5563 char *stream;
5564
5565 Newx(stream, buflen, char);
5566
5567 if(sv_isobject(b)) {
5568 const char *h = HvNAME(SvSTASH(SvRV(b)));
5569 if(strEQ(h, "Math::GMPz") ||
5570 strEQ(h, "Math::GMP") ||
5571 strEQ(h, "GMP::Mpz")) {
5572 ret = gmp_sprintf(stream, SvPV_nolen(a), *(INT2PTR(mpz_t *, SvIVX(SvRV(b)))));
5573 sv_setpv(s, stream);
5574 Safefree(stream);
5575 return newSViv(ret);
5576 }
5577
5578 if(strEQ(h, "Math::GMPq") ||
5579 strEQ(h, "GMP::Mpq")) {
5580 ret = gmp_sprintf(stream, SvPV_nolen(a), *(INT2PTR(mpq_t *, SvIVX(SvRV(b)))));
5581 sv_setpv(s, stream);
5582 Safefree(stream);
5583 return newSViv(ret);
5584 }
5585
5586 if(strEQ(h, "Math::GMPf") ||
5587 strEQ(h, "GMP::Mpf")) {
5588 ret = gmp_sprintf(stream, SvPV_nolen(a), *(INT2PTR(mpf_t *, SvIVX(SvRV(b)))));
5589 sv_setpv(s, stream);
5590 Safefree(stream);
5591 return newSViv(ret);
5592 }
5593
5594 croak("Unrecognised object supplied as argument to Rmpz_sprintf");
5595 }
5596
5597 if(SV_IS_IOK(b)) {
5598 if(SvUOK(b)) {
5599 ret = gmp_sprintf(stream, SvPV_nolen(a), SvUVX(b));
5600 sv_setpv(s, stream);
5601 Safefree(stream);
5602 return newSViv(ret);
5603 }
5604
5605 ret = gmp_sprintf(stream, SvPV_nolen(a), SvIVX(b));
5606 sv_setpv(s, stream);
5607 Safefree(stream);
5608 return newSViv(ret);
5609 }
5610
5611 if(SV_IS_POK(b)) {
5612 ret = gmp_sprintf(stream, SvPV_nolen(a), SvPV_nolen(b));
5613 sv_setpv(s, stream);
5614 Safefree(stream);
5615 return newSViv(ret);
5616 }
5617
5618 if(SV_IS_NOK(b)) {
5619 ret = gmp_sprintf(stream, SvPV_nolen(a), SvNVX(b));
5620 sv_setpv(s, stream);
5621 Safefree(stream);
5622 return newSViv(ret);
5623 }
5624
5625 croak("Unrecognised type supplied as argument to Rmpz_sprintf");
5626 }
5627
wrap_gmp_snprintf(pTHX_ SV * s,SV * bytes,SV * a,SV * b,int buflen)5628 SV * wrap_gmp_snprintf(pTHX_ SV * s, SV * bytes, SV * a, SV * b, int buflen) {
5629 int ret;
5630 char * stream;
5631
5632 Newx(stream, buflen, char);
5633
5634 if(sv_isobject(b)) {
5635 const char *h = HvNAME(SvSTASH(SvRV(b)));
5636 if(strEQ(h, "Math::GMPz") ||
5637 strEQ(h, "Math::GMP") ||
5638 strEQ(h, "GMP::Mpz")) {
5639 ret = gmp_snprintf(stream, (size_t)SvUV(bytes), SvPV_nolen(a), *(INT2PTR(mpz_t *, SvIVX(SvRV(b)))));
5640 sv_setpv(s, stream);
5641 Safefree(stream);
5642 return newSViv(ret);
5643 }
5644
5645 if(strEQ(h, "Math::GMPq") ||
5646 strEQ(h, "GMP::Mpq")) {
5647 ret = gmp_snprintf(stream, (size_t)SvUV(bytes), SvPV_nolen(a), *(INT2PTR(mpq_t *, SvIVX(SvRV(b)))));
5648 sv_setpv(s, stream);
5649 Safefree(stream);
5650 return newSViv(ret);
5651 }
5652
5653 if(strEQ(h, "Math::GMPf") ||
5654 strEQ(h, "GMP::Mpf")) {
5655 ret = gmp_snprintf(stream, (size_t)SvUV(bytes), SvPV_nolen(a), *(INT2PTR(mpf_t *, SvIVX(SvRV(b)))));
5656 sv_setpv(s, stream);
5657 Safefree(stream);
5658 return newSViv(ret);
5659 }
5660
5661 croak("Unrecognised object supplied as argument to Rmpz_snprintf");
5662 }
5663
5664 if(SV_IS_IOK(b)) {
5665 if(SvUOK(b)) {
5666 ret = gmp_snprintf(stream, (size_t)SvUV(bytes), SvPV_nolen(a), SvUVX(b));
5667 sv_setpv(s, stream);
5668 Safefree(stream);
5669 return newSViv(ret);
5670 }
5671
5672 ret = gmp_snprintf(stream, (size_t)SvUV(bytes), SvPV_nolen(a), SvIVX(b));
5673 sv_setpv(s, stream);
5674 Safefree(stream);
5675 return newSViv(ret);
5676 }
5677
5678 if(SV_IS_POK(b)) {
5679 ret = gmp_snprintf(stream, (size_t)SvUV(bytes), SvPV_nolen(a), SvPV_nolen(b));
5680 sv_setpv(s, stream);
5681 Safefree(stream);
5682 return newSViv(ret);
5683 }
5684
5685 if(SV_IS_NOK(b)) {
5686 ret = gmp_snprintf(stream, (size_t)SvUV(bytes), SvPV_nolen(a), SvNVX(b));
5687 sv_setpv(s, stream);
5688 Safefree(stream);
5689 return newSViv(ret);
5690 }
5691
5692 croak("Unrecognised type supplied as argument to Rmpz_snprintf");
5693 }
5694
_itsa(pTHX_ SV * a)5695 SV * _itsa(pTHX_ SV * a) {
5696 if(SV_IS_IOK(a)) {
5697 if(SvUOK(a)) return newSViv(1);
5698 return newSViv(2);
5699 }
5700 if(SV_IS_POK(a)) return newSViv(4);
5701 if(SV_IS_NOK(a)) return newSViv(3);
5702 if(sv_isobject(a)) {
5703 const char *h = HvNAME(SvSTASH(SvRV(a)));
5704 if(strEQ(h, "Math::GMPz")) return newSViv(8);
5705 if(strEQ(h, "Math::GMP")) return newSViv(9);
5706 if(strEQ(h, "Math::BigInt")) return newSViv(-1);
5707 }
5708 return newSVuv(0);
5709 }
5710
Rmpz_urandomb(pTHX_ SV * p,...)5711 void Rmpz_urandomb(pTHX_ SV * p, ...) {
5712 dXSARGS;
5713 unsigned long q, i, thingies;
5714
5715 thingies = items;
5716 q = SvUV(ST(thingies - 1));
5717
5718 if((q + 3) != thingies) croak ("Wrong args supplied to mpz_urandomb function");
5719
5720 for(i = 0; i < q; ++i) {
5721 mpz_urandomb(*(INT2PTR(mpz_t *, SvIVX(SvRV(ST(i))))), *(INT2PTR(gmp_randstate_t *, SvIVX(SvRV(ST(thingies - 3))))), SvUV(ST(thingies - 2)));
5722 }
5723
5724 XSRETURN(0);
5725 }
5726
Rmpz_urandomm(pTHX_ SV * x,...)5727 void Rmpz_urandomm(pTHX_ SV * x, ...){
5728 dXSARGS;
5729 unsigned long q, i, thingies;
5730
5731 thingies = items;
5732 q = SvUV(ST(thingies - 1));
5733
5734 if((q + 3) != thingies) croak ("Wrong args supplied to mpz_urandomm function");
5735
5736 for(i = 0; i < q; ++i) {
5737 mpz_urandomm(*(INT2PTR(mpz_t *, SvIVX(SvRV(ST(i))))), *(INT2PTR(gmp_randstate_t *, SvIVX(SvRV(ST(thingies - 3))))), *(INT2PTR(mpz_t *, SvIVX(SvRV(ST(thingies - 2))))));
5738 }
5739
5740 XSRETURN(0);
5741 }
5742
Rmpz_rrandomb(pTHX_ SV * x,...)5743 void Rmpz_rrandomb(pTHX_ SV * x, ...) {
5744 dXSARGS;
5745 unsigned long q, i, thingies;
5746
5747 thingies = items;
5748 q = SvUV(ST(thingies - 1));
5749
5750 if((q + 3) != thingies) croak ("Wrong args supplied to mpz_rrandomb function");
5751
5752 for(i = 0; i < q; ++i) {
5753 mpz_rrandomb(*(INT2PTR(mpz_t *, SvIVX(SvRV(ST(i))))), *(INT2PTR(gmp_randstate_t *, SvIVX(SvRV(ST(thingies - 3))))), SvUV(ST(thingies - 2)));
5754 }
5755
5756 XSRETURN(0);
5757 }
5758
rand_init(pTHX_ SV * seed)5759 SV * rand_init(pTHX_ SV * seed) {
5760 gmp_randstate_t * state;
5761 SV * obj_ref, * obj;
5762
5763 New(1, state, 1, gmp_randstate_t);
5764 if(state == NULL) croak("Failed to allocate memory in rand_init function");
5765 obj_ref = newSV(0);
5766 obj = newSVrv(obj_ref, NULL);
5767 gmp_randinit_default(*state);
5768 gmp_randseed(*state, *(INT2PTR(mpz_t *, SvIVX(SvRV(seed)))));
5769 sv_setiv(obj, INT2PTR(IV, state));
5770 SvREADONLY_on(obj);
5771 return obj_ref;
5772 }
5773
rand_clear(pTHX_ SV * p)5774 void rand_clear(pTHX_ SV * p) {
5775 gmp_randclear(*(INT2PTR(gmp_randstate_t *, SvIVX(SvRV(p)))));
5776 Safefree(INT2PTR(gmp_randstate_t *, SvIVX(SvRV(p))));
5777 }
5778
_has_longlong(void)5779 int _has_longlong(void) {
5780 #ifdef MATH_GMPZ_NEED_LONG_LONG_INT
5781 return 1;
5782 #else
5783 return 0;
5784 #endif
5785 }
5786
_has_longdouble(void)5787 int _has_longdouble(void) {
5788 #if defined(USE_LONG_DOUBLE)
5789 return 1;
5790 #else
5791 return 0;
5792 #endif
5793 }
5794
_has_float128(void)5795 int _has_float128(void) {
5796 #if defined(USE_QUADMATH)
5797 return 1;
5798 #else
5799 return 0;
5800 #endif
5801 }
5802
5803 /* Has inttypes.h been included ? */
_has_inttypes(void)5804 int _has_inttypes(void) {
5805 #ifdef _MSC_VER
5806 return 0;
5807 #else
5808 #if defined MATH_GMPZ_NEED_LONG_LONG_INT
5809 return 1;
5810 #else
5811 return 0;
5812 #endif
5813 #endif
5814 }
5815
Rmpz_inp_raw(pTHX_ mpz_t * a,FILE * stream)5816 SV * Rmpz_inp_raw(pTHX_ mpz_t * a, FILE * stream) {
5817 size_t ret = mpz_inp_raw(*a, stream);
5818 fflush(stream);
5819 return newSVuv(ret);
5820 }
5821
Rmpz_out_raw(pTHX_ FILE * stream,mpz_t * a)5822 SV * Rmpz_out_raw(pTHX_ FILE * stream, mpz_t * a) {
5823 size_t ret = mpz_out_raw(stream, *a);
5824 fflush(stream);
5825 return newSVuv(ret);
5826 }
5827
___GNU_MP_VERSION(pTHX)5828 SV * ___GNU_MP_VERSION(pTHX) {
5829 return newSVuv(__GNU_MP_VERSION);
5830 }
5831
___GNU_MP_VERSION_MINOR(pTHX)5832 SV * ___GNU_MP_VERSION_MINOR(pTHX) {
5833 return newSVuv(__GNU_MP_VERSION_MINOR);
5834 }
5835
___GNU_MP_VERSION_PATCHLEVEL(pTHX)5836 SV * ___GNU_MP_VERSION_PATCHLEVEL(pTHX) {
5837 return newSVuv(__GNU_MP_VERSION_PATCHLEVEL);
5838 }
5839
___GNU_MP_RELEASE(pTHX)5840 SV * ___GNU_MP_RELEASE(pTHX) {
5841 #if defined(__GNU_MP_RELEASE)
5842 return newSVuv(__GNU_MP_RELEASE);
5843 #else
5844 return &PL_sv_undef;
5845 #endif
5846 }
5847
___GMP_CC(pTHX)5848 SV * ___GMP_CC(pTHX) {
5849 #ifdef __GMP_CC
5850 char * ret = __GMP_CC;
5851 return newSVpv(ret, 0);
5852 #else
5853 return &PL_sv_undef;
5854 #endif
5855 }
5856
___GMP_CFLAGS(pTHX)5857 SV * ___GMP_CFLAGS(pTHX) {
5858 #ifdef __GMP_CFLAGS
5859 char * ret = __GMP_CFLAGS;
5860 return newSVpv(ret, 0);
5861 #else
5862 return &PL_sv_undef;
5863 #endif
5864 }
5865
5866 #if __GNU_MP_VERSION >= 5
5867 #ifndef __MPIR_VERSION
Rmpz_powm_sec(mpz_t * dest,mpz_t * base,mpz_t * exp,mpz_t * mod)5868 void Rmpz_powm_sec(mpz_t * dest, mpz_t * base, mpz_t * exp, mpz_t * mod) {
5869 mpz_powm_sec(*dest, *base, *exp, *mod);
5870 }
5871 #else
Rmpz_powm_sec(mpz_t * dest,mpz_t * base,mpz_t * exp,mpz_t * mod)5872 void Rmpz_powm_sec(mpz_t * dest, mpz_t * base, mpz_t * exp, mpz_t * mod) {
5873 croak("Rmpz_powm_sec not implemented by the mpir library");
5874 }
5875 #endif
5876 #else
Rmpz_powm_sec(mpz_t * dest,mpz_t * base,mpz_t * exp,mpz_t * mod)5877 void Rmpz_powm_sec(mpz_t * dest, mpz_t * base, mpz_t * exp, mpz_t * mod) {
5878 croak("Rmpz_powm_sec not implemented - gmp-5 or later needed, this is gmp-%d", __GNU_MP_VERSION);
5879 }
5880 #endif
5881
_using_mpir(void)5882 int _using_mpir(void) {
5883 #ifdef __MPIR_VERSION
5884 return 1;
5885 #else
5886 return 0;
5887 #endif
5888 }
5889
_Rmpz_NULL(pTHX)5890 SV * _Rmpz_NULL(pTHX) {
5891 mpz_t * mpz_t_obj;
5892 SV * obj_ref, * obj;
5893
5894 mpz_t_obj = NULL;
5895 obj_ref = newSV(0);
5896 obj = newSVrv(obj_ref, NULL);
5897
5898 sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
5899 SvREADONLY_on(obj);
5900 return obj_ref;
5901 }
5902
_wrap_count(pTHX)5903 SV * _wrap_count(pTHX) {
5904 return newSVuv(PL_sv_count);
5905 }
5906
Rprbg_ms(pTHX_ mpz_t * outref,mpz_t * p,mpz_t * q,mpz_t * seed,int bits_required)5907 void Rprbg_ms(pTHX_ mpz_t * outref, mpz_t * p, mpz_t * q, mpz_t * seed, int bits_required) {
5908 mpz_t n, phi, pless1, qless1, mod, keep;
5909 unsigned long e, k, bign, r, its, i, r_shift, check;
5910 double kdoub;
5911 gmp_randstate_t state;
5912
5913 mpz_init(n);
5914 mpz_init(phi);
5915 mpz_init(pless1);
5916 mpz_init(qless1);
5917
5918 mpz_sub_ui(qless1, *q, 1);
5919 mpz_sub_ui(pless1, *p, 1);
5920
5921 mpz_mul(n, *p, *q);
5922
5923 mpz_mul(phi, pless1, qless1);
5924 mpz_clear(pless1);
5925 mpz_clear(qless1);
5926
5927 bign = mpz_sizeinbase(n, 2);
5928 e = bign / 80;
5929
5930 while(1) {
5931 if(e < 1) croak("You need to choose larger primes P and Q. The product of P-1 and Q-1 needs to be at least an 80-bit number");
5932 if(mpz_gcd_ui(NULL, phi, e) == 1) break;
5933 --e;
5934 if(e < 3) croak("The chosen primes are unsuitable in prbg_ms() function");
5935 }
5936
5937 mpz_clear(phi);
5938
5939 kdoub = (double) 2 / (double) e;
5940 kdoub = (double) 1 - kdoub;
5941 kdoub *= (double) bign;
5942 k = kdoub;
5943 r = bign - k;
5944
5945 gmp_randinit_default(state);
5946 gmp_randseed(state, *seed);
5947 mpz_urandomb(*seed, state, r);
5948 gmp_randclear(state);
5949
5950 r_shift = bits_required % k;
5951
5952 if(r_shift) its = (bits_required / k) + 1;
5953 else its = bits_required / k;
5954
5955 mpz_init(mod);
5956 mpz_init(keep);
5957 mpz_set_ui(*outref, 0);
5958 mpz_ui_pow_ui(mod, 2, k);
5959
5960 for(i = 0; i < its; ++i) {
5961 mpz_powm_ui(*seed, *seed, e, n);
5962 mpz_mod(keep, *seed, mod);
5963 mpz_mul_2exp(*outref, *outref, k);
5964 mpz_add(*outref, *outref, keep);
5965 mpz_fdiv_q_2exp(*seed, *seed, k);
5966 if(!i) check = k - mpz_sizeinbase(keep, 2);
5967 }
5968 mpz_clear(n);
5969 mpz_clear(keep);
5970 mpz_clear(mod);
5971
5972 if(r_shift) mpz_fdiv_q_2exp(*outref, *outref, k - r_shift);
5973
5974 if(check + mpz_sizeinbase(*outref, 2) != bits_required)
5975 croak("Bug in csprng() function");
5976
5977 }
5978
Rprbg_bbs(pTHX_ mpz_t * outref,mpz_t * p,mpz_t * q,mpz_t * seed,int bits_required)5979 void Rprbg_bbs(pTHX_ mpz_t * outref, mpz_t * p, mpz_t * q, mpz_t * seed, int bits_required) {
5980 mpz_t n, gcd, one;
5981 unsigned long i, k;
5982 gmp_randstate_t state;
5983
5984 if(mpz_fdiv_ui(*p, 4) != 3) croak ("First prime is unsuitable for Blum-Blum-Shub prbg (must be congruent to 3, mod 4)");
5985 if(mpz_fdiv_ui(*q, 4) != 3) croak ("Second prime is unsuitable for Blum-Blum-Shub prbg (must be congruent to 3, mod 4)");
5986 mpz_init(n);
5987
5988 mpz_mul(n, *p, *q);
5989
5990 mpz_init(gcd);
5991 gmp_randinit_default(state);
5992 gmp_randseed(state, *seed);
5993 mpz_urandomm(*seed, state, n);
5994 gmp_randclear(state);
5995
5996 while(1) {
5997 if(mpz_cmp_ui(*seed, 100) < 0)croak("Blum-Blum-Shub seed is ridiculously small. How did this happen ?");
5998 mpz_gcd(gcd, *seed, n);
5999 if(!mpz_cmp_ui(gcd, 1)) break;
6000 mpz_sub_ui(*seed, *seed, 1);
6001 }
6002
6003 mpz_powm_ui(*seed, *seed, 2, n);
6004
6005 mpz_init_set_ui(*outref, 0);
6006 mpz_init_set_ui(one, 1);
6007
6008 for(i = 0; i < bits_required; ++i) {
6009 mpz_powm_ui(*seed, *seed, 2, n);
6010 k = mpz_tstbit(*seed, 0);
6011 if(k) {
6012 mpz_mul_2exp(gcd, one, i);
6013 mpz_add(*outref, gcd, *outref);
6014 }
6015 }
6016
6017 mpz_clear(n);
6018 mpz_clear(gcd);
6019 mpz_clear(one);
6020
6021 }
6022
Rmonobit(mpz_t * bitstream)6023 int Rmonobit(mpz_t * bitstream) {
6024 unsigned long len, i, count = 0;
6025
6026 len = mpz_sizeinbase(*bitstream, 2);
6027
6028 if(len > 20000) croak("Wrong size random sequence for monobit test");
6029 if(len < 19967) {
6030 warn("More than 33 leading zeroes in Rmonobit test\n");
6031 return 0;
6032 }
6033
6034 count = mpz_popcount(*bitstream);
6035
6036 if(count > 9654 && count < 10346) return 1;
6037 return 0;
6038
6039 }
6040
Rlong_run(mpz_t * bitstream)6041 int Rlong_run(mpz_t * bitstream) {
6042 unsigned int i, el, init = 0, count = 0, len, t;
6043
6044 len = mpz_sizeinbase(*bitstream, 2);
6045
6046 if(len > 20000) croak("Wrong size random sequence for Rlong_run test");
6047 if(len < 19967) {
6048 warn("More than 33 leading zeroes in long_run test\n");
6049 return 0;
6050 }
6051
6052 el = mpz_tstbit(*bitstream, 0);
6053
6054 for(i = 0; i < len; ++i) {
6055 t = mpz_tstbit(*bitstream, i);
6056 if(t == el) ++count;
6057 else {
6058 el = t;
6059 if(count > init) init = count;
6060 count = 1;
6061 }
6062 }
6063
6064 if(init < 34 && count < 34) return 1;
6065 else warn("init: %u count: %u", init, count);
6066 return 0;
6067
6068 }
6069
Rruns(mpz_t * bitstream)6070 int Rruns(mpz_t * bitstream) {
6071 int b[6] = {0,0,0,0,0,0}, g[6] = {0,0,0,0,0,0},
6072 len, count = 1, i, t, diff;
6073
6074 len = mpz_sizeinbase(*bitstream, 2);
6075 diff = 20000 - len;
6076
6077 if(len > 20000) croak("Wrong size random sequence for monobit test");
6078 if(len < 19967) {
6079 warn("More than 33 leading zeroes in runs test\n");
6080 return 0;
6081 }
6082
6083 --len;
6084
6085 for(i = 0; i < len; ++i) {
6086 t = mpz_tstbit(*bitstream, i);
6087 if(t == mpz_tstbit(*bitstream, i + 1)) ++ count;
6088 else {
6089 if(t) {
6090 if(count >= 6) ++b[5];
6091 else ++b[count - 1];
6092 }
6093 else {
6094 if(count >= 6) ++g[5];
6095 else ++g[count - 1];
6096 }
6097 count = 1;
6098 }
6099 }
6100
6101 if(count >= 6) {
6102 if(mpz_tstbit(*bitstream, len)) {
6103 ++b[5];
6104 if(diff >= 6) {
6105 ++g[5];
6106 }
6107 else {
6108 if(diff) ++g[diff - 1];
6109 }
6110 }
6111 else ++g[5];
6112 }
6113 else {
6114 if(mpz_tstbit(*bitstream, len)) {
6115 ++b[count - 1];
6116 if(diff >= 6) {
6117 ++g[5];
6118 }
6119 else {
6120 if(diff) ++ g[diff - 1];
6121 }
6122 }
6123 else {
6124 count += diff;
6125 count >= 6 ? ++g[5] : ++g[count - 1];
6126 }
6127 }
6128
6129
6130 if (
6131 b[0] <= 2267 || g[0] <= 2267 ||
6132 b[0] >= 2733 || g[0] >= 2733 ||
6133 b[1] <= 1079 || g[1] <= 1079 ||
6134 b[1] >= 1421 || g[1] >= 1421 ||
6135 b[2] <= 502 || g[2] <= 502 ||
6136 b[2] >= 748 || g[2] >= 748 ||
6137 b[3] <= 223 || g[3] <= 223 ||
6138 b[3] >= 402 || g[3] >= 402 ||
6139 b[4] <= 90 || g[4] <= 90 ||
6140 b[4] >= 223 || g[4] >= 223 ||
6141 b[5] <= 90 || g[5] <= 90 ||
6142 b[5] >= 223 || g[5] >= 223
6143 ) return 0;
6144
6145 return 1;
6146
6147 }
6148
Rpoker(mpz_t * bitstream)6149 int Rpoker (mpz_t * bitstream) {
6150 int counts[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
6151 len, i, st, diff;
6152 double n = 0;
6153
6154 len = mpz_sizeinbase(*bitstream, 2);
6155
6156 if(len > 20000) croak("Wrong size random sequence for poker test");
6157 if(len < 19967) {
6158 warn("More than 33 leading zeroes in poker test\n");
6159 return 0;
6160 }
6161
6162 /* pad with trailing zeroes (if necessary) to achieve length of 20000 bits. */
6163 diff = 20000 - len;
6164 if(diff) mpz_mul_2exp(*bitstream, *bitstream, diff);
6165 if(mpz_sizeinbase(*bitstream, 2) != 20000) croak("Bug in bit sequence manipulation in poker() function");
6166
6167 for(i = 0; i < 20000; i += 4) {
6168 st = mpz_tstbit(*bitstream, i) +
6169 (mpz_tstbit(*bitstream, i + 1) * 2) +
6170 (mpz_tstbit(*bitstream, i + 2) * 4) +
6171 (mpz_tstbit(*bitstream, i + 3) * 8);
6172 ++counts[st];
6173 }
6174
6175
6176 for(i = 0; i < 16; ++i) n += counts[i] * counts[i];
6177
6178 n /= 5000;
6179 n *= 16;
6180 n -= 5000;
6181
6182 if(n > 1.03 && n < 57.4) return 1;
6183
6184 return 0;
6185 }
6186
_get_xs_version(pTHX)6187 SV * _get_xs_version(pTHX) {
6188 return newSVpv(XS_VERSION, 0);
6189 }
6190
query_eratosthenes_string(pTHX_ int candidate,char * str)6191 SV * query_eratosthenes_string(pTHX_ int candidate, char * str) {
6192 int cand = candidate - 1;
6193 if(cand == 1) return newSVuv(1);
6194 if(cand & 1 || cand <= 0) return newSVuv(0);
6195 if(str[cand / 16] & 1 << (cand / 2) % 8)
6196 return newSVuv(1);
6197 return newSVuv(0);
6198 }
6199
autocorrelation(pTHX_ mpz_t * bitstream,int offset)6200 void autocorrelation(pTHX_ mpz_t * bitstream, int offset) {
6201 dXSARGS;
6202 int i, index, last, count = 0, short_ = 0;
6203 mpz_t temp;
6204 double x, diff;
6205 int len = mpz_sizeinbase(*bitstream, 2);
6206
6207 if(len > 20000) croak("Wrong size random sequence for autocorrelation test");
6208 if(len < 19967) {
6209 warn("More than 33 leading zeroes in autocorrelation test\n");
6210 ST(0) = sv_2mortal(newSViv(0));
6211 ST(1) = sv_2mortal(newSVnv(0.0));
6212 XSRETURN(2);
6213 }
6214
6215 /* make sure *bitstream has a length of 20000 bits. */
6216 if(20000 - len) {
6217 short_ = 1;
6218 mpz_init_set_ui(temp, 1);
6219 mpz_mul_2exp(temp, temp, 19999);
6220 mpz_add(*bitstream, *bitstream, temp);
6221 }
6222 if(mpz_sizeinbase(*bitstream, 2) != 20000) croak("Bit sequence has length of %d bits in autocorrelation function", (int)mpz_sizeinbase(*bitstream, 2));
6223
6224 index = 19999 - offset;
6225 for(i = 0; i < index - 1; ++i) {
6226 if(mpz_tstbit(*bitstream, i) ^ mpz_tstbit(*bitstream, i + offset)) count += 1;
6227 }
6228
6229 last = short_ ? 0 : 1;
6230
6231 if(mpz_tstbit(*bitstream, index - 1) ^ last) count += 1;
6232
6233 /* restore *bitstream to its original value && free temp (iff necessary) */
6234 if(short_) {
6235 mpz_sub(*bitstream, *bitstream, temp);
6236 mpz_clear(temp);
6237 }
6238
6239 ST(0) = sv_2mortal(newSViv(count));
6240
6241 diff = 20000.0 - (double)offset;
6242 x = (2 * ((double)count - (diff / 2))) / (sqrt(diff));
6243
6244 ST(1) = sv_2mortal(newSVnv(x));
6245 XSRETURN(2);
6246 }
6247
autocorrelation_20000(pTHX_ mpz_t * bitstream,int offset)6248 int autocorrelation_20000(pTHX_ mpz_t * bitstream, int offset) {
6249 dXSARGS;
6250 int i, last, count = 0, short_ = 0;
6251 mpz_t temp;
6252 double x, diff;
6253 int len = mpz_sizeinbase(*bitstream, 2);
6254
6255 if(len > 20000 + offset) croak("Wrong size random sequence for autocorrelation_20000 test");
6256 if(len < 19967 + offset) {
6257 warn("More than 33 leading zeroes in autocorrelation_20000 test\n");
6258 return 0;
6259 }
6260
6261 /* make sure *bitstream has a length of 20000 + offset bits. */
6262 if(20000 + offset - len) {
6263 short_ = 1;
6264 mpz_init_set_ui(temp, 1);
6265 mpz_mul_2exp(temp, temp, 19999 + offset);
6266 mpz_add(*bitstream, *bitstream, temp);
6267 }
6268 if(mpz_sizeinbase(*bitstream, 2) != 20000 + offset) croak("Bit sequence has length of %d bits in autocorrelation_20000 function; should have size of %d bits", (int)mpz_sizeinbase(*bitstream, 2), 20000 + offset);
6269
6270 for(i = 0; i < 19999; ++i) {
6271 if(mpz_tstbit(*bitstream, i) ^ mpz_tstbit(*bitstream, i + offset)) count += 1;
6272 }
6273
6274 last = short_ ? 0 : 1;
6275
6276 if(mpz_tstbit(*bitstream, 19999) ^ last) count += 1;
6277
6278 /* restore *bitstream to its original value && free temp (iff necessary) */
6279 if(short_) {
6280 mpz_sub(*bitstream, *bitstream, temp);
6281 mpz_clear(temp);
6282 }
6283 if(count > 9654 && count < 10346) return 1;
6284 return 0;
6285 }
6286
_GMP_LIMB_BITS(pTHX)6287 SV * _GMP_LIMB_BITS(pTHX) {
6288 #ifdef GMP_LIMB_BITS
6289 return newSVuv(GMP_LIMB_BITS);
6290 #else
6291 return &PL_sv_undef;
6292 #endif
6293 }
6294
_GMP_NAIL_BITS(pTHX)6295 SV * _GMP_NAIL_BITS(pTHX) {
6296 #ifdef GMP_NAIL_BITS
6297 return newSVuv(GMP_NAIL_BITS);
6298 #else
6299 return &PL_sv_undef;
6300 #endif
6301 }
6302
_new_from_MBI(pTHX_ SV * b)6303 SV * _new_from_MBI(pTHX_ SV * b) {
6304 mpz_t * mpz_t_obj;
6305 SV * obj_ref, * obj;
6306 MBI_DECLARATIONS
6307 MBI_GMP_DECLARATIONS
6308
6309 /*
6310 This function gets called only if it has already been ascertained that b is
6311 an object && HvNAME(SvSTASH(SvRV(b))) is "Math::BigInt", but we still need to
6312 check that the object is not NaN or Inf.
6313 */
6314 VALIDATE_MBI_OBJECT
6315 croak("Invalid Math::BigInt object supplied to Math::GMPz::_new_from_MBI");
6316
6317 New(1, mpz_t_obj, 1, mpz_t);
6318 if(mpz_t_obj == NULL) croak("Failed to allocate memory in Math::GMPz::_new_from_MBI function");
6319 obj_ref = newSV(0);
6320 obj = newSVrv(obj_ref, "Math::GMPz");
6321 mpz_init(*mpz_t_obj);
6322 sv_setiv(obj, INT2PTR(IV, mpz_t_obj));
6323 SvREADONLY_on(obj);
6324
6325 MBI_GMP_INSERT
6326
6327 if(mpz) {
6328 mpz_set(*mpz_t_obj, (mpz_srcptr)mpz);
6329 if(strEQ("-", sign)) mpz_neg(*mpz_t_obj, *mpz_t_obj);
6330 return obj_ref;
6331 }
6332
6333 mpz_set_str(*mpz_t_obj, SvPV_nolen(b), 0);
6334 return obj_ref;
6335 }
6336
6337
_magic_status(pTHX)6338 SV * _magic_status(pTHX) {
6339 #ifdef MATH_GMPz_HAS_MAGICEXT
6340 return newSVuv(MATH_GMPz_HAS_MAGICEXT);
6341 #endif
6342 return &PL_sv_undef;
6343 }
6344
_dump_mbi_gmp(pTHX_ SV * b)6345 void _dump_mbi_gmp(pTHX_ SV * b) {
6346
6347 MBI_DECLARATIONS
6348 MBI_GMP_DECLARATIONS
6349
6350 VALIDATE_MBI_OBJECT
6351 croak("Invalid Math::BigInt object supplied to Math::GMPz::_new_from_MBI");
6352
6353 MBI_GMP_INSERT
6354
6355 if(mpz) {
6356 mpz_out_str(NULL, 10, (mpz_srcptr)mpz);
6357 printf(" %s\n", sign);
6358 }
6359
6360 else printf("Unable to obtain information. (Perhaps NA ?)\n");
6361 }
6362
_SvIOK(pTHX_ SV * sv)6363 int _SvIOK(pTHX_ SV * sv) {
6364 if(SV_IS_IOK(sv)) return 1;
6365 return 0;
6366 }
6367
_SvPOK(SV * sv)6368 int _SvPOK(SV * sv) {
6369 if(SV_IS_POK(sv)) return 1;
6370 return 0;
6371 }
6372
_SvNOK(SV * sv)6373 int _SvNOK(SV * sv) {
6374 if(SV_IS_NOK(sv)) return 1;
6375 return 0;
6376 }
6377
IOK_flag(SV * sv)6378 int IOK_flag(SV * sv) {
6379 if(SvUOK(sv)) return 2;
6380 if(SvIOK(sv)) return 1;
6381 return 0;
6382 }
6383
POK_flag(SV * sv)6384 int POK_flag(SV * sv) {
6385 if(SvPOK(sv)) return 1;
6386 return 0;
6387 }
6388
NOK_flag(SV * sv)6389 int NOK_flag(SV * sv) {
6390 if(SvNOK(sv)) return 1;
6391 return 0;
6392 }
6393
_sizeof_mp_bitcnt_t(pTHX)6394 SV * _sizeof_mp_bitcnt_t(pTHX) {
6395 return newSVuv(sizeof(mp_bitcnt_t));
6396 }
6397
_gmp_index_overflow(void)6398 int _gmp_index_overflow(void) {
6399 #if defined(_GMP_INDEX_OVERFLOW)
6400 return 1;
6401 #else
6402 return 0;
6403 #endif
6404 }
6405
6406
6407 MODULE = Math::GMPz PACKAGE = Math::GMPz
6408
6409 PROTOTYPES: ENABLE
6410
6411
6412 SV *
6413 MATH_GMPz_IV_MAX ()
6414 CODE:
6415 RETVAL = MATH_GMPz_IV_MAX (aTHX);
6416 OUTPUT: RETVAL
6417
6418
6419 SV *
6420 MATH_GMPz_IV_MIN ()
6421 CODE:
6422 RETVAL = MATH_GMPz_IV_MIN (aTHX);
6423 OUTPUT: RETVAL
6424
6425
6426 SV *
6427 MATH_GMPz_UV_MAX ()
6428 CODE:
6429 RETVAL = MATH_GMPz_UV_MAX (aTHX);
6430 OUTPUT: RETVAL
6431
6432 PROTOTYPES: DISABLE
6433
6434 int
6435 _is_infstring (s)
6436 char * s
6437
6438 SV *
6439 Rmpz_init_set_str_nobless (num, base)
6440 SV * num
6441 SV * base
6442 CODE:
6443 RETVAL = Rmpz_init_set_str_nobless (aTHX_ num, base);
6444 OUTPUT: RETVAL
6445
6446 SV *
6447 Rmpz_init2_nobless (bits)
6448 SV * bits
6449 CODE:
6450 RETVAL = Rmpz_init2_nobless (aTHX_ bits);
6451 OUTPUT: RETVAL
6452
6453 SV *
6454 Rmpz_init_nobless ()
6455 CODE:
6456 RETVAL = Rmpz_init_nobless (aTHX);
6457 OUTPUT: RETVAL
6458
6459
6460 SV *
6461 Rmpz_init_set_nobless (p)
6462 mpz_t * p
6463 CODE:
6464 RETVAL = Rmpz_init_set_nobless (aTHX_ p);
6465 OUTPUT: RETVAL
6466
6467 SV *
6468 Rmpz_init_set_ui_nobless (p)
6469 SV * p
6470 CODE:
6471 RETVAL = Rmpz_init_set_ui_nobless (aTHX_ p);
6472 OUTPUT: RETVAL
6473
6474 SV *
6475 Rmpz_init_set_si_nobless (p)
6476 SV * p
6477 CODE:
6478 RETVAL = Rmpz_init_set_si_nobless (aTHX_ p);
6479 OUTPUT: RETVAL
6480
6481 SV *
6482 Rmpz_init_set_d_nobless (p)
6483 SV * p
6484 CODE:
6485 RETVAL = Rmpz_init_set_d_nobless (aTHX_ p);
6486 OUTPUT: RETVAL
6487
6488 SV *
6489 Rmpz_init ()
6490 CODE:
6491 RETVAL = Rmpz_init (aTHX);
6492 OUTPUT: RETVAL
6493
6494
6495 SV *
6496 Rmpz_init_set (p)
6497 mpz_t * p
6498 CODE:
6499 RETVAL = Rmpz_init_set (aTHX_ p);
6500 OUTPUT: RETVAL
6501
6502 SV *
6503 Rmpz_init_set_ui (p)
6504 SV * p
6505 CODE:
6506 RETVAL = Rmpz_init_set_ui (aTHX_ p);
6507 OUTPUT: RETVAL
6508
6509 SV *
6510 Rmpz_init_set_si (p)
6511 SV * p
6512 CODE:
6513 RETVAL = Rmpz_init_set_si (aTHX_ p);
6514 OUTPUT: RETVAL
6515
6516 void
6517 Rmpz_set_uj (copy, original)
6518 mpz_t * copy
6519 UV original
6520 PREINIT:
6521 I32* temp;
6522 PPCODE:
6523 temp = PL_markstack_ptr++;
6524 Rmpz_set_uj(copy, original);
6525 if (PL_markstack_ptr != temp) {
6526 /* truly void, because dXSARGS not invoked */
6527 PL_markstack_ptr = temp;
6528 XSRETURN_EMPTY; /* return empty stack */
6529 }
6530 /* must have used dXSARGS; list context implied */
6531 return; /* assume stack size is correct */
6532
6533 void
6534 Rmpz_set_sj (copy, original)
6535 mpz_t * copy
6536 IV original
6537 PREINIT:
6538 I32* temp;
6539 PPCODE:
6540 temp = PL_markstack_ptr++;
6541 Rmpz_set_sj(copy, original);
6542 if (PL_markstack_ptr != temp) {
6543 /* truly void, because dXSARGS not invoked */
6544 PL_markstack_ptr = temp;
6545 XSRETURN_EMPTY; /* return empty stack */
6546 }
6547 /* must have used dXSARGS; list context implied */
6548 return; /* assume stack size is correct */
6549
6550 void
6551 Rmpz_set_IV (copy, original)
6552 mpz_t * copy
6553 SV * original
6554 PREINIT:
6555 I32* temp;
6556 PPCODE:
6557 temp = PL_markstack_ptr++;
6558 Rmpz_set_IV(aTHX_ copy, original);
6559 if (PL_markstack_ptr != temp) {
6560 /* truly void, because dXSARGS not invoked */
6561 PL_markstack_ptr = temp;
6562 XSRETURN_EMPTY; /* return empty stack */
6563 }
6564 /* must have used dXSARGS; list context implied */
6565 return; /* assume stack size is correct */
6566
6567 SV *
6568 Rmpz_init_set_IV (p)
6569 SV * p
6570 CODE:
6571 RETVAL = Rmpz_init_set_IV (aTHX_ p);
6572 OUTPUT: RETVAL
6573
6574 SV *
6575 Rmpz_init_set_IV_nobless (p)
6576 SV * p
6577 CODE:
6578 RETVAL = Rmpz_init_set_IV_nobless (aTHX_ p);
6579 OUTPUT: RETVAL
6580
6581 SV *
6582 _Rmpz_get_IV (n)
6583 mpz_t * n
6584 CODE:
6585 RETVAL = _Rmpz_get_IV (aTHX_ n);
6586 OUTPUT: RETVAL
6587
6588 int
6589 Rmpz_fits_IV_p (n)
6590 mpz_t * n
6591 CODE:
6592 RETVAL = Rmpz_fits_IV_p (aTHX_ n);
6593 OUTPUT: RETVAL
6594
6595 double
6596 Rmpz_get_d (n)
6597 mpz_t * n
6598
6599 NV
6600 Rmpz_get_NV (n)
6601 mpz_t * n
6602
6603 int
6604 Rmpz_cmp_IV (z, iv)
6605 mpz_t * z
6606 SV * iv
6607 CODE:
6608 RETVAL = Rmpz_cmp_IV (aTHX_ z, iv);
6609 OUTPUT: RETVAL
6610
6611 SV *
6612 Rmpz_init_set_d (p)
6613 SV * p
6614 CODE:
6615 RETVAL = Rmpz_init_set_d (aTHX_ p);
6616 OUTPUT: RETVAL
6617
6618 void
6619 _mpf_set_dd (q, p)
6620 mpf_t * q
6621 SV * p
6622 PREINIT:
6623 I32* temp;
6624 PPCODE:
6625 temp = PL_markstack_ptr++;
6626 _mpf_set_dd(q, p);
6627 if (PL_markstack_ptr != temp) {
6628 /* truly void, because dXSARGS not invoked */
6629 PL_markstack_ptr = temp;
6630 XSRETURN_EMPTY; /* return empty stack */
6631 }
6632 /* must have used dXSARGS; list context implied */
6633 return; /* assume stack size is correct */
6634
6635 void
6636 Rmpz_set_NV (copy, original)
6637 mpz_t * copy
6638 SV * original
6639 PREINIT:
6640 I32* temp;
6641 PPCODE:
6642 temp = PL_markstack_ptr++;
6643 Rmpz_set_NV(aTHX_ copy, original);
6644 if (PL_markstack_ptr != temp) {
6645 /* truly void, because dXSARGS not invoked */
6646 PL_markstack_ptr = temp;
6647 XSRETURN_EMPTY; /* return empty stack */
6648 }
6649 /* must have used dXSARGS; list context implied */
6650 return; /* assume stack size is correct */
6651
6652 SV *
6653 Rmpz_init_set_NV (p)
6654 SV * p
6655 CODE:
6656 RETVAL = Rmpz_init_set_NV (aTHX_ p);
6657 OUTPUT: RETVAL
6658
6659 SV *
6660 Rmpz_init_set_NV_nobless (p)
6661 SV * p
6662 CODE:
6663 RETVAL = Rmpz_init_set_NV_nobless (aTHX_ p);
6664 OUTPUT: RETVAL
6665
6666 SV *
6667 Rmpz_init_set_str (num, base)
6668 SV * num
6669 SV * base
6670 CODE:
6671 RETVAL = Rmpz_init_set_str (aTHX_ num, base);
6672 OUTPUT: RETVAL
6673
6674 SV *
6675 Rmpz_init2 (bits)
6676 SV * bits
6677 CODE:
6678 RETVAL = Rmpz_init2 (aTHX_ bits);
6679 OUTPUT: RETVAL
6680
6681 SV *
6682 Rmpz_get_str (p, base)
6683 mpz_t * p
6684 SV * base
6685 CODE:
6686 RETVAL = Rmpz_get_str (aTHX_ p, base);
6687 OUTPUT: RETVAL
6688
6689 void
6690 DESTROY (p)
6691 mpz_t * p
6692 PREINIT:
6693 I32* temp;
6694 PPCODE:
6695 temp = PL_markstack_ptr++;
6696 DESTROY(aTHX_ p);
6697 if (PL_markstack_ptr != temp) {
6698 /* truly void, because dXSARGS not invoked */
6699 PL_markstack_ptr = temp;
6700 XSRETURN_EMPTY; /* return empty stack */
6701 }
6702 /* must have used dXSARGS; list context implied */
6703 return; /* assume stack size is correct */
6704
6705 void
6706 Rmpz_clear (p)
6707 mpz_t * p
6708 PREINIT:
6709 I32* temp;
6710 PPCODE:
6711 temp = PL_markstack_ptr++;
6712 Rmpz_clear(aTHX_ p);
6713 if (PL_markstack_ptr != temp) {
6714 /* truly void, because dXSARGS not invoked */
6715 PL_markstack_ptr = temp;
6716 XSRETURN_EMPTY; /* return empty stack */
6717 }
6718 /* must have used dXSARGS; list context implied */
6719 return; /* assume stack size is correct */
6720
6721 void
6722 Rmpz_clear_mpz (p)
6723 mpz_t * p
6724 PREINIT:
6725 I32* temp;
6726 PPCODE:
6727 temp = PL_markstack_ptr++;
6728 Rmpz_clear_mpz(p);
6729 if (PL_markstack_ptr != temp) {
6730 /* truly void, because dXSARGS not invoked */
6731 PL_markstack_ptr = temp;
6732 XSRETURN_EMPTY; /* return empty stack */
6733 }
6734 /* must have used dXSARGS; list context implied */
6735 return; /* assume stack size is correct */
6736
6737 void
6738 Rmpz_clear_ptr (p)
6739 mpz_t * p
6740 PREINIT:
6741 I32* temp;
6742 PPCODE:
6743 temp = PL_markstack_ptr++;
6744 Rmpz_clear_ptr(aTHX_ p);
6745 if (PL_markstack_ptr != temp) {
6746 /* truly void, because dXSARGS not invoked */
6747 PL_markstack_ptr = temp;
6748 XSRETURN_EMPTY; /* return empty stack */
6749 }
6750 /* must have used dXSARGS; list context implied */
6751 return; /* assume stack size is correct */
6752
6753 void
6754 Rmpz_realloc2 (integer, bits)
6755 mpz_t * integer
6756 SV * bits
6757 PREINIT:
6758 I32* temp;
6759 PPCODE:
6760 temp = PL_markstack_ptr++;
6761 Rmpz_realloc2(aTHX_ integer, bits);
6762 if (PL_markstack_ptr != temp) {
6763 /* truly void, because dXSARGS not invoked */
6764 PL_markstack_ptr = temp;
6765 XSRETURN_EMPTY; /* return empty stack */
6766 }
6767 /* must have used dXSARGS; list context implied */
6768 return; /* assume stack size is correct */
6769
6770 void
6771 Rmpz_set (copy, original)
6772 mpz_t * copy
6773 mpz_t * original
6774 PREINIT:
6775 I32* temp;
6776 PPCODE:
6777 temp = PL_markstack_ptr++;
6778 Rmpz_set(copy, original);
6779 if (PL_markstack_ptr != temp) {
6780 /* truly void, because dXSARGS not invoked */
6781 PL_markstack_ptr = temp;
6782 XSRETURN_EMPTY; /* return empty stack */
6783 }
6784 /* must have used dXSARGS; list context implied */
6785 return; /* assume stack size is correct */
6786
6787 void
6788 Rmpz_set_q (copy, original)
6789 mpz_t * copy
6790 mpq_t * original
6791 PREINIT:
6792 I32* temp;
6793 PPCODE:
6794 temp = PL_markstack_ptr++;
6795 Rmpz_set_q(copy, original);
6796 if (PL_markstack_ptr != temp) {
6797 /* truly void, because dXSARGS not invoked */
6798 PL_markstack_ptr = temp;
6799 XSRETURN_EMPTY; /* return empty stack */
6800 }
6801 /* must have used dXSARGS; list context implied */
6802 return; /* assume stack size is correct */
6803
6804 void
6805 Rmpz_set_f (copy, original)
6806 mpz_t * copy
6807 mpf_t * original
6808 PREINIT:
6809 I32* temp;
6810 PPCODE:
6811 temp = PL_markstack_ptr++;
6812 Rmpz_set_f(copy, original);
6813 if (PL_markstack_ptr != temp) {
6814 /* truly void, because dXSARGS not invoked */
6815 PL_markstack_ptr = temp;
6816 XSRETURN_EMPTY; /* return empty stack */
6817 }
6818 /* must have used dXSARGS; list context implied */
6819 return; /* assume stack size is correct */
6820
6821 void
6822 Rmpz_set_si (copy, original)
6823 mpz_t * copy
6824 long original
6825 PREINIT:
6826 I32* temp;
6827 PPCODE:
6828 temp = PL_markstack_ptr++;
6829 Rmpz_set_si(copy, original);
6830 if (PL_markstack_ptr != temp) {
6831 /* truly void, because dXSARGS not invoked */
6832 PL_markstack_ptr = temp;
6833 XSRETURN_EMPTY; /* return empty stack */
6834 }
6835 /* must have used dXSARGS; list context implied */
6836 return; /* assume stack size is correct */
6837
6838 void
6839 Rmpz_set_ui (copy, original)
6840 mpz_t * copy
6841 unsigned long original
6842 PREINIT:
6843 I32* temp;
6844 PPCODE:
6845 temp = PL_markstack_ptr++;
6846 Rmpz_set_ui(copy, original);
6847 if (PL_markstack_ptr != temp) {
6848 /* truly void, because dXSARGS not invoked */
6849 PL_markstack_ptr = temp;
6850 XSRETURN_EMPTY; /* return empty stack */
6851 }
6852 /* must have used dXSARGS; list context implied */
6853 return; /* assume stack size is correct */
6854
6855 void
6856 Rmpz_set_d (copy, d)
6857 mpz_t * copy
6858 double d
6859 PREINIT:
6860 I32* temp;
6861 PPCODE:
6862 temp = PL_markstack_ptr++;
6863 Rmpz_set_d(copy, d);
6864 if (PL_markstack_ptr != temp) {
6865 /* truly void, because dXSARGS not invoked */
6866 PL_markstack_ptr = temp;
6867 XSRETURN_EMPTY; /* return empty stack */
6868 }
6869 /* must have used dXSARGS; list context implied */
6870 return; /* assume stack size is correct */
6871
6872 void
Rmpz_set_str(copy,original,base)6873 Rmpz_set_str (copy, original, base)
6874 mpz_t * copy
6875 SV * original
6876 int base
6877 PREINIT:
6878 I32* temp;
6879 PPCODE:
6880 temp = PL_markstack_ptr++;
6881 Rmpz_set_str(aTHX_ copy, original, base);
6882 if (PL_markstack_ptr != temp) {
6883 /* truly void, because dXSARGS not invoked */
6884 PL_markstack_ptr = temp;
6885 XSRETURN_EMPTY; /* return empty stack */
6886 }
6887 /* must have used dXSARGS; list context implied */
6888 return; /* assume stack size is correct */
6889
6890 void
6891 Rmpz_swap (a, b)
6892 mpz_t * a
6893 mpz_t * b
6894 PREINIT:
6895 I32* temp;
6896 PPCODE:
6897 temp = PL_markstack_ptr++;
6898 Rmpz_swap(a, b);
6899 if (PL_markstack_ptr != temp) {
6900 /* truly void, because dXSARGS not invoked */
6901 PL_markstack_ptr = temp;
6902 XSRETURN_EMPTY; /* return empty stack */
6903 }
6904 /* must have used dXSARGS; list context implied */
6905 return; /* assume stack size is correct */
6906
6907 unsigned long
6908 Rmpz_get_ui (n)
6909 mpz_t * n
6910
6911 long
6912 Rmpz_get_si (n)
6913 mpz_t * n
6914
6915 void
6916 Rmpz_get_d_2exp (n)
6917 mpz_t * n
6918 PREINIT:
6919 I32* temp;
6920 PPCODE:
6921 temp = PL_markstack_ptr++;
6922 Rmpz_get_d_2exp(aTHX_ n);
6923 if (PL_markstack_ptr != temp) {
6924 /* truly void, because dXSARGS not invoked */
6925 PL_markstack_ptr = temp;
6926 XSRETURN_EMPTY; /* return empty stack */
6927 }
6928 /* must have used dXSARGS; list context implied */
6929 return; /* assume stack size is correct */
6930
6931 SV *
6932 Rmpz_getlimbn (p, n)
6933 mpz_t * p
6934 SV * n
6935 CODE:
6936 RETVAL = Rmpz_getlimbn (aTHX_ p, n);
6937 OUTPUT: RETVAL
6938
6939 void
Rmpz_add(dest,src1,src2)6940 Rmpz_add (dest, src1, src2)
6941 mpz_t * dest
6942 mpz_t * src1
6943 mpz_t * src2
6944 PREINIT:
6945 I32* temp;
6946 PPCODE:
6947 temp = PL_markstack_ptr++;
6948 Rmpz_add(dest, src1, src2);
6949 if (PL_markstack_ptr != temp) {
6950 /* truly void, because dXSARGS not invoked */
6951 PL_markstack_ptr = temp;
6952 XSRETURN_EMPTY; /* return empty stack */
6953 }
6954 /* must have used dXSARGS; list context implied */
6955 return; /* assume stack size is correct */
6956
6957 void
Rmpz_add_ui(dest,src,num)6958 Rmpz_add_ui (dest, src, num)
6959 mpz_t * dest
6960 mpz_t * src
6961 unsigned long num
6962 PREINIT:
6963 I32* temp;
6964 PPCODE:
6965 temp = PL_markstack_ptr++;
6966 Rmpz_add_ui(dest, src, num);
6967 if (PL_markstack_ptr != temp) {
6968 /* truly void, because dXSARGS not invoked */
6969 PL_markstack_ptr = temp;
6970 XSRETURN_EMPTY; /* return empty stack */
6971 }
6972 /* must have used dXSARGS; list context implied */
6973 return; /* assume stack size is correct */
6974
6975 void
Rmpz_sub(dest,src1,src2)6976 Rmpz_sub (dest, src1, src2)
6977 mpz_t * dest
6978 mpz_t * src1
6979 mpz_t * src2
6980 PREINIT:
6981 I32* temp;
6982 PPCODE:
6983 temp = PL_markstack_ptr++;
6984 Rmpz_sub(dest, src1, src2);
6985 if (PL_markstack_ptr != temp) {
6986 /* truly void, because dXSARGS not invoked */
6987 PL_markstack_ptr = temp;
6988 XSRETURN_EMPTY; /* return empty stack */
6989 }
6990 /* must have used dXSARGS; list context implied */
6991 return; /* assume stack size is correct */
6992
6993 void
Rmpz_sub_ui(dest,src,num)6994 Rmpz_sub_ui (dest, src, num)
6995 mpz_t * dest
6996 mpz_t * src
6997 unsigned long num
6998 PREINIT:
6999 I32* temp;
7000 PPCODE:
7001 temp = PL_markstack_ptr++;
7002 Rmpz_sub_ui(dest, src, num);
7003 if (PL_markstack_ptr != temp) {
7004 /* truly void, because dXSARGS not invoked */
7005 PL_markstack_ptr = temp;
7006 XSRETURN_EMPTY; /* return empty stack */
7007 }
7008 /* must have used dXSARGS; list context implied */
7009 return; /* assume stack size is correct */
7010
7011 void
Rmpz_ui_sub(dest,num,src)7012 Rmpz_ui_sub (dest, num, src)
7013 mpz_t * dest
7014 unsigned long num
7015 mpz_t * src
7016 PREINIT:
7017 I32* temp;
7018 PPCODE:
7019 temp = PL_markstack_ptr++;
7020 Rmpz_ui_sub(dest, num, src);
7021 if (PL_markstack_ptr != temp) {
7022 /* truly void, because dXSARGS not invoked */
7023 PL_markstack_ptr = temp;
7024 XSRETURN_EMPTY; /* return empty stack */
7025 }
7026 /* must have used dXSARGS; list context implied */
7027 return; /* assume stack size is correct */
7028
7029 void
Rmpz_mul(dest,src1,src2)7030 Rmpz_mul (dest, src1, src2)
7031 mpz_t * dest
7032 mpz_t * src1
7033 mpz_t * src2
7034 PREINIT:
7035 I32* temp;
7036 PPCODE:
7037 temp = PL_markstack_ptr++;
7038 Rmpz_mul(dest, src1, src2);
7039 if (PL_markstack_ptr != temp) {
7040 /* truly void, because dXSARGS not invoked */
7041 PL_markstack_ptr = temp;
7042 XSRETURN_EMPTY; /* return empty stack */
7043 }
7044 /* must have used dXSARGS; list context implied */
7045 return; /* assume stack size is correct */
7046
7047 void
Rmpz_mul_si(dest,src,num)7048 Rmpz_mul_si (dest, src, num)
7049 mpz_t * dest
7050 mpz_t * src
7051 long num
7052 PREINIT:
7053 I32* temp;
7054 PPCODE:
7055 temp = PL_markstack_ptr++;
7056 Rmpz_mul_si(dest, src, num);
7057 if (PL_markstack_ptr != temp) {
7058 /* truly void, because dXSARGS not invoked */
7059 PL_markstack_ptr = temp;
7060 XSRETURN_EMPTY; /* return empty stack */
7061 }
7062 /* must have used dXSARGS; list context implied */
7063 return; /* assume stack size is correct */
7064
7065 void
Rmpz_mul_ui(dest,src,num)7066 Rmpz_mul_ui (dest, src, num)
7067 mpz_t * dest
7068 mpz_t * src
7069 unsigned long num
7070 PREINIT:
7071 I32* temp;
7072 PPCODE:
7073 temp = PL_markstack_ptr++;
7074 Rmpz_mul_ui(dest, src, num);
7075 if (PL_markstack_ptr != temp) {
7076 /* truly void, because dXSARGS not invoked */
7077 PL_markstack_ptr = temp;
7078 XSRETURN_EMPTY; /* return empty stack */
7079 }
7080 /* must have used dXSARGS; list context implied */
7081 return; /* assume stack size is correct */
7082
7083 void
Rmpz_addmul(dest,src1,src2)7084 Rmpz_addmul (dest, src1, src2)
7085 mpz_t * dest
7086 mpz_t * src1
7087 mpz_t * src2
7088 PREINIT:
7089 I32* temp;
7090 PPCODE:
7091 temp = PL_markstack_ptr++;
7092 Rmpz_addmul(dest, src1, src2);
7093 if (PL_markstack_ptr != temp) {
7094 /* truly void, because dXSARGS not invoked */
7095 PL_markstack_ptr = temp;
7096 XSRETURN_EMPTY; /* return empty stack */
7097 }
7098 /* must have used dXSARGS; list context implied */
7099 return; /* assume stack size is correct */
7100
7101 void
Rmpz_addmul_ui(dest,src,num)7102 Rmpz_addmul_ui (dest, src, num)
7103 mpz_t * dest
7104 mpz_t * src
7105 unsigned long num
7106 PREINIT:
7107 I32* temp;
7108 PPCODE:
7109 temp = PL_markstack_ptr++;
7110 Rmpz_addmul_ui(dest, src, num);
7111 if (PL_markstack_ptr != temp) {
7112 /* truly void, because dXSARGS not invoked */
7113 PL_markstack_ptr = temp;
7114 XSRETURN_EMPTY; /* return empty stack */
7115 }
7116 /* must have used dXSARGS; list context implied */
7117 return; /* assume stack size is correct */
7118
7119 void
Rmpz_submul(dest,src1,src2)7120 Rmpz_submul (dest, src1, src2)
7121 mpz_t * dest
7122 mpz_t * src1
7123 mpz_t * src2
7124 PREINIT:
7125 I32* temp;
7126 PPCODE:
7127 temp = PL_markstack_ptr++;
7128 Rmpz_submul(dest, src1, src2);
7129 if (PL_markstack_ptr != temp) {
7130 /* truly void, because dXSARGS not invoked */
7131 PL_markstack_ptr = temp;
7132 XSRETURN_EMPTY; /* return empty stack */
7133 }
7134 /* must have used dXSARGS; list context implied */
7135 return; /* assume stack size is correct */
7136
7137 void
Rmpz_submul_ui(dest,src,num)7138 Rmpz_submul_ui (dest, src, num)
7139 mpz_t * dest
7140 mpz_t * src
7141 unsigned long num
7142 PREINIT:
7143 I32* temp;
7144 PPCODE:
7145 temp = PL_markstack_ptr++;
7146 Rmpz_submul_ui(dest, src, num);
7147 if (PL_markstack_ptr != temp) {
7148 /* truly void, because dXSARGS not invoked */
7149 PL_markstack_ptr = temp;
7150 XSRETURN_EMPTY; /* return empty stack */
7151 }
7152 /* must have used dXSARGS; list context implied */
7153 return; /* assume stack size is correct */
7154
7155 void
Rmpz_mul_2exp(dest,src1,b)7156 Rmpz_mul_2exp (dest, src1, b)
7157 mpz_t * dest
7158 mpz_t * src1
7159 SV * b
7160 PREINIT:
7161 I32* temp;
7162 PPCODE:
7163 temp = PL_markstack_ptr++;
7164 Rmpz_mul_2exp(aTHX_ dest, src1, b);
7165 if (PL_markstack_ptr != temp) {
7166 /* truly void, because dXSARGS not invoked */
7167 PL_markstack_ptr = temp;
7168 XSRETURN_EMPTY; /* return empty stack */
7169 }
7170 /* must have used dXSARGS; list context implied */
7171 return; /* assume stack size is correct */
7172
7173 void
Rmpz_div_2exp(dest,src1,b)7174 Rmpz_div_2exp (dest, src1, b)
7175 mpz_t * dest
7176 mpz_t * src1
7177 SV * b
7178 PREINIT:
7179 I32* temp;
7180 PPCODE:
7181 temp = PL_markstack_ptr++;
7182 Rmpz_div_2exp(aTHX_ dest, src1, b);
7183 if (PL_markstack_ptr != temp) {
7184 /* truly void, because dXSARGS not invoked */
7185 PL_markstack_ptr = temp;
7186 XSRETURN_EMPTY; /* return empty stack */
7187 }
7188 /* must have used dXSARGS; list context implied */
7189 return; /* assume stack size is correct */
7190
7191 void
7192 Rmpz_neg (dest, src)
7193 mpz_t * dest
7194 mpz_t * src
7195 PREINIT:
7196 I32* temp;
7197 PPCODE:
7198 temp = PL_markstack_ptr++;
7199 Rmpz_neg(dest, src);
7200 if (PL_markstack_ptr != temp) {
7201 /* truly void, because dXSARGS not invoked */
7202 PL_markstack_ptr = temp;
7203 XSRETURN_EMPTY; /* return empty stack */
7204 }
7205 /* must have used dXSARGS; list context implied */
7206 return; /* assume stack size is correct */
7207
7208 void
7209 Rmpz_abs (dest, src)
7210 mpz_t * dest
7211 mpz_t * src
7212 PREINIT:
7213 I32* temp;
7214 PPCODE:
7215 temp = PL_markstack_ptr++;
7216 Rmpz_abs(dest, src);
7217 if (PL_markstack_ptr != temp) {
7218 /* truly void, because dXSARGS not invoked */
7219 PL_markstack_ptr = temp;
7220 XSRETURN_EMPTY; /* return empty stack */
7221 }
7222 /* must have used dXSARGS; list context implied */
7223 return; /* assume stack size is correct */
7224
7225 void
Rmpz_cdiv_q(q,n,d)7226 Rmpz_cdiv_q (q, n, d)
7227 mpz_t * q
7228 mpz_t * n
7229 mpz_t * d
7230 PREINIT:
7231 I32* temp;
7232 PPCODE:
7233 temp = PL_markstack_ptr++;
7234 Rmpz_cdiv_q(q, n, d);
7235 if (PL_markstack_ptr != temp) {
7236 /* truly void, because dXSARGS not invoked */
7237 PL_markstack_ptr = temp;
7238 XSRETURN_EMPTY; /* return empty stack */
7239 }
7240 /* must have used dXSARGS; list context implied */
7241 return; /* assume stack size is correct */
7242
7243 void
Rmpz_cdiv_r(mod,n,d)7244 Rmpz_cdiv_r (mod, n, d)
7245 mpz_t * mod
7246 mpz_t * n
7247 mpz_t * d
7248 PREINIT:
7249 I32* temp;
7250 PPCODE:
7251 temp = PL_markstack_ptr++;
7252 Rmpz_cdiv_r(mod, n, d);
7253 if (PL_markstack_ptr != temp) {
7254 /* truly void, because dXSARGS not invoked */
7255 PL_markstack_ptr = temp;
7256 XSRETURN_EMPTY; /* return empty stack */
7257 }
7258 /* must have used dXSARGS; list context implied */
7259 return; /* assume stack size is correct */
7260
7261 void
Rmpz_cdiv_qr(q,r,n,d)7262 Rmpz_cdiv_qr (q, r, n, d)
7263 mpz_t * q
7264 mpz_t * r
7265 mpz_t * n
7266 mpz_t * d
7267 PREINIT:
7268 I32* temp;
7269 PPCODE:
7270 temp = PL_markstack_ptr++;
7271 Rmpz_cdiv_qr(q, r, n, d);
7272 if (PL_markstack_ptr != temp) {
7273 /* truly void, because dXSARGS not invoked */
7274 PL_markstack_ptr = temp;
7275 XSRETURN_EMPTY; /* return empty stack */
7276 }
7277 /* must have used dXSARGS; list context implied */
7278 return; /* assume stack size is correct */
7279
7280 unsigned long
7281 Rmpz_cdiv_q_ui (q, n, d)
7282 mpz_t * q
7283 mpz_t * n
7284 unsigned long d
7285
7286 unsigned long
7287 Rmpz_cdiv_r_ui (q, n, d)
7288 mpz_t * q
7289 mpz_t * n
7290 unsigned long d
7291
7292 unsigned long
7293 Rmpz_cdiv_qr_ui (q, r, n, d)
7294 mpz_t * q
7295 mpz_t * r
7296 mpz_t * n
7297 unsigned long d
7298
7299 unsigned long
7300 Rmpz_cdiv_ui (n, d)
7301 mpz_t * n
7302 unsigned long d
7303
7304 void
7305 Rmpz_cdiv_q_2exp (q, n, b)
7306 mpz_t * q
7307 mpz_t * n
7308 SV * b
7309 PREINIT:
7310 I32* temp;
7311 PPCODE:
7312 temp = PL_markstack_ptr++;
7313 Rmpz_cdiv_q_2exp(aTHX_ q, n, b);
7314 if (PL_markstack_ptr != temp) {
7315 /* truly void, because dXSARGS not invoked */
7316 PL_markstack_ptr = temp;
7317 XSRETURN_EMPTY; /* return empty stack */
7318 }
7319 /* must have used dXSARGS; list context implied */
7320 return; /* assume stack size is correct */
7321
7322 void
Rmpz_cdiv_r_2exp(r,n,b)7323 Rmpz_cdiv_r_2exp (r, n, b)
7324 mpz_t * r
7325 mpz_t * n
7326 SV * b
7327 PREINIT:
7328 I32* temp;
7329 PPCODE:
7330 temp = PL_markstack_ptr++;
7331 Rmpz_cdiv_r_2exp(aTHX_ r, n, b);
7332 if (PL_markstack_ptr != temp) {
7333 /* truly void, because dXSARGS not invoked */
7334 PL_markstack_ptr = temp;
7335 XSRETURN_EMPTY; /* return empty stack */
7336 }
7337 /* must have used dXSARGS; list context implied */
7338 return; /* assume stack size is correct */
7339
7340 void
Rmpz_fdiv_q(q,n,d)7341 Rmpz_fdiv_q (q, n, d)
7342 mpz_t * q
7343 mpz_t * n
7344 mpz_t * d
7345 PREINIT:
7346 I32* temp;
7347 PPCODE:
7348 temp = PL_markstack_ptr++;
7349 Rmpz_fdiv_q(q, n, d);
7350 if (PL_markstack_ptr != temp) {
7351 /* truly void, because dXSARGS not invoked */
7352 PL_markstack_ptr = temp;
7353 XSRETURN_EMPTY; /* return empty stack */
7354 }
7355 /* must have used dXSARGS; list context implied */
7356 return; /* assume stack size is correct */
7357
7358 void
Rmpz_div(q,n,d)7359 Rmpz_div (q, n, d)
7360 mpz_t * q
7361 mpz_t * n
7362 mpz_t * d
7363 PREINIT:
7364 I32* temp;
7365 PPCODE:
7366 temp = PL_markstack_ptr++;
7367 Rmpz_div(q, n, d);
7368 if (PL_markstack_ptr != temp) {
7369 /* truly void, because dXSARGS not invoked */
7370 PL_markstack_ptr = temp;
7371 XSRETURN_EMPTY; /* return empty stack */
7372 }
7373 /* must have used dXSARGS; list context implied */
7374 return; /* assume stack size is correct */
7375
7376 void
Rmpz_fdiv_r(mod,n,d)7377 Rmpz_fdiv_r (mod, n, d)
7378 mpz_t * mod
7379 mpz_t * n
7380 mpz_t * d
7381 PREINIT:
7382 I32* temp;
7383 PPCODE:
7384 temp = PL_markstack_ptr++;
7385 Rmpz_fdiv_r(mod, n, d);
7386 if (PL_markstack_ptr != temp) {
7387 /* truly void, because dXSARGS not invoked */
7388 PL_markstack_ptr = temp;
7389 XSRETURN_EMPTY; /* return empty stack */
7390 }
7391 /* must have used dXSARGS; list context implied */
7392 return; /* assume stack size is correct */
7393
7394 void
Rmpz_fdiv_qr(q,r,n,d)7395 Rmpz_fdiv_qr (q, r, n, d)
7396 mpz_t * q
7397 mpz_t * r
7398 mpz_t * n
7399 mpz_t * d
7400 PREINIT:
7401 I32* temp;
7402 PPCODE:
7403 temp = PL_markstack_ptr++;
7404 Rmpz_fdiv_qr(q, r, n, d);
7405 if (PL_markstack_ptr != temp) {
7406 /* truly void, because dXSARGS not invoked */
7407 PL_markstack_ptr = temp;
7408 XSRETURN_EMPTY; /* return empty stack */
7409 }
7410 /* must have used dXSARGS; list context implied */
7411 return; /* assume stack size is correct */
7412
7413 void
Rmpz_divmod(q,r,n,d)7414 Rmpz_divmod (q, r, n, d)
7415 mpz_t * q
7416 mpz_t * r
7417 mpz_t * n
7418 mpz_t * d
7419 PREINIT:
7420 I32* temp;
7421 PPCODE:
7422 temp = PL_markstack_ptr++;
7423 Rmpz_divmod(q, r, n, d);
7424 if (PL_markstack_ptr != temp) {
7425 /* truly void, because dXSARGS not invoked */
7426 PL_markstack_ptr = temp;
7427 XSRETURN_EMPTY; /* return empty stack */
7428 }
7429 /* must have used dXSARGS; list context implied */
7430 return; /* assume stack size is correct */
7431
7432 unsigned long
7433 Rmpz_fdiv_q_ui (q, n, d)
7434 mpz_t * q
7435 mpz_t * n
7436 unsigned long d
7437
7438 unsigned long
7439 Rmpz_div_ui (q, n, d)
7440 mpz_t * q
7441 mpz_t * n
7442 unsigned long d
7443
7444 unsigned long
7445 Rmpz_fdiv_r_ui (q, n, d)
7446 mpz_t * q
7447 mpz_t * n
7448 unsigned long d
7449
7450 unsigned long
7451 Rmpz_fdiv_qr_ui (q, r, n, d)
7452 mpz_t * q
7453 mpz_t * r
7454 mpz_t * n
7455 unsigned long d
7456
7457 unsigned long
7458 Rmpz_divmod_ui (q, r, n, d)
7459 mpz_t * q
7460 mpz_t * r
7461 mpz_t * n
7462 unsigned long d
7463
7464 unsigned long
7465 Rmpz_fdiv_ui (n, d)
7466 mpz_t * n
7467 unsigned long d
7468
7469 void
7470 Rmpz_fdiv_q_2exp (q, n, b)
7471 mpz_t * q
7472 mpz_t * n
7473 SV * b
7474 PREINIT:
7475 I32* temp;
7476 PPCODE:
7477 temp = PL_markstack_ptr++;
7478 Rmpz_fdiv_q_2exp(aTHX_ q, n, b);
7479 if (PL_markstack_ptr != temp) {
7480 /* truly void, because dXSARGS not invoked */
7481 PL_markstack_ptr = temp;
7482 XSRETURN_EMPTY; /* return empty stack */
7483 }
7484 /* must have used dXSARGS; list context implied */
7485 return; /* assume stack size is correct */
7486
7487 void
Rmpz_fdiv_r_2exp(r,n,b)7488 Rmpz_fdiv_r_2exp (r, n, b)
7489 mpz_t * r
7490 mpz_t * n
7491 SV * b
7492 PREINIT:
7493 I32* temp;
7494 PPCODE:
7495 temp = PL_markstack_ptr++;
7496 Rmpz_fdiv_r_2exp(aTHX_ r, n, b);
7497 if (PL_markstack_ptr != temp) {
7498 /* truly void, because dXSARGS not invoked */
7499 PL_markstack_ptr = temp;
7500 XSRETURN_EMPTY; /* return empty stack */
7501 }
7502 /* must have used dXSARGS; list context implied */
7503 return; /* assume stack size is correct */
7504
7505 void
Rmpz_mod_2exp(r,n,b)7506 Rmpz_mod_2exp (r, n, b)
7507 mpz_t * r
7508 mpz_t * n
7509 SV * b
7510 PREINIT:
7511 I32* temp;
7512 PPCODE:
7513 temp = PL_markstack_ptr++;
7514 Rmpz_mod_2exp(aTHX_ r, n, b);
7515 if (PL_markstack_ptr != temp) {
7516 /* truly void, because dXSARGS not invoked */
7517 PL_markstack_ptr = temp;
7518 XSRETURN_EMPTY; /* return empty stack */
7519 }
7520 /* must have used dXSARGS; list context implied */
7521 return; /* assume stack size is correct */
7522
7523 void
Rmpz_tdiv_q(q,n,d)7524 Rmpz_tdiv_q (q, n, d)
7525 mpz_t * q
7526 mpz_t * n
7527 mpz_t * d
7528 PREINIT:
7529 I32* temp;
7530 PPCODE:
7531 temp = PL_markstack_ptr++;
7532 Rmpz_tdiv_q(q, n, d);
7533 if (PL_markstack_ptr != temp) {
7534 /* truly void, because dXSARGS not invoked */
7535 PL_markstack_ptr = temp;
7536 XSRETURN_EMPTY; /* return empty stack */
7537 }
7538 /* must have used dXSARGS; list context implied */
7539 return; /* assume stack size is correct */
7540
7541 void
Rmpz_tdiv_r(mod,n,d)7542 Rmpz_tdiv_r (mod, n, d)
7543 mpz_t * mod
7544 mpz_t * n
7545 mpz_t * d
7546 PREINIT:
7547 I32* temp;
7548 PPCODE:
7549 temp = PL_markstack_ptr++;
7550 Rmpz_tdiv_r(mod, n, d);
7551 if (PL_markstack_ptr != temp) {
7552 /* truly void, because dXSARGS not invoked */
7553 PL_markstack_ptr = temp;
7554 XSRETURN_EMPTY; /* return empty stack */
7555 }
7556 /* must have used dXSARGS; list context implied */
7557 return; /* assume stack size is correct */
7558
7559 void
Rmpz_tdiv_qr(q,r,n,d)7560 Rmpz_tdiv_qr (q, r, n, d)
7561 mpz_t * q
7562 mpz_t * r
7563 mpz_t * n
7564 mpz_t * d
7565 PREINIT:
7566 I32* temp;
7567 PPCODE:
7568 temp = PL_markstack_ptr++;
7569 Rmpz_tdiv_qr(q, r, n, d);
7570 if (PL_markstack_ptr != temp) {
7571 /* truly void, because dXSARGS not invoked */
7572 PL_markstack_ptr = temp;
7573 XSRETURN_EMPTY; /* return empty stack */
7574 }
7575 /* must have used dXSARGS; list context implied */
7576 return; /* assume stack size is correct */
7577
7578 unsigned long
7579 Rmpz_tdiv_q_ui (q, n, d)
7580 mpz_t * q
7581 mpz_t * n
7582 unsigned long d
7583
7584 unsigned long
7585 Rmpz_tdiv_r_ui (q, n, d)
7586 mpz_t * q
7587 mpz_t * n
7588 unsigned long d
7589
7590 unsigned long
7591 Rmpz_tdiv_qr_ui (q, r, n, d)
7592 mpz_t * q
7593 mpz_t * r
7594 mpz_t * n
7595 unsigned long d
7596
7597 unsigned long
7598 Rmpz_tdiv_ui (n, d)
7599 mpz_t * n
7600 unsigned long d
7601
7602 void
7603 Rmpz_tdiv_q_2exp (q, n, b)
7604 mpz_t * q
7605 mpz_t * n
7606 SV * b
7607 PREINIT:
7608 I32* temp;
7609 PPCODE:
7610 temp = PL_markstack_ptr++;
7611 Rmpz_tdiv_q_2exp(aTHX_ q, n, b);
7612 if (PL_markstack_ptr != temp) {
7613 /* truly void, because dXSARGS not invoked */
7614 PL_markstack_ptr = temp;
7615 XSRETURN_EMPTY; /* return empty stack */
7616 }
7617 /* must have used dXSARGS; list context implied */
7618 return; /* assume stack size is correct */
7619
7620 void
Rmpz_tdiv_r_2exp(r,n,b)7621 Rmpz_tdiv_r_2exp (r, n, b)
7622 mpz_t * r
7623 mpz_t * n
7624 SV * b
7625 PREINIT:
7626 I32* temp;
7627 PPCODE:
7628 temp = PL_markstack_ptr++;
7629 Rmpz_tdiv_r_2exp(aTHX_ r, n, b);
7630 if (PL_markstack_ptr != temp) {
7631 /* truly void, because dXSARGS not invoked */
7632 PL_markstack_ptr = temp;
7633 XSRETURN_EMPTY; /* return empty stack */
7634 }
7635 /* must have used dXSARGS; list context implied */
7636 return; /* assume stack size is correct */
7637
7638 void
Rmpz_mod(r,n,d)7639 Rmpz_mod (r, n, d)
7640 mpz_t * r
7641 mpz_t * n
7642 mpz_t * d
7643 PREINIT:
7644 I32* temp;
7645 PPCODE:
7646 temp = PL_markstack_ptr++;
7647 Rmpz_mod(r, n, d);
7648 if (PL_markstack_ptr != temp) {
7649 /* truly void, because dXSARGS not invoked */
7650 PL_markstack_ptr = temp;
7651 XSRETURN_EMPTY; /* return empty stack */
7652 }
7653 /* must have used dXSARGS; list context implied */
7654 return; /* assume stack size is correct */
7655
7656 unsigned long
7657 Rmpz_mod_ui (r, n, d)
7658 mpz_t * r
7659 mpz_t * n
7660 unsigned long d
7661
7662 void
7663 Rmpz_divexact (dest, n, d)
7664 mpz_t * dest
7665 mpz_t * n
7666 mpz_t * d
7667 PREINIT:
7668 I32* temp;
7669 PPCODE:
7670 temp = PL_markstack_ptr++;
7671 Rmpz_divexact(dest, n, d);
7672 if (PL_markstack_ptr != temp) {
7673 /* truly void, because dXSARGS not invoked */
7674 PL_markstack_ptr = temp;
7675 XSRETURN_EMPTY; /* return empty stack */
7676 }
7677 /* must have used dXSARGS; list context implied */
7678 return; /* assume stack size is correct */
7679
7680 void
Rmpz_divexact_ui(dest,n,d)7681 Rmpz_divexact_ui (dest, n, d)
7682 mpz_t * dest
7683 mpz_t * n
7684 unsigned long d
7685 PREINIT:
7686 I32* temp;
7687 PPCODE:
7688 temp = PL_markstack_ptr++;
7689 Rmpz_divexact_ui(dest, n, d);
7690 if (PL_markstack_ptr != temp) {
7691 /* truly void, because dXSARGS not invoked */
7692 PL_markstack_ptr = temp;
7693 XSRETURN_EMPTY; /* return empty stack */
7694 }
7695 /* must have used dXSARGS; list context implied */
7696 return; /* assume stack size is correct */
7697
7698 int
7699 Rmpz_divisible_p (n, d)
7700 mpz_t * n
7701 mpz_t * d
7702
7703 int
7704 Rmpz_divisible_ui_p (n, d)
7705 mpz_t * n
7706 unsigned long d
7707
7708 int
7709 Rmpz_divisible_2exp_p (n, b)
7710 mpz_t * n
7711 SV * b
7712 CODE:
7713 RETVAL = Rmpz_divisible_2exp_p (aTHX_ n, b);
7714 OUTPUT: RETVAL
7715
7716 int
7717 Rmpz_congruent_p (n, c, d)
7718 mpz_t * n
7719 mpz_t * c
7720 mpz_t * d
7721
7722 int
7723 Rmpz_congruent_ui_p (n, c, d)
7724 mpz_t * n
7725 unsigned long c
7726 unsigned long d
7727
7728 SV *
7729 Rmpz_congruent_2exp_p (n, c, d)
7730 mpz_t * n
7731 mpz_t * c
7732 SV * d
7733 CODE:
7734 RETVAL = Rmpz_congruent_2exp_p (aTHX_ n, c, d);
7735 OUTPUT: RETVAL
7736
7737 void
Rmpz_powm(dest,base,exp,mod)7738 Rmpz_powm (dest, base, exp, mod)
7739 mpz_t * dest
7740 mpz_t * base
7741 mpz_t * exp
7742 mpz_t * mod
7743 PREINIT:
7744 I32* temp;
7745 PPCODE:
7746 temp = PL_markstack_ptr++;
7747 Rmpz_powm(dest, base, exp, mod);
7748 if (PL_markstack_ptr != temp) {
7749 /* truly void, because dXSARGS not invoked */
7750 PL_markstack_ptr = temp;
7751 XSRETURN_EMPTY; /* return empty stack */
7752 }
7753 /* must have used dXSARGS; list context implied */
7754 return; /* assume stack size is correct */
7755
7756 void
Rmpz_powm_ui(dest,base,exp,mod)7757 Rmpz_powm_ui (dest, base, exp, mod)
7758 mpz_t * dest
7759 mpz_t * base
7760 unsigned long exp
7761 mpz_t * mod
7762 PREINIT:
7763 I32* temp;
7764 PPCODE:
7765 temp = PL_markstack_ptr++;
7766 Rmpz_powm_ui(dest, base, exp, mod);
7767 if (PL_markstack_ptr != temp) {
7768 /* truly void, because dXSARGS not invoked */
7769 PL_markstack_ptr = temp;
7770 XSRETURN_EMPTY; /* return empty stack */
7771 }
7772 /* must have used dXSARGS; list context implied */
7773 return; /* assume stack size is correct */
7774
7775 void
Rmpz_pow_ui(dest,base,exp)7776 Rmpz_pow_ui (dest, base, exp)
7777 mpz_t * dest
7778 mpz_t * base
7779 unsigned long exp
7780 PREINIT:
7781 I32* temp;
7782 PPCODE:
7783 temp = PL_markstack_ptr++;
7784 Rmpz_pow_ui(dest, base, exp);
7785 if (PL_markstack_ptr != temp) {
7786 /* truly void, because dXSARGS not invoked */
7787 PL_markstack_ptr = temp;
7788 XSRETURN_EMPTY; /* return empty stack */
7789 }
7790 /* must have used dXSARGS; list context implied */
7791 return; /* assume stack size is correct */
7792
7793 void
Rmpz_ui_pow_ui(dest,base,exp)7794 Rmpz_ui_pow_ui (dest, base, exp)
7795 mpz_t * dest
7796 unsigned long base
7797 unsigned long exp
7798 PREINIT:
7799 I32* temp;
7800 PPCODE:
7801 temp = PL_markstack_ptr++;
7802 Rmpz_ui_pow_ui(dest, base, exp);
7803 if (PL_markstack_ptr != temp) {
7804 /* truly void, because dXSARGS not invoked */
7805 PL_markstack_ptr = temp;
7806 XSRETURN_EMPTY; /* return empty stack */
7807 }
7808 /* must have used dXSARGS; list context implied */
7809 return; /* assume stack size is correct */
7810
7811 int
7812 Rmpz_root (r, n, d)
7813 mpz_t * r
7814 mpz_t * n
7815 unsigned long d
7816
7817 void
7818 Rmpz_sqrt (r, n)
7819 mpz_t * r
7820 mpz_t * n
7821 PREINIT:
7822 I32* temp;
7823 PPCODE:
7824 temp = PL_markstack_ptr++;
7825 Rmpz_sqrt(r, n);
7826 if (PL_markstack_ptr != temp) {
7827 /* truly void, because dXSARGS not invoked */
7828 PL_markstack_ptr = temp;
7829 XSRETURN_EMPTY; /* return empty stack */
7830 }
7831 /* must have used dXSARGS; list context implied */
7832 return; /* assume stack size is correct */
7833
7834 void
Rmpz_sqrtrem(root,rem,src)7835 Rmpz_sqrtrem (root, rem, src)
7836 mpz_t * root
7837 mpz_t * rem
7838 mpz_t * src
7839 PREINIT:
7840 I32* temp;
7841 PPCODE:
7842 temp = PL_markstack_ptr++;
7843 Rmpz_sqrtrem(root, rem, src);
7844 if (PL_markstack_ptr != temp) {
7845 /* truly void, because dXSARGS not invoked */
7846 PL_markstack_ptr = temp;
7847 XSRETURN_EMPTY; /* return empty stack */
7848 }
7849 /* must have used dXSARGS; list context implied */
7850 return; /* assume stack size is correct */
7851
7852 int
7853 Rmpz_perfect_power_p (in)
7854 mpz_t * in
7855
7856 int
7857 Rmpz_perfect_square_p (in)
7858 mpz_t * in
7859
7860 int
7861 Rmpz_probab_prime_p (cand, reps)
7862 mpz_t * cand
7863 SV * reps
7864 CODE:
7865 RETVAL = Rmpz_probab_prime_p (aTHX_ cand, reps);
7866 OUTPUT: RETVAL
7867
7868 void
7869 Rmpz_nextprime (prime, init)
7870 mpz_t * prime
7871 mpz_t * init
7872 PREINIT:
7873 I32* temp;
7874 PPCODE:
7875 temp = PL_markstack_ptr++;
7876 Rmpz_nextprime(prime, init);
7877 if (PL_markstack_ptr != temp) {
7878 /* truly void, because dXSARGS not invoked */
7879 PL_markstack_ptr = temp;
7880 XSRETURN_EMPTY; /* return empty stack */
7881 }
7882 /* must have used dXSARGS; list context implied */
7883 return; /* assume stack size is correct */
7884
7885 void
Rmpz_gcd(gcd,src1,src2)7886 Rmpz_gcd (gcd, src1, src2)
7887 mpz_t * gcd
7888 mpz_t * src1
7889 mpz_t * src2
7890 PREINIT:
7891 I32* temp;
7892 PPCODE:
7893 temp = PL_markstack_ptr++;
7894 Rmpz_gcd(gcd, src1, src2);
7895 if (PL_markstack_ptr != temp) {
7896 /* truly void, because dXSARGS not invoked */
7897 PL_markstack_ptr = temp;
7898 XSRETURN_EMPTY; /* return empty stack */
7899 }
7900 /* must have used dXSARGS; list context implied */
7901 return; /* assume stack size is correct */
7902
7903 unsigned long
7904 Rmpz_gcd_ui (gcd, n, d)
7905 mpz_t * gcd
7906 mpz_t * n
7907 unsigned long d
7908
7909 void
7910 Rmpz_gcdext (g, s, t, a, b)
7911 mpz_t * g
7912 mpz_t * s
7913 mpz_t * t
7914 mpz_t * a
7915 mpz_t * b
7916 PREINIT:
7917 I32* temp;
7918 PPCODE:
7919 temp = PL_markstack_ptr++;
7920 Rmpz_gcdext(g, s, t, a, b);
7921 if (PL_markstack_ptr != temp) {
7922 /* truly void, because dXSARGS not invoked */
7923 PL_markstack_ptr = temp;
7924 XSRETURN_EMPTY; /* return empty stack */
7925 }
7926 /* must have used dXSARGS; list context implied */
7927 return; /* assume stack size is correct */
7928
7929 void
Rmpz_lcm(lcm,src1,src2)7930 Rmpz_lcm (lcm, src1, src2)
7931 mpz_t * lcm
7932 mpz_t * src1
7933 mpz_t * src2
7934 PREINIT:
7935 I32* temp;
7936 PPCODE:
7937 temp = PL_markstack_ptr++;
7938 Rmpz_lcm(lcm, src1, src2);
7939 if (PL_markstack_ptr != temp) {
7940 /* truly void, because dXSARGS not invoked */
7941 PL_markstack_ptr = temp;
7942 XSRETURN_EMPTY; /* return empty stack */
7943 }
7944 /* must have used dXSARGS; list context implied */
7945 return; /* assume stack size is correct */
7946
7947 void
Rmpz_lcm_ui(lcm,src1,src2)7948 Rmpz_lcm_ui (lcm, src1, src2)
7949 mpz_t * lcm
7950 mpz_t * src1
7951 unsigned long src2
7952 PREINIT:
7953 I32* temp;
7954 PPCODE:
7955 temp = PL_markstack_ptr++;
7956 Rmpz_lcm_ui(lcm, src1, src2);
7957 if (PL_markstack_ptr != temp) {
7958 /* truly void, because dXSARGS not invoked */
7959 PL_markstack_ptr = temp;
7960 XSRETURN_EMPTY; /* return empty stack */
7961 }
7962 /* must have used dXSARGS; list context implied */
7963 return; /* assume stack size is correct */
7964
7965 int
7966 Rmpz_invert (inv, src1, src2)
7967 mpz_t * inv
7968 mpz_t * src1
7969 mpz_t * src2
7970
7971 int
7972 Rmpz_jacobi (a, b)
7973 mpz_t * a
7974 mpz_t * b
7975
7976 int
7977 Rmpz_legendre (a, b)
7978 mpz_t * a
7979 mpz_t * b
7980
7981 int
7982 Rmpz_kronecker (a, b)
7983 mpz_t * a
7984 mpz_t * b
7985
7986 int
7987 Rmpz_kronecker_si (a, b)
7988 mpz_t * a
7989 long b
7990
7991 int
7992 Rmpz_kronecker_ui (a, b)
7993 mpz_t * a
7994 unsigned long b
7995
7996 int
7997 Rmpz_si_kronecker (a, b)
7998 long a
7999 mpz_t * b
8000
8001 int
8002 Rmpz_ui_kronecker (a, b)
8003 unsigned long a
8004 mpz_t * b
8005
8006 SV *
8007 Rmpz_remove (rem, src1, src2)
8008 mpz_t * rem
8009 mpz_t * src1
8010 mpz_t * src2
8011 CODE:
8012 RETVAL = Rmpz_remove (aTHX_ rem, src1, src2);
8013 OUTPUT: RETVAL
8014
8015 void
8016 Rmpz_fac_ui (fac, b)
8017 mpz_t * fac
8018 unsigned long b
8019 PREINIT:
8020 I32* temp;
8021 PPCODE:
8022 temp = PL_markstack_ptr++;
8023 Rmpz_fac_ui(fac, b);
8024 if (PL_markstack_ptr != temp) {
8025 /* truly void, because dXSARGS not invoked */
8026 PL_markstack_ptr = temp;
8027 XSRETURN_EMPTY; /* return empty stack */
8028 }
8029 /* must have used dXSARGS; list context implied */
8030 return; /* assume stack size is correct */
8031
8032 void
8033 Rmpz_2fac_ui (fac, b)
8034 mpz_t * fac
8035 unsigned long b
8036 PREINIT:
8037 I32* temp;
8038 PPCODE:
8039 temp = PL_markstack_ptr++;
8040 Rmpz_2fac_ui(fac, b);
8041 if (PL_markstack_ptr != temp) {
8042 /* truly void, because dXSARGS not invoked */
8043 PL_markstack_ptr = temp;
8044 XSRETURN_EMPTY; /* return empty stack */
8045 }
8046 /* must have used dXSARGS; list context implied */
8047 return; /* assume stack size is correct */
8048
8049 void
Rmpz_mfac_uiui(fac,b,c)8050 Rmpz_mfac_uiui (fac, b, c)
8051 mpz_t * fac
8052 unsigned long b
8053 unsigned long c
8054 PREINIT:
8055 I32* temp;
8056 PPCODE:
8057 temp = PL_markstack_ptr++;
8058 Rmpz_mfac_uiui(fac, b, c);
8059 if (PL_markstack_ptr != temp) {
8060 /* truly void, because dXSARGS not invoked */
8061 PL_markstack_ptr = temp;
8062 XSRETURN_EMPTY; /* return empty stack */
8063 }
8064 /* must have used dXSARGS; list context implied */
8065 return; /* assume stack size is correct */
8066
8067 void
8068 Rmpz_primorial_ui (fac, b)
8069 mpz_t * fac
8070 unsigned long b
8071 PREINIT:
8072 I32* temp;
8073 PPCODE:
8074 temp = PL_markstack_ptr++;
8075 Rmpz_primorial_ui(fac, b);
8076 if (PL_markstack_ptr != temp) {
8077 /* truly void, because dXSARGS not invoked */
8078 PL_markstack_ptr = temp;
8079 XSRETURN_EMPTY; /* return empty stack */
8080 }
8081 /* must have used dXSARGS; list context implied */
8082 return; /* assume stack size is correct */
8083
8084 void
Rmpz_bin_ui(dest,n,d)8085 Rmpz_bin_ui (dest, n, d)
8086 mpz_t * dest
8087 mpz_t * n
8088 unsigned long d
8089 PREINIT:
8090 I32* temp;
8091 PPCODE:
8092 temp = PL_markstack_ptr++;
8093 Rmpz_bin_ui(dest, n, d);
8094 if (PL_markstack_ptr != temp) {
8095 /* truly void, because dXSARGS not invoked */
8096 PL_markstack_ptr = temp;
8097 XSRETURN_EMPTY; /* return empty stack */
8098 }
8099 /* must have used dXSARGS; list context implied */
8100 return; /* assume stack size is correct */
8101
8102 void
Rmpz_bin_si(dest,n,d)8103 Rmpz_bin_si (dest, n, d)
8104 mpz_t * dest
8105 mpz_t * n
8106 long d
8107 PREINIT:
8108 I32* temp;
8109 PPCODE:
8110 temp = PL_markstack_ptr++;
8111 Rmpz_bin_si(dest, n, d);
8112 if (PL_markstack_ptr != temp) {
8113 /* truly void, because dXSARGS not invoked */
8114 PL_markstack_ptr = temp;
8115 XSRETURN_EMPTY; /* return empty stack */
8116 }
8117 /* must have used dXSARGS; list context implied */
8118 return; /* assume stack size is correct */
8119
8120 void
Rmpz_bin_uiui(dest,n,d)8121 Rmpz_bin_uiui (dest, n, d)
8122 mpz_t * dest
8123 unsigned long n
8124 unsigned long d
8125 PREINIT:
8126 I32* temp;
8127 PPCODE:
8128 temp = PL_markstack_ptr++;
8129 Rmpz_bin_uiui(dest, n, d);
8130 if (PL_markstack_ptr != temp) {
8131 /* truly void, because dXSARGS not invoked */
8132 PL_markstack_ptr = temp;
8133 XSRETURN_EMPTY; /* return empty stack */
8134 }
8135 /* must have used dXSARGS; list context implied */
8136 return; /* assume stack size is correct */
8137
8138 void
8139 Rmpz_fib_ui (dest, b)
8140 mpz_t * dest
8141 unsigned long b
8142 PREINIT:
8143 I32* temp;
8144 PPCODE:
8145 temp = PL_markstack_ptr++;
8146 Rmpz_fib_ui(dest, b);
8147 if (PL_markstack_ptr != temp) {
8148 /* truly void, because dXSARGS not invoked */
8149 PL_markstack_ptr = temp;
8150 XSRETURN_EMPTY; /* return empty stack */
8151 }
8152 /* must have used dXSARGS; list context implied */
8153 return; /* assume stack size is correct */
8154
8155 void
Rmpz_fib2_ui(fn,fnsub1,b)8156 Rmpz_fib2_ui (fn, fnsub1, b)
8157 mpz_t * fn
8158 mpz_t * fnsub1
8159 unsigned long b
8160 PREINIT:
8161 I32* temp;
8162 PPCODE:
8163 temp = PL_markstack_ptr++;
8164 Rmpz_fib2_ui(fn, fnsub1, b);
8165 if (PL_markstack_ptr != temp) {
8166 /* truly void, because dXSARGS not invoked */
8167 PL_markstack_ptr = temp;
8168 XSRETURN_EMPTY; /* return empty stack */
8169 }
8170 /* must have used dXSARGS; list context implied */
8171 return; /* assume stack size is correct */
8172
8173 void
8174 Rmpz_lucnum_ui (dest, b)
8175 mpz_t * dest
8176 unsigned long b
8177 PREINIT:
8178 I32* temp;
8179 PPCODE:
8180 temp = PL_markstack_ptr++;
8181 Rmpz_lucnum_ui(dest, b);
8182 if (PL_markstack_ptr != temp) {
8183 /* truly void, because dXSARGS not invoked */
8184 PL_markstack_ptr = temp;
8185 XSRETURN_EMPTY; /* return empty stack */
8186 }
8187 /* must have used dXSARGS; list context implied */
8188 return; /* assume stack size is correct */
8189
8190 void
Rmpz_lucnum2_ui(ln,lnsub1,b)8191 Rmpz_lucnum2_ui (ln, lnsub1, b)
8192 mpz_t * ln
8193 mpz_t * lnsub1
8194 unsigned long b
8195 PREINIT:
8196 I32* temp;
8197 PPCODE:
8198 temp = PL_markstack_ptr++;
8199 Rmpz_lucnum2_ui(ln, lnsub1, b);
8200 if (PL_markstack_ptr != temp) {
8201 /* truly void, because dXSARGS not invoked */
8202 PL_markstack_ptr = temp;
8203 XSRETURN_EMPTY; /* return empty stack */
8204 }
8205 /* must have used dXSARGS; list context implied */
8206 return; /* assume stack size is correct */
8207
8208 int
8209 Rmpz_cmp (n, d)
8210 mpz_t * n
8211 mpz_t * d
8212
8213 int
8214 Rmpz_cmp_d (n, d)
8215 mpz_t * n
8216 double d
8217
8218 int
8219 Rmpz_cmp_NV (a, b)
8220 mpz_t * a
8221 SV * b
8222 CODE:
8223 RETVAL = Rmpz_cmp_NV (aTHX_ a, b);
8224 OUTPUT: RETVAL
8225
8226 int
8227 Rmpz_cmp_si (n, d)
8228 mpz_t * n
8229 long d
8230
8231 int
8232 Rmpz_cmp_ui (n, d)
8233 mpz_t * n
8234 unsigned long d
8235
8236 int
8237 Rmpz_cmpabs (n, d)
8238 mpz_t * n
8239 mpz_t * d
8240
8241 int
8242 Rmpz_cmpabs_d (n, d)
8243 mpz_t * n
8244 double d
8245
8246 int
8247 Rmpz_cmpabs_ui (n, d)
8248 mpz_t * n
8249 unsigned long d
8250
8251 int
8252 Rmpz_sgn (n)
8253 mpz_t * n
8254
8255 void
8256 Rmpz_and (dest, src1, src2)
8257 mpz_t * dest
8258 mpz_t * src1
8259 mpz_t * src2
8260 PREINIT:
8261 I32* temp;
8262 PPCODE:
8263 temp = PL_markstack_ptr++;
8264 Rmpz_and(dest, src1, src2);
8265 if (PL_markstack_ptr != temp) {
8266 /* truly void, because dXSARGS not invoked */
8267 PL_markstack_ptr = temp;
8268 XSRETURN_EMPTY; /* return empty stack */
8269 }
8270 /* must have used dXSARGS; list context implied */
8271 return; /* assume stack size is correct */
8272
8273 void
Rmpz_ior(dest,src1,src2)8274 Rmpz_ior (dest, src1, src2)
8275 mpz_t * dest
8276 mpz_t * src1
8277 mpz_t * src2
8278 PREINIT:
8279 I32* temp;
8280 PPCODE:
8281 temp = PL_markstack_ptr++;
8282 Rmpz_ior(dest, src1, src2);
8283 if (PL_markstack_ptr != temp) {
8284 /* truly void, because dXSARGS not invoked */
8285 PL_markstack_ptr = temp;
8286 XSRETURN_EMPTY; /* return empty stack */
8287 }
8288 /* must have used dXSARGS; list context implied */
8289 return; /* assume stack size is correct */
8290
8291 void
Rmpz_xor(dest,src1,src2)8292 Rmpz_xor (dest, src1, src2)
8293 mpz_t * dest
8294 mpz_t * src1
8295 mpz_t * src2
8296 PREINIT:
8297 I32* temp;
8298 PPCODE:
8299 temp = PL_markstack_ptr++;
8300 Rmpz_xor(dest, src1, src2);
8301 if (PL_markstack_ptr != temp) {
8302 /* truly void, because dXSARGS not invoked */
8303 PL_markstack_ptr = temp;
8304 XSRETURN_EMPTY; /* return empty stack */
8305 }
8306 /* must have used dXSARGS; list context implied */
8307 return; /* assume stack size is correct */
8308
8309 void
8310 Rmpz_com (dest, src)
8311 mpz_t * dest
8312 mpz_t * src
8313 PREINIT:
8314 I32* temp;
8315 PPCODE:
8316 temp = PL_markstack_ptr++;
8317 Rmpz_com(dest, src);
8318 if (PL_markstack_ptr != temp) {
8319 /* truly void, because dXSARGS not invoked */
8320 PL_markstack_ptr = temp;
8321 XSRETURN_EMPTY; /* return empty stack */
8322 }
8323 /* must have used dXSARGS; list context implied */
8324 return; /* assume stack size is correct */
8325
8326 SV *
8327 Rmpz_popcount (in)
8328 mpz_t * in
8329 CODE:
8330 RETVAL = Rmpz_popcount (aTHX_ in);
8331 OUTPUT: RETVAL
8332
8333 SV *
8334 Rmpz_hamdist (dest, src)
8335 mpz_t * dest
8336 mpz_t * src
8337 CODE:
8338 RETVAL = Rmpz_hamdist (aTHX_ dest, src);
8339 OUTPUT: RETVAL
8340
8341 SV *
8342 Rmpz_scan0 (n, start_bit)
8343 mpz_t * n
8344 SV * start_bit
8345 CODE:
8346 RETVAL = Rmpz_scan0 (aTHX_ n, start_bit);
8347 OUTPUT: RETVAL
8348
8349 SV *
8350 Rmpz_scan1 (n, start_bit)
8351 mpz_t * n
8352 SV * start_bit
8353 CODE:
8354 RETVAL = Rmpz_scan1 (aTHX_ n, start_bit);
8355 OUTPUT: RETVAL
8356
8357 void
8358 Rmpz_setbit (num, bit_index)
8359 mpz_t * num
8360 SV * bit_index
8361 PREINIT:
8362 I32* temp;
8363 PPCODE:
8364 temp = PL_markstack_ptr++;
8365 Rmpz_setbit(aTHX_ num, bit_index);
8366 if (PL_markstack_ptr != temp) {
8367 /* truly void, because dXSARGS not invoked */
8368 PL_markstack_ptr = temp;
8369 XSRETURN_EMPTY; /* return empty stack */
8370 }
8371 /* must have used dXSARGS; list context implied */
8372 return; /* assume stack size is correct */
8373
8374 void
8375 Rmpz_clrbit (num, bit_index)
8376 mpz_t * num
8377 SV * bit_index
8378 PREINIT:
8379 I32* temp;
8380 PPCODE:
8381 temp = PL_markstack_ptr++;
8382 Rmpz_clrbit(aTHX_ num, bit_index);
8383 if (PL_markstack_ptr != temp) {
8384 /* truly void, because dXSARGS not invoked */
8385 PL_markstack_ptr = temp;
8386 XSRETURN_EMPTY; /* return empty stack */
8387 }
8388 /* must have used dXSARGS; list context implied */
8389 return; /* assume stack size is correct */
8390
8391 SV *
8392 Rmpz_tstbit (num, bit_index)
8393 mpz_t * num
8394 SV * bit_index
8395 CODE:
8396 RETVAL = Rmpz_tstbit (aTHX_ num, bit_index);
8397 OUTPUT: RETVAL
8398
8399 void
Rmpz_import(rop,count,order,size,endian,nails,op)8400 Rmpz_import (rop, count, order, size, endian, nails, op)
8401 mpz_t * rop
8402 SV * count
8403 SV * order
8404 SV * size
8405 SV * endian
8406 SV * nails
8407 SV * op
8408 PREINIT:
8409 I32* temp;
8410 PPCODE:
8411 temp = PL_markstack_ptr++;
8412 Rmpz_import(aTHX_ rop, count, order, size, endian, nails, op);
8413 if (PL_markstack_ptr != temp) {
8414 /* truly void, because dXSARGS not invoked */
8415 PL_markstack_ptr = temp;
8416 XSRETURN_EMPTY; /* return empty stack */
8417 }
8418 /* must have used dXSARGS; list context implied */
8419 return; /* assume stack size is correct */
8420
8421 SV *
8422 Rmpz_export (order, size, endian, nails, op)
8423 SV * order
8424 SV * size
8425 SV * endian
8426 SV * nails
8427 mpz_t * op
8428 CODE:
8429 RETVAL = Rmpz_export (aTHX_ order, size, endian, nails, op);
8430 OUTPUT: RETVAL
8431
8432 void
Rmpz_import_UV(rop,count,order,size,endian,nails,op)8433 Rmpz_import_UV (rop, count, order, size, endian, nails, op)
8434 mpz_t * rop
8435 SV * count
8436 SV * order
8437 SV * size
8438 SV * endian
8439 SV * nails
8440 AV * op
8441 PREINIT:
8442 I32* temp;
8443 PPCODE:
8444 temp = PL_markstack_ptr++;
8445 Rmpz_import_UV(aTHX_ rop, count, order, size, endian, nails, op);
8446 if (PL_markstack_ptr != temp) {
8447 /* truly void, because dXSARGS not invoked */
8448 PL_markstack_ptr = temp;
8449 XSRETURN_EMPTY; /* return empty stack */
8450 }
8451 /* must have used dXSARGS; list context implied */
8452 return; /* assume stack size is correct */
8453
8454 void
Rmpz_export_UV(order,size,endian,nails,op)8455 Rmpz_export_UV (order, size, endian, nails, op)
8456 SV * order
8457 SV * size
8458 SV * endian
8459 SV * nails
8460 mpz_t * op
8461 PREINIT:
8462 I32* temp;
8463 PPCODE:
8464 temp = PL_markstack_ptr++;
8465 Rmpz_export_UV(aTHX_ order, size, endian, nails, op);
8466 if (PL_markstack_ptr != temp) {
8467 /* truly void, because dXSARGS not invoked */
8468 PL_markstack_ptr = temp;
8469 XSRETURN_EMPTY; /* return empty stack */
8470 }
8471 /* must have used dXSARGS; list context implied */
8472 return; /* assume stack size is correct */
8473
8474 int
8475 Rmpz_fits_ulong_p (in)
8476 mpz_t * in
8477
8478 int
8479 Rmpz_fits_slong_p (in)
8480 mpz_t * in
8481
8482 int
8483 Rmpz_fits_uint_p (in)
8484 mpz_t * in
8485
8486 int
8487 Rmpz_fits_sint_p (in)
8488 mpz_t * in
8489
8490 int
8491 Rmpz_fits_ushort_p (in)
8492 mpz_t * in
8493
8494 int
8495 Rmpz_fits_sshort_p (in)
8496 mpz_t * in
8497
8498 int
8499 Rmpz_odd_p (in)
8500 mpz_t * in
8501
8502 int
8503 Rmpz_even_p (in)
8504 mpz_t * in
8505
8506 SV *
8507 Rmpz_size (in)
8508 mpz_t * in
8509 CODE:
8510 RETVAL = Rmpz_size (aTHX_ in);
8511 OUTPUT: RETVAL
8512
8513 SV *
8514 Rmpz_sizeinbase (in, base)
8515 mpz_t * in
8516 int base
8517 CODE:
8518 RETVAL = Rmpz_sizeinbase (aTHX_ in, base);
8519 OUTPUT: RETVAL
8520
8521 void
Rsieve_gmp(x_arg,a,number)8522 Rsieve_gmp (x_arg, a, number)
8523 int x_arg
8524 int a
8525 mpz_t * number
8526 PREINIT:
8527 I32* temp;
8528 PPCODE:
8529 temp = PL_markstack_ptr++;
8530 Rsieve_gmp(aTHX_ x_arg, a, number);
8531 if (PL_markstack_ptr != temp) {
8532 /* truly void, because dXSARGS not invoked */
8533 PL_markstack_ptr = temp;
8534 XSRETURN_EMPTY; /* return empty stack */
8535 }
8536 /* must have used dXSARGS; list context implied */
8537 return; /* assume stack size is correct */
8538
8539 SV *
8540 Rfermat_gmp (num, base)
8541 mpz_t * num
8542 int base
8543 CODE:
8544 RETVAL = Rfermat_gmp (aTHX_ num, base);
8545 OUTPUT: RETVAL
8546
8547 SV *
8548 Rrm_gmp (num, base)
8549 mpz_t * num
8550 int base
8551 CODE:
8552 RETVAL = Rrm_gmp (aTHX_ num, base);
8553 OUTPUT: RETVAL
8554
8555 SV *
8556 _Rmpz_out_str (p, base)
8557 mpz_t * p
8558 int base
8559 CODE:
8560 RETVAL = _Rmpz_out_str (aTHX_ p, base);
8561 OUTPUT: RETVAL
8562
8563 SV *
8564 _Rmpz_out_strS (p, base, suff)
8565 mpz_t * p
8566 SV * base
8567 SV * suff
8568 CODE:
8569 RETVAL = _Rmpz_out_strS (aTHX_ p, base, suff);
8570 OUTPUT: RETVAL
8571
8572 SV *
8573 _Rmpz_out_strP (pre, p, base)
8574 SV * pre
8575 mpz_t * p
8576 SV * base
8577 CODE:
8578 RETVAL = _Rmpz_out_strP (aTHX_ pre, p, base);
8579 OUTPUT: RETVAL
8580
8581 SV *
8582 _Rmpz_out_strPS (pre, p, base, suff)
8583 SV * pre
8584 mpz_t * p
8585 SV * base
8586 SV * suff
8587 CODE:
8588 RETVAL = _Rmpz_out_strPS (aTHX_ pre, p, base, suff);
8589 OUTPUT: RETVAL
8590
8591 SV *
8592 _TRmpz_out_str (stream, base, p)
8593 FILE * stream
8594 SV * base
8595 mpz_t * p
8596 CODE:
8597 RETVAL = _TRmpz_out_str (aTHX_ stream, base, p);
8598 OUTPUT: RETVAL
8599
8600 SV *
8601 _TRmpz_out_strS (stream, base, p, suff)
8602 FILE * stream
8603 SV * base
8604 mpz_t * p
8605 SV * suff
8606 CODE:
8607 RETVAL = _TRmpz_out_strS (aTHX_ stream, base, p, suff);
8608 OUTPUT: RETVAL
8609
8610 SV *
8611 _TRmpz_out_strP (pre, stream, base, p)
8612 SV * pre
8613 FILE * stream
8614 SV * base
8615 mpz_t * p
8616 CODE:
8617 RETVAL = _TRmpz_out_strP (aTHX_ pre, stream, base, p);
8618 OUTPUT: RETVAL
8619
8620 SV *
8621 _TRmpz_out_strPS (pre, stream, base, p, suff)
8622 SV * pre
8623 FILE * stream
8624 SV * base
8625 mpz_t * p
8626 SV * suff
8627 CODE:
8628 RETVAL = _TRmpz_out_strPS (aTHX_ pre, stream, base, p, suff);
8629 OUTPUT: RETVAL
8630
8631 SV *
8632 Rmpz_inp_str (p, base)
8633 mpz_t * p
8634 int base
8635 CODE:
8636 RETVAL = Rmpz_inp_str (aTHX_ p, base);
8637 OUTPUT: RETVAL
8638
8639 SV *
8640 TRmpz_inp_str (p, stream, base)
8641 mpz_t * p
8642 FILE * stream
8643 int base
8644 CODE:
8645 RETVAL = TRmpz_inp_str (aTHX_ p, stream, base);
8646 OUTPUT: RETVAL
8647
8648 void
8649 eratosthenes (x_arg)
8650 SV * x_arg
8651 PREINIT:
8652 I32* temp;
8653 PPCODE:
8654 temp = PL_markstack_ptr++;
8655 eratosthenes(aTHX_ x_arg);
8656 if (PL_markstack_ptr != temp) {
8657 /* truly void, because dXSARGS not invoked */
8658 PL_markstack_ptr = temp;
8659 XSRETURN_EMPTY; /* return empty stack */
8660 }
8661 /* must have used dXSARGS; list context implied */
8662 return; /* assume stack size is correct */
8663
8664 SV *
8665 trial_div_ul (num, x_arg)
8666 mpz_t * num
8667 SV * x_arg
8668 CODE:
8669 RETVAL = trial_div_ul (aTHX_ num, x_arg);
8670 OUTPUT: RETVAL
8671
8672 void
Rmpz_rootrem(root,rem,u,d)8673 Rmpz_rootrem (root, rem, u, d)
8674 mpz_t * root
8675 mpz_t * rem
8676 mpz_t * u
8677 unsigned long d
8678 PREINIT:
8679 I32* temp;
8680 PPCODE:
8681 temp = PL_markstack_ptr++;
8682 Rmpz_rootrem(root, rem, u, d);
8683 if (PL_markstack_ptr != temp) {
8684 /* truly void, because dXSARGS not invoked */
8685 PL_markstack_ptr = temp;
8686 XSRETURN_EMPTY; /* return empty stack */
8687 }
8688 /* must have used dXSARGS; list context implied */
8689 return; /* assume stack size is correct */
8690
8691 void
8692 Rmpz_combit (num, bitpos)
8693 mpz_t * num
8694 SV * bitpos
8695 PREINIT:
8696 I32* temp;
8697 PPCODE:
8698 temp = PL_markstack_ptr++;
8699 Rmpz_combit(aTHX_ num, bitpos);
8700 if (PL_markstack_ptr != temp) {
8701 /* truly void, because dXSARGS not invoked */
8702 PL_markstack_ptr = temp;
8703 XSRETURN_EMPTY; /* return empty stack */
8704 }
8705 /* must have used dXSARGS; list context implied */
8706 return; /* assume stack size is correct */
8707
8708 SV *
8709 overload_mul (a, b, third)
8710 SV * a
8711 SV * b
8712 SV * third
8713 CODE:
8714 RETVAL = overload_mul (aTHX_ a, b, third);
8715 OUTPUT: RETVAL
8716
8717 SV *
8718 overload_add (a, b, third)
8719 SV * a
8720 SV * b
8721 SV * third
8722 CODE:
8723 RETVAL = overload_add (aTHX_ a, b, third);
8724 OUTPUT: RETVAL
8725
8726 SV *
8727 overload_sub (a, b, third)
8728 SV * a
8729 SV * b
8730 SV * third
8731 CODE:
8732 RETVAL = overload_sub (aTHX_ a, b, third);
8733 OUTPUT: RETVAL
8734
8735 SV *
8736 overload_div (a, b, third)
8737 SV * a
8738 SV * b
8739 SV * third
8740 CODE:
8741 RETVAL = overload_div (aTHX_ a, b, third);
8742 OUTPUT: RETVAL
8743
8744 SV *
8745 overload_mod (a, b, third)
8746 mpz_t * a
8747 SV * b
8748 SV * third
8749 CODE:
8750 RETVAL = overload_mod (aTHX_ a, b, third);
8751 OUTPUT: RETVAL
8752
8753 SV *
8754 overload_string (p, second, third)
8755 mpz_t * p
8756 SV * second
8757 SV * third
8758 CODE:
8759 RETVAL = overload_string (aTHX_ p, second, third);
8760 OUTPUT: RETVAL
8761
8762 SV *
8763 overload_copy (p, second, third)
8764 mpz_t * p
8765 SV * second
8766 SV * third
8767 CODE:
8768 RETVAL = overload_copy (aTHX_ p, second, third);
8769 OUTPUT: RETVAL
8770
8771 SV *
8772 overload_abs (p, second, third)
8773 mpz_t * p
8774 SV * second
8775 SV * third
8776 CODE:
8777 RETVAL = overload_abs (aTHX_ p, second, third);
8778 OUTPUT: RETVAL
8779
8780 SV *
8781 overload_lshift (a, b, third)
8782 mpz_t * a
8783 SV * b
8784 SV * third
8785 CODE:
8786 RETVAL = overload_lshift (aTHX_ a, b, third);
8787 OUTPUT: RETVAL
8788
8789 SV *
8790 overload_rshift (a, b, third)
8791 mpz_t * a
8792 SV * b
8793 SV * third
8794 CODE:
8795 RETVAL = overload_rshift (aTHX_ a, b, third);
8796 OUTPUT: RETVAL
8797
8798 SV *
8799 overload_pow (a, b, third)
8800 SV * a
8801 SV * b
8802 SV * third
8803 CODE:
8804 RETVAL = overload_pow (aTHX_ a, b, third);
8805 OUTPUT: RETVAL
8806
8807 SV *
8808 overload_sqrt (p, second, third)
8809 mpz_t * p
8810 SV * second
8811 SV * third
8812 CODE:
8813 RETVAL = overload_sqrt (aTHX_ p, second, third);
8814 OUTPUT: RETVAL
8815
8816 SV *
8817 overload_and (a, b, third, ...)
8818 mpz_t * a
8819 SV * b
8820 SV * third
8821 PREINIT:
8822 I32* temp;
8823 CODE:
8824 temp = PL_markstack_ptr++;
8825 RETVAL = overload_and(aTHX_ a, b, third);
8826 PL_markstack_ptr = temp;
8827 OUTPUT:
8828 RETVAL
8829
8830 SV *
8831 overload_ior (a, b, third, ...)
8832 mpz_t * a
8833 SV * b
8834 SV * third
8835 PREINIT:
8836 I32* temp;
8837 CODE:
8838 temp = PL_markstack_ptr++;
8839 RETVAL = overload_ior(aTHX_ a, b, third);
8840 PL_markstack_ptr = temp;
8841 OUTPUT:
8842 RETVAL
8843
8844 SV *
8845 overload_xor (a, b, third, ...)
8846 mpz_t * a
8847 SV * b
8848 SV * third
8849 PREINIT:
8850 I32* temp;
8851 CODE:
8852 temp = PL_markstack_ptr++;
8853 RETVAL = overload_xor(aTHX_ a, b, third);
8854 PL_markstack_ptr = temp;
8855 OUTPUT:
8856 RETVAL
8857
8858 SV *
8859 overload_com (p, second, third)
8860 mpz_t * p
8861 SV * second
8862 SV * third
8863 CODE:
8864 RETVAL = overload_com (aTHX_ p, second, third);
8865 OUTPUT: RETVAL
8866
8867 int
8868 my_cmp_z (p, z)
8869 mpq_t * p
8870 mpz_t * z
8871
8872 SV *
8873 overload_gt (a, b, third)
8874 mpz_t * a
8875 SV * b
8876 SV * third
8877 CODE:
8878 RETVAL = overload_gt (aTHX_ a, b, third);
8879 OUTPUT: RETVAL
8880
8881 SV *
8882 overload_gte (a, b, third)
8883 mpz_t * a
8884 SV * b
8885 SV * third
8886 CODE:
8887 RETVAL = overload_gte (aTHX_ a, b, third);
8888 OUTPUT: RETVAL
8889
8890 SV *
8891 overload_lt (a, b, third)
8892 mpz_t * a
8893 SV * b
8894 SV * third
8895 CODE:
8896 RETVAL = overload_lt (aTHX_ a, b, third);
8897 OUTPUT: RETVAL
8898
8899 SV *
8900 overload_lte (a, b, third)
8901 mpz_t * a
8902 SV * b
8903 SV * third
8904 CODE:
8905 RETVAL = overload_lte (aTHX_ a, b, third);
8906 OUTPUT: RETVAL
8907
8908 SV *
8909 overload_spaceship (a, b, third)
8910 mpz_t * a
8911 SV * b
8912 SV * third
8913 CODE:
8914 RETVAL = overload_spaceship (aTHX_ a, b, third);
8915 OUTPUT: RETVAL
8916
8917 SV *
8918 overload_equiv (a, b, third)
8919 mpz_t * a
8920 SV * b
8921 SV * third
8922 CODE:
8923 RETVAL = overload_equiv (aTHX_ a, b, third);
8924 OUTPUT: RETVAL
8925
8926 SV *
8927 overload_not_equiv (a, b, third)
8928 mpz_t * a
8929 SV * b
8930 SV * third
8931 CODE:
8932 RETVAL = overload_not_equiv (aTHX_ a, b, third);
8933 OUTPUT: RETVAL
8934
8935 SV *
8936 overload_not (a, second, third)
8937 mpz_t * a
8938 SV * second
8939 SV * third
8940 CODE:
8941 RETVAL = overload_not (aTHX_ a, second, third);
8942 OUTPUT: RETVAL
8943
8944 SV *
8945 overload_xor_eq (a, b, third, ...)
8946 SV * a
8947 SV * b
8948 SV * third
8949 PREINIT:
8950 I32* temp;
8951 CODE:
8952 temp = PL_markstack_ptr++;
8953 RETVAL = overload_xor_eq(aTHX_ a, b, third);
8954 PL_markstack_ptr = temp;
8955 OUTPUT:
8956 RETVAL
8957
8958 SV *
8959 overload_ior_eq (a, b, third, ...)
8960 SV * a
8961 SV * b
8962 SV * third
8963 PREINIT:
8964 I32* temp;
8965 CODE:
8966 temp = PL_markstack_ptr++;
8967 RETVAL = overload_ior_eq(aTHX_ a, b, third);
8968 PL_markstack_ptr = temp;
8969 OUTPUT:
8970 RETVAL
8971
8972 SV *
8973 overload_and_eq (a, b, third, ...)
8974 SV * a
8975 SV * b
8976 SV * third
8977 PREINIT:
8978 I32* temp;
8979 CODE:
8980 temp = PL_markstack_ptr++;
8981 RETVAL = overload_and_eq(aTHX_ a, b, third);
8982 PL_markstack_ptr = temp;
8983 OUTPUT:
8984 RETVAL
8985
8986 SV *
8987 overload_pow_eq (a, b, third)
8988 SV * a
8989 SV * b
8990 SV * third
8991 CODE:
8992 RETVAL = overload_pow_eq (aTHX_ a, b, third);
8993 OUTPUT: RETVAL
8994
8995 SV *
8996 overload_rshift_eq (a, b, third)
8997 SV * a
8998 SV * b
8999 SV * third
9000 CODE:
9001 RETVAL = overload_rshift_eq (aTHX_ a, b, third);
9002 OUTPUT: RETVAL
9003
9004 SV *
9005 overload_lshift_eq (a, b, third)
9006 SV * a
9007 SV * b
9008 SV * third
9009 CODE:
9010 RETVAL = overload_lshift_eq (aTHX_ a, b, third);
9011 OUTPUT: RETVAL
9012
9013 SV *
9014 overload_inc (p, second, third)
9015 SV * p
9016 SV * second
9017 SV * third
9018 CODE:
9019 RETVAL = overload_inc (aTHX_ p, second, third);
9020 OUTPUT: RETVAL
9021
9022 SV *
9023 overload_dec (p, second, third)
9024 SV * p
9025 SV * second
9026 SV * third
9027 CODE:
9028 RETVAL = overload_dec (aTHX_ p, second, third);
9029 OUTPUT: RETVAL
9030
9031 SV *
9032 overload_mod_eq (a, b, third)
9033 SV * a
9034 SV * b
9035 SV * third
9036 CODE:
9037 RETVAL = overload_mod_eq (aTHX_ a, b, third);
9038 OUTPUT: RETVAL
9039
9040 SV *
9041 get_refcnt (s)
9042 SV * s
9043 CODE:
9044 RETVAL = get_refcnt (aTHX_ s);
9045 OUTPUT: RETVAL
9046
9047 SV *
9048 overload_div_eq (a, b, third)
9049 SV * a
9050 SV * b
9051 SV * third
9052 CODE:
9053 RETVAL = overload_div_eq (aTHX_ a, b, third);
9054 OUTPUT: RETVAL
9055
9056 SV *
9057 overload_sub_eq (a, b, third)
9058 SV * a
9059 SV * b
9060 SV * third
9061 CODE:
9062 RETVAL = overload_sub_eq (aTHX_ a, b, third);
9063 OUTPUT: RETVAL
9064
9065 SV *
9066 overload_add_eq (a, b, third)
9067 SV * a
9068 SV * b
9069 SV * third
9070 CODE:
9071 RETVAL = overload_add_eq (aTHX_ a, b, third);
9072 OUTPUT: RETVAL
9073
9074 SV *
9075 overload_mul_eq (a, b, third)
9076 SV * a
9077 SV * b
9078 SV * third
9079 CODE:
9080 RETVAL = overload_mul_eq (aTHX_ a, b, third);
9081 OUTPUT: RETVAL
9082
9083 SV *
9084 eratosthenes_string (x_arg)
9085 SV * x_arg
9086 CODE:
9087 RETVAL = eratosthenes_string (aTHX_ x_arg);
9088 OUTPUT: RETVAL
9089
9090 SV *
9091 gmp_v ()
9092 CODE:
9093 RETVAL = gmp_v (aTHX);
9094 OUTPUT: RETVAL
9095
9096
9097 SV *
9098 wrap_gmp_printf (a, b)
9099 SV * a
9100 SV * b
9101 CODE:
9102 RETVAL = wrap_gmp_printf (aTHX_ a, b);
9103 OUTPUT: RETVAL
9104
9105 SV *
9106 wrap_gmp_fprintf (stream, a, b)
9107 FILE * stream
9108 SV * a
9109 SV * b
9110 CODE:
9111 RETVAL = wrap_gmp_fprintf (aTHX_ stream, a, b);
9112 OUTPUT: RETVAL
9113
9114 SV *
9115 wrap_gmp_sprintf (s, a, b, buflen)
9116 SV * s
9117 SV * a
9118 SV * b
9119 int buflen
9120 CODE:
9121 RETVAL = wrap_gmp_sprintf (aTHX_ s, a, b, buflen);
9122 OUTPUT: RETVAL
9123
9124 SV *
9125 wrap_gmp_snprintf (s, bytes, a, b, buflen)
9126 SV * s
9127 SV * bytes
9128 SV * a
9129 SV * b
9130 int buflen
9131 CODE:
9132 RETVAL = wrap_gmp_snprintf (aTHX_ s, bytes, a, b, buflen);
9133 OUTPUT: RETVAL
9134
9135 SV *
9136 _itsa (a)
9137 SV * a
9138 CODE:
9139 RETVAL = _itsa (aTHX_ a);
9140 OUTPUT: RETVAL
9141
9142 void
9143 Rmpz_urandomb (p, ...)
9144 SV * p
9145 PREINIT:
9146 I32* temp;
9147 PPCODE:
9148 temp = PL_markstack_ptr++;
9149 Rmpz_urandomb(aTHX_ p);
9150 if (PL_markstack_ptr != temp) {
9151 /* truly void, because dXSARGS not invoked */
9152 PL_markstack_ptr = temp;
9153 XSRETURN_EMPTY; /* return empty stack */
9154 }
9155 /* must have used dXSARGS; list context implied */
9156 return; /* assume stack size is correct */
9157
9158 void
9159 Rmpz_urandomm (x, ...)
9160 SV * x
9161 PREINIT:
9162 I32* temp;
9163 PPCODE:
9164 temp = PL_markstack_ptr++;
9165 Rmpz_urandomm(aTHX_ x);
9166 if (PL_markstack_ptr != temp) {
9167 /* truly void, because dXSARGS not invoked */
9168 PL_markstack_ptr = temp;
9169 XSRETURN_EMPTY; /* return empty stack */
9170 }
9171 /* must have used dXSARGS; list context implied */
9172 return; /* assume stack size is correct */
9173
9174 void
9175 Rmpz_rrandomb (x, ...)
9176 SV * x
9177 PREINIT:
9178 I32* temp;
9179 PPCODE:
9180 temp = PL_markstack_ptr++;
9181 Rmpz_rrandomb(aTHX_ x);
9182 if (PL_markstack_ptr != temp) {
9183 /* truly void, because dXSARGS not invoked */
9184 PL_markstack_ptr = temp;
9185 XSRETURN_EMPTY; /* return empty stack */
9186 }
9187 /* must have used dXSARGS; list context implied */
9188 return; /* assume stack size is correct */
9189
9190 SV *
9191 rand_init (seed)
9192 SV * seed
9193 CODE:
9194 RETVAL = rand_init (aTHX_ seed);
9195 OUTPUT: RETVAL
9196
9197 void
9198 rand_clear (p)
9199 SV * p
9200 PREINIT:
9201 I32* temp;
9202 PPCODE:
9203 temp = PL_markstack_ptr++;
9204 rand_clear(aTHX_ p);
9205 if (PL_markstack_ptr != temp) {
9206 /* truly void, because dXSARGS not invoked */
9207 PL_markstack_ptr = temp;
9208 XSRETURN_EMPTY; /* return empty stack */
9209 }
9210 /* must have used dXSARGS; list context implied */
9211 return; /* assume stack size is correct */
9212
9213 int
9214 _has_longlong ()
9215
9216
9217 int
9218 _has_longdouble ()
9219
9220
9221 int
9222 _has_float128 ()
9223
9224
9225 int
9226 _has_inttypes ()
9227
9228
9229 SV *
9230 Rmpz_inp_raw (a, stream)
9231 mpz_t * a
9232 FILE * stream
9233 CODE:
9234 RETVAL = Rmpz_inp_raw (aTHX_ a, stream);
9235 OUTPUT: RETVAL
9236
9237 SV *
9238 Rmpz_out_raw (stream, a)
9239 FILE * stream
9240 mpz_t * a
9241 CODE:
9242 RETVAL = Rmpz_out_raw (aTHX_ stream, a);
9243 OUTPUT: RETVAL
9244
9245 SV *
9246 ___GNU_MP_VERSION ()
9247 CODE:
9248 RETVAL = ___GNU_MP_VERSION (aTHX);
9249 OUTPUT: RETVAL
9250
9251
9252 SV *
9253 ___GNU_MP_VERSION_MINOR ()
9254 CODE:
9255 RETVAL = ___GNU_MP_VERSION_MINOR (aTHX);
9256 OUTPUT: RETVAL
9257
9258
9259 SV *
9260 ___GNU_MP_VERSION_PATCHLEVEL ()
9261 CODE:
9262 RETVAL = ___GNU_MP_VERSION_PATCHLEVEL (aTHX);
9263 OUTPUT: RETVAL
9264
9265
9266 SV *
9267 ___GNU_MP_RELEASE ()
9268 CODE:
9269 RETVAL = ___GNU_MP_RELEASE (aTHX);
9270 OUTPUT: RETVAL
9271
9272
9273 SV *
9274 ___GMP_CC ()
9275 CODE:
9276 RETVAL = ___GMP_CC (aTHX);
9277 OUTPUT: RETVAL
9278
9279
9280 SV *
9281 ___GMP_CFLAGS ()
9282 CODE:
9283 RETVAL = ___GMP_CFLAGS (aTHX);
9284 OUTPUT: RETVAL
9285
9286
9287 void
Rmpz_powm_sec(dest,base,exp,mod)9288 Rmpz_powm_sec (dest, base, exp, mod)
9289 mpz_t * dest
9290 mpz_t * base
9291 mpz_t * exp
9292 mpz_t * mod
9293 PREINIT:
9294 I32* temp;
9295 PPCODE:
9296 temp = PL_markstack_ptr++;
9297 Rmpz_powm_sec(dest, base, exp, mod);
9298 if (PL_markstack_ptr != temp) {
9299 /* truly void, because dXSARGS not invoked */
9300 PL_markstack_ptr = temp;
9301 XSRETURN_EMPTY; /* return empty stack */
9302 }
9303 /* must have used dXSARGS; list context implied */
9304 return; /* assume stack size is correct */
9305
9306 int
9307 _using_mpir ()
9308
9309
9310 SV *
9311 _Rmpz_NULL ()
9312 CODE:
9313 RETVAL = _Rmpz_NULL (aTHX);
9314 OUTPUT: RETVAL
9315
9316
9317 SV *
9318 _wrap_count ()
9319 CODE:
9320 RETVAL = _wrap_count (aTHX);
9321 OUTPUT: RETVAL
9322
9323
9324 void
Rprbg_ms(outref,p,q,seed,bits_required)9325 Rprbg_ms (outref, p, q, seed, bits_required)
9326 mpz_t * outref
9327 mpz_t * p
9328 mpz_t * q
9329 mpz_t * seed
9330 int bits_required
9331 PREINIT:
9332 I32* temp;
9333 PPCODE:
9334 temp = PL_markstack_ptr++;
9335 Rprbg_ms(aTHX_ outref, p, q, seed, bits_required);
9336 if (PL_markstack_ptr != temp) {
9337 /* truly void, because dXSARGS not invoked */
9338 PL_markstack_ptr = temp;
9339 XSRETURN_EMPTY; /* return empty stack */
9340 }
9341 /* must have used dXSARGS; list context implied */
9342 return; /* assume stack size is correct */
9343
9344 void
Rprbg_bbs(outref,p,q,seed,bits_required)9345 Rprbg_bbs (outref, p, q, seed, bits_required)
9346 mpz_t * outref
9347 mpz_t * p
9348 mpz_t * q
9349 mpz_t * seed
9350 int bits_required
9351 PREINIT:
9352 I32* temp;
9353 PPCODE:
9354 temp = PL_markstack_ptr++;
9355 Rprbg_bbs(aTHX_ outref, p, q, seed, bits_required);
9356 if (PL_markstack_ptr != temp) {
9357 /* truly void, because dXSARGS not invoked */
9358 PL_markstack_ptr = temp;
9359 XSRETURN_EMPTY; /* return empty stack */
9360 }
9361 /* must have used dXSARGS; list context implied */
9362 return; /* assume stack size is correct */
9363
9364 int
9365 Rmonobit (bitstream)
9366 mpz_t * bitstream
9367
9368 int
9369 Rlong_run (bitstream)
9370 mpz_t * bitstream
9371
9372 int
9373 Rruns (bitstream)
9374 mpz_t * bitstream
9375
9376 int
9377 Rpoker (bitstream)
9378 mpz_t * bitstream
9379
9380 SV *
9381 _get_xs_version ()
9382 CODE:
9383 RETVAL = _get_xs_version (aTHX);
9384 OUTPUT: RETVAL
9385
9386
9387 SV *
9388 query_eratosthenes_string (candidate, str)
9389 int candidate
9390 char * str
9391 CODE:
9392 RETVAL = query_eratosthenes_string (aTHX_ candidate, str);
9393 OUTPUT: RETVAL
9394
9395 void
9396 autocorrelation (bitstream, offset)
9397 mpz_t * bitstream
9398 int offset
9399 PREINIT:
9400 I32* temp;
9401 PPCODE:
9402 temp = PL_markstack_ptr++;
9403 autocorrelation(aTHX_ bitstream, offset);
9404 if (PL_markstack_ptr != temp) {
9405 /* truly void, because dXSARGS not invoked */
9406 PL_markstack_ptr = temp;
9407 XSRETURN_EMPTY; /* return empty stack */
9408 }
9409 /* must have used dXSARGS; list context implied */
9410 return; /* assume stack size is correct */
9411
9412 int
9413 autocorrelation_20000 (bitstream, offset)
9414 mpz_t * bitstream
9415 int offset
9416 CODE:
9417 RETVAL = autocorrelation_20000 (aTHX_ bitstream, offset);
9418 OUTPUT: RETVAL
9419
9420 SV *
9421 _GMP_LIMB_BITS ()
9422 CODE:
9423 RETVAL = _GMP_LIMB_BITS (aTHX);
9424 OUTPUT: RETVAL
9425
9426
9427 SV *
9428 _GMP_NAIL_BITS ()
9429 CODE:
9430 RETVAL = _GMP_NAIL_BITS (aTHX);
9431 OUTPUT: RETVAL
9432
9433
9434 SV *
9435 _new_from_MBI (b)
9436 SV * b
9437 CODE:
9438 RETVAL = _new_from_MBI (aTHX_ b);
9439 OUTPUT: RETVAL
9440
9441 SV *
9442 _magic_status ()
9443 CODE:
9444 RETVAL = _magic_status (aTHX);
9445 OUTPUT: RETVAL
9446
9447
9448 void
9449 _dump_mbi_gmp (b)
9450 SV * b
9451 PREINIT:
9452 I32* temp;
9453 PPCODE:
9454 temp = PL_markstack_ptr++;
9455 _dump_mbi_gmp(aTHX_ b);
9456 if (PL_markstack_ptr != temp) {
9457 /* truly void, because dXSARGS not invoked */
9458 PL_markstack_ptr = temp;
9459 XSRETURN_EMPTY; /* return empty stack */
9460 }
9461 /* must have used dXSARGS; list context implied */
9462 return; /* assume stack size is correct */
9463
9464 int
9465 _SvIOK (sv)
9466 SV * sv
9467 CODE:
9468 RETVAL = _SvIOK (aTHX_ sv);
9469 OUTPUT: RETVAL
9470
9471 int
9472 _SvPOK (sv)
9473 SV * sv
9474
9475 int
9476 _SvNOK (sv)
9477 SV * sv
9478
9479 int
9480 IOK_flag (sv)
9481 SV * sv
9482
9483 int
9484 POK_flag (sv)
9485 SV * sv
9486
9487 int
9488 NOK_flag (sv)
9489 SV * sv
9490
9491 SV *
9492 _sizeof_mp_bitcnt_t ()
9493 CODE:
9494 RETVAL = _sizeof_mp_bitcnt_t (aTHX);
9495 OUTPUT: RETVAL
9496
9497
9498 int
9499 _gmp_index_overflow ()
9500
9501
9502