File Coverage

inc/CryptX_BigInt_LTM.xs.inc
Criterion Covered Total %
statement 188 218 86.2
branch 94 134 70.1
condition n/a
subroutine n/a
pod n/a
total 282 352 80.1


line stmt bran cond sub pod time code
1             MODULE = CryptX PACKAGE = Math::BigInt::LTM
2              
3             PROTOTYPES: DISABLE
4              
5             ##############################################################################
6             # _new()
7              
8             Math::BigInt::LTM
9             _new(Class, SV *x)
10             PREINIT:
11             mp_err merr;
12             CODE:
13 32718           Newz(0, RETVAL, 1, mp_int);
14 32718           merr = mp_init(RETVAL);
15             #if IVSIZE == 8
16 32718 50         if (SvUOK(x)) {
17 0           mp_set_u64(RETVAL, (unsigned long long)SvUV(x));
18             }
19 32718 100         else if (SvIOK(x)) {
20 17357           mp_set_i64(RETVAL, (long long)SvIV(x));
21             }
22             #else
23             if (SvUOK(x)) {
24             mp_set_u32(RETVAL, (unsigned int)SvUV(x));
25             }
26             else if (SvIOK(x)) {
27             mp_set_i32(RETVAL, (int)SvIV(x));
28             }
29             #endif
30             else {
31             /* fallback - read the decimal number from string */
32 15361           merr = mp_read_radix(RETVAL, SvPV_nolen(x), 10);
33             }
34             PERL_UNUSED_VAR(merr);
35             OUTPUT:
36             RETVAL
37              
38             ##############################################################################
39             # _from_bin()
40              
41             Math::BigInt::LTM
42             _from_bin(Class, SV *x)
43             PREINIT:
44             mp_err merr;
45             char *str, *start;
46             CODE:
47 64           Newz(0, RETVAL, 1, mp_int);
48 64           merr = mp_init(RETVAL);
49 64           str = SvPV_nolen(x);
50 64 50         start = (strlen(str)>2 && str[0] == '0' && str[1] == 'b') ? str+2 : str;
    50          
    50          
51 64           merr = mp_read_radix(RETVAL, start, 2);
52             PERL_UNUSED_VAR(merr);
53             OUTPUT:
54             RETVAL
55              
56             ##############################################################################
57             # _from_hex()
58              
59             Math::BigInt::LTM
60             _from_hex(Class, SV *x)
61             PREINIT:
62             mp_err merr;
63             char *str, *start;
64             CODE:
65 276           Newz(0, RETVAL, 1, mp_int);
66 276           merr = mp_init(RETVAL);
67 276           str = SvPV_nolen(x);
68 276 50         start = (strlen(str)>2 && str[0] == '0' && str[1] == 'x') ? str+2 : str;
    50          
    50          
69 276           merr = mp_read_radix(RETVAL, start, 16);
70             PERL_UNUSED_VAR(merr);
71             OUTPUT:
72             RETVAL
73              
74             ##############################################################################
75             # _from_oct()
76              
77             Math::BigInt::LTM
78             _from_oct(Class, SV *x)
79             PREINIT:
80             mp_err merr;
81             CODE:
82 6           Newz(0, RETVAL, 1, mp_int);
83 6           merr = mp_init(RETVAL);
84 6           merr = mp_read_radix(RETVAL, SvPV_nolen(x), 8);
85             PERL_UNUSED_VAR(merr);
86             OUTPUT:
87             RETVAL
88              
89             ##############################################################################
90             # _from_base()
91              
92             Math::BigInt::LTM
93             _from_base(Class, SV *x, int base)
94             PREINIT:
95             mp_err merr;
96             CODE:
97 0           Newz(0, RETVAL, 1, mp_int);
98 0           merr = mp_init(RETVAL);
99 0           merr = mp_read_radix(RETVAL, SvPV_nolen(x), base);
100             PERL_UNUSED_VAR(merr);
101             OUTPUT:
102             RETVAL
103              
104             ##############################################################################
105             # _from_bytes()
106              
107             Math::BigInt::LTM
108             _from_bytes(Class, SV *x)
109             PREINIT:
110             mp_err merr;
111             STRLEN buf_len;
112             unsigned char *buf_ptr;
113             CODE:
114 0           Newz(0, RETVAL, 1, mp_int);
115 0           merr = mp_init(RETVAL);
116 0           buf_ptr = (unsigned char *)SvPVbyte(x, buf_len);
117 0           merr = mp_from_ubin(RETVAL, buf_ptr, buf_len);
118             PERL_UNUSED_VAR(merr);
119             OUTPUT:
120             RETVAL
121              
122             ##############################################################################
123             # _set() - set an already existing object to the given scalar value
124              
125             void
126             _set(Class, Math::BigInt::LTM n, SV *x)
127             PREINIT:
128             mp_err merr;
129             CODE:
130             #if IVSIZE == 8
131 3 50         if (SvUOK(x)) {
132 0           mp_set_u64(n, (unsigned long long)SvUV(x));
133             }
134 3 50         else if (SvIOK(x)) {
135 3           mp_set_i64(n, (long long)SvIV(x));
136             }
137             #else
138             if (SvUOK(x)) {
139             mp_set_u32(n, (unsigned int)SvUV(x));
140             }
141             else if (SvIOK(x)) {
142             mp_set_i32(n, (int)SvIV(x));
143             }
144             #endif
145             else {
146             /* fallback - read the decimal number from string */
147 0           merr = mp_read_radix(n, SvPV_nolen(x), 10);
148             PERL_UNUSED_VAR(merr);
149             }
150              
151             ##############################################################################
152             # _zero()
153              
154             Math::BigInt::LTM
155             _zero(Class)
156             PREINIT:
157             mp_err merr;
158             CODE:
159 7726           Newz(0, RETVAL, 1, mp_int);
160 7726           merr = mp_init(RETVAL);
161 7726           mp_zero(RETVAL);
162             PERL_UNUSED_VAR(merr);
163             OUTPUT:
164             RETVAL
165              
166             ##############################################################################
167             # _one()
168              
169             Math::BigInt::LTM
170             _one(Class)
171             PREINIT:
172             mp_err merr;
173             CODE:
174 342           Newz(0, RETVAL, 1, mp_int);
175 342           merr = mp_init(RETVAL);
176 342           mp_set_u32(RETVAL, 1);
177             PERL_UNUSED_VAR(merr);
178             OUTPUT:
179             RETVAL
180              
181             ##############################################################################
182             # _two()
183              
184             Math::BigInt::LTM
185             _two(Class)
186             PREINIT:
187             mp_err merr;
188             CODE:
189 142           Newz(0, RETVAL, 1, mp_int);
190 142           merr = mp_init(RETVAL);
191 142           mp_set_u32(RETVAL, 2);
192             PERL_UNUSED_VAR(merr);
193             OUTPUT:
194             RETVAL
195              
196             ##############################################################################
197             # _ten()
198              
199             Math::BigInt::LTM
200             _ten(Class)
201             PREINIT:
202             mp_err merr;
203             CODE:
204 4           Newz(0, RETVAL, 1, mp_int);
205 4           merr = mp_init(RETVAL);
206 4           mp_set_u32(RETVAL, 10);
207             PERL_UNUSED_VAR(merr);
208             OUTPUT:
209             RETVAL
210              
211             ##############################################################################
212             # _1ex()
213              
214             Math::BigInt::LTM
215             _1ex(Class, int x)
216             PREINIT:
217             mp_err merr;
218             CODE:
219 5           Newz(0, RETVAL, 1, mp_int);
220 5           merr = mp_init(RETVAL);
221 5           mp_set_u32(RETVAL, 10);
222 5           merr = mp_expt_n(RETVAL, x, RETVAL);
223             PERL_UNUSED_VAR(merr);
224             OUTPUT:
225             RETVAL
226              
227             ##############################################################################
228             # DESTROY() - free memory of a GMP number
229              
230             void
231             DESTROY(Math::BigInt::LTM n)
232             PPCODE:
233 65036 50         if (n) {
234 65036           mp_clear(n);
235 65036           Safefree(n);
236             }
237              
238             ##############################################################################
239             # _str() - return string so that atof() and atoi() can use it
240              
241             SV *
242             _str(Class, Math::BigInt::LTM n)
243             PREINIT:
244             mp_err merr;
245             int len;
246             char *buf;
247             CODE:
248 18304 100         if (mp_iszero(n) == MP_YES) {
249 1344           RETVAL = newSVpv("0", 0);
250             }
251             else {
252 16960           len = mp_count_bits(n) / 3 + 3; /* decimal_size ~ (binary_size/3 + 1) +1 for sign +1 for NUL-byte */
253 16960           Newz(0, buf, len, char);
254 16960           merr = mp_to_radix(n, buf, len, NULL, 10);
255 16960           RETVAL = newSVpv(buf, 0);
256 16960           Safefree(buf);
257             }
258             PERL_UNUSED_VAR(merr);
259             OUTPUT:
260             RETVAL
261              
262             ##############################################################################
263             # _len() - return the length of the number in base 10 (costly)
264              
265             int
266             _len(Class, Math::BigInt::LTM n)
267             PREINIT:
268             mp_err merr;
269             int len;
270             char *buf;
271             CODE:
272 31802 100         if (mp_iszero(n) == MP_YES) {
273 9           RETVAL = 1;
274             }
275             else {
276 31793           len = mp_count_bits(n) / 3 + 3; /* decimal_size ~ (binary_size/3 + 1) +1 for sign +1 for NUL-byte */
277 31793           Newz(0, buf, len, char);
278 31793           merr = mp_to_radix(n, buf, len, NULL, 10);
279 31793           RETVAL = (int)strlen(buf);
280 31793           Safefree(buf);
281             }
282             PERL_UNUSED_VAR(merr);
283             OUTPUT:
284             RETVAL
285              
286             ##############################################################################
287             # _alen() - return the approx. length of the number in base 10 (fast)
288             # _alen() might underestimate, but never overestimate the true value
289              
290             int
291             _alen(Class, Math::BigInt::LTM n)
292             PREINIT:
293             int bits;
294             CODE:
295 36           bits = mp_count_bits(n);
296             /* alen = round(bits * log(2) / log(10)) */
297 36 100         RETVAL = (bits < 5) ? 1 : (int)(bits * 0.301029995663 + 0.499999999999);
    100          
298             /* less accurate approximation, but without floating-point calculations
299             RETVAL = (bits < 5) ? 1 : bits / 4 + bits / 32 + bits / 64 + bits / 256;
300             RETVAL = (bits < 5) ? 1 : bits / 4;
301             */
302             OUTPUT:
303             RETVAL
304              
305             ##############################################################################
306             # _zeros() - return number of trailing zeros (in decimal form)
307              
308             int
309             _zeros(Class, Math::BigInt::LTM n)
310             PREINIT:
311             mp_err merr;
312             int len;
313             char *buf;
314             CODE:
315 23279 100         if (mp_iszero(n) == MP_YES) {
316 450           RETVAL = 0; /* '0' has no trailing zeros! */
317             }
318             else {
319 22829           len = mp_count_bits(n) / 3 + 3; /* decimal_size ~ (binary_size/3 + 1) +1 for sign +1 for NUL-byte */
320 22829           Newz(0, buf, len, char);
321 22829           merr = mp_to_radix(n, buf, len, NULL, 10);
322 22829           len = (int)strlen(buf);
323 22829           RETVAL = 0;
324 242145 50         while (len > 0) {
325 242145 100         if (buf[len-1] != '0') break;
326 219316           RETVAL++;
327 219316           len--;
328             }
329 22829           Safefree(buf);
330             }
331             PERL_UNUSED_VAR(merr);
332             OUTPUT:
333             RETVAL
334              
335             ##############################################################################
336             # _to_hex() - return ref to hexadecimal string (no prefix)
337              
338             SV *
339             _to_hex(Class, Math::BigInt::LTM n)
340             PREINIT:
341             mp_err merr;
342             size_t i, len;
343             char *buf;
344             CODE:
345 72 100         len = mp_iszero(n) ? 2 : mp_ubin_size(n) * 2 + 1; /* incl. NUL-byte */
346 72           RETVAL = newSV(len);
347 72           SvPOK_on(RETVAL);
348 72           buf = SvPVX(RETVAL);
349 72           merr = mp_to_radix(n, buf, len, NULL, 16); /* to hex */
350 206 100         for (i=0; i0; i++) buf[i] = toLOWER(buf[i]);
    50          
    100          
351 72           SvCUR_set(RETVAL, strlen(buf));
352             PERL_UNUSED_VAR(merr);
353             OUTPUT:
354             RETVAL
355              
356             ##############################################################################
357             # _to_bin() - return ref to binary string (no prefix)
358              
359             SV *
360             _to_bin(Class, Math::BigInt::LTM n)
361             PREINIT:
362             mp_err merr;
363             size_t len;
364             char *buf;
365             CODE:
366 31 100         len = mp_iszero(n) ? 2 : mp_ubin_size(n) * 8 + 1; /* incl. NUL-byte */
367 31           RETVAL = newSV(len);
368 31           SvPOK_on(RETVAL);
369 31           buf = SvPVX(RETVAL);
370 31           merr = mp_to_radix(n, buf, len, NULL, 2); /* to binary */
371 31           SvCUR_set(RETVAL, strlen(buf));
372             PERL_UNUSED_VAR(merr);
373             OUTPUT:
374             RETVAL
375              
376             ##############################################################################
377             # _to_oct() - return ref to octal string (no prefix)
378              
379             SV *
380             _to_oct(Class, Math::BigInt::LTM n)
381             PREINIT:
382             mp_err merr;
383             size_t len;
384             char *buf;
385             CODE:
386 10 100         len = mp_iszero(n) ? 2 : mp_ubin_size(n) * 3 + 1; /* incl. NUL-byte */
387 10           RETVAL = newSV(len);
388 10           SvPOK_on(RETVAL);
389 10           buf = SvPVX(RETVAL);
390 10           merr = mp_to_radix(n, buf, len, NULL, 8); /* to octal */
391 10           SvCUR_set(RETVAL, strlen(buf));
392             PERL_UNUSED_VAR(merr);
393             OUTPUT:
394             RETVAL
395              
396             ##############################################################################
397             # _to_base() - raw bytes
398              
399             SV *
400             _to_base(Class, Math::BigInt::LTM n, int base)
401             PREINIT:
402             mp_err merr;
403             size_t len;
404             char *buf;
405             CODE:
406 0 0         len = mp_iszero(n) ? 2 : mp_ubin_size(n) * 8 + 1; /* the worst case for base == 2 */
407 0           RETVAL = newSV(len);
408 0           SvPOK_on(RETVAL);
409 0           buf = SvPVX(RETVAL);
410 0           merr = mp_to_radix(n, buf, len, NULL, base);
411 0           SvCUR_set(RETVAL, strlen(buf));
412             PERL_UNUSED_VAR(merr);
413             OUTPUT:
414             RETVAL
415              
416             ##############################################################################
417             # _to_bytes() - raw bytes
418             # _as_bytes() - raw bytes
419              
420             SV *
421             _to_bytes(Class, Math::BigInt::LTM n)
422             ALIAS:
423             _as_bytes = 1
424             PREINIT:
425             mp_err merr;
426             size_t len;
427             unsigned char *buf;
428             CODE:
429             PERL_UNUSED_VAR(ix);
430 0           len = mp_ubin_size(n);
431 0 0         if (len > 0) {
432 0           RETVAL = newSV(len);
433 0           SvPOK_on(RETVAL);
434 0           buf = (unsigned char*)SvPVX(RETVAL);
435 0           merr = mp_to_ubin(n, buf, len, NULL);
436 0           SvCUR_set(RETVAL, len);
437             }
438             else {
439 0           RETVAL = newSV(1);
440 0           SvPOK_on(RETVAL);
441 0           buf = (unsigned char*)SvPVX(RETVAL);
442 0           buf[0] = 0;
443 0           SvCUR_set(RETVAL, 1);
444             }
445             PERL_UNUSED_VAR(merr);
446             OUTPUT:
447             RETVAL
448              
449             ##############################################################################
450             # _modpow() - ($n ** $exp) % $mod
451              
452             Math::BigInt::LTM
453             _modpow(Class, Math::BigInt::LTM n, Math::BigInt::LTM exp, Math::BigInt::LTM mod)
454             PREINIT:
455             mp_err merr;
456             CODE:
457 144           Newz(0, RETVAL, 1, mp_int);
458 144           merr = mp_init(RETVAL);
459 144 100         if (mp_cmp_d(mod, 1) == MP_EQ) {
460 50           mp_zero(RETVAL);
461             }
462             else {
463 94           merr = mp_exptmod(n, exp, mod, RETVAL);
464             }
465             PERL_UNUSED_VAR(merr);
466             OUTPUT:
467             RETVAL
468              
469             ##############################################################################
470             # _modinv() - compute the inverse of x % y
471              
472             void
473             _modinv(Class, Math::BigInt::LTM x, Math::BigInt::LTM y)
474             PREINIT:
475             mp_err merr;
476             int rc;
477             SV* s;
478             mp_int* RETVAL;
479             PPCODE:
480 42           Newz(0, RETVAL, 1, mp_int);
481 42           merr = mp_init(RETVAL);
482 42           rc = mp_invmod(x, y, RETVAL);
483 42 50         EXTEND(SP, 2); /* we return two values */
484 42 100         if (rc != MP_OKAY) {
485             /* Inverse doesn't exist. Return both values undefined. */
486 7           PUSHs(&PL_sv_undef);
487 7           PUSHs(&PL_sv_undef);
488             }
489             else {
490             /* Inverse exists. When the modulus to mp_invert() is positive,
491             * the returned value is also positive. */
492 35           PUSHs(sv_2mortal(sv_from_mpi(RETVAL)));
493 35           s = sv_newmortal();
494 35           sv_setpvn(s, "+", 1);
495 35           PUSHs(s);
496             }
497             PERL_UNUSED_VAR(merr);
498              
499             ##############################################################################
500             # _add() - add $y to $x in place
501              
502             void
503             _add(Class, Math::BigInt::LTM x, Math::BigInt::LTM y)
504             PREINIT:
505             mp_err merr;
506             PPCODE:
507 15548           merr = mp_add(x, y, x);
508             PERL_UNUSED_VAR(merr);
509 15548 50         XPUSHs(ST(1)); /* x */
510              
511             ##############################################################################
512             # _inc() - modify x inline by doing x++
513              
514             void
515             _inc(Class, Math::BigInt::LTM x)
516             PREINIT:
517             mp_err merr;
518             PPCODE:
519 1425           merr = mp_add_d(x, 1, x);
520             PERL_UNUSED_VAR(merr);
521 1425 50         XPUSHs(ST(1)); /* x */
522              
523             ##############################################################################
524             # _dec() - modify x inline by doing x--
525              
526             void
527             _dec(Class, Math::BigInt::LTM x)
528             PREINIT:
529             mp_err merr;
530             PPCODE:
531 558           merr = mp_sub_d(x, 1, x);
532             PERL_UNUSED_VAR(merr);
533 558 50         XPUSHs(ST(1)); /* x */
534              
535             ##############################################################################
536             # _sub() - $x - $y
537             # $x is always larger than $y! So overflow/underflow can not happen here.
538              
539             void
540             _sub(Class, Math::BigInt::LTM x, Math::BigInt::LTM y, ...)
541             PREINIT:
542             mp_err merr;
543             PPCODE:
544 15762 100         if ( items == 4 && SvTRUE(ST(3)) ) {
    100          
545             /* y -= x */
546 1563           merr = mp_sub(x, y, y);
547 1563 50         XPUSHs(ST(2)); /* y */
548             }
549             else {
550             /* x -= y */
551 14199           merr = mp_sub(x, y, x);
552 14199 50         XPUSHs(ST(1)); /* x */
553             }
554             PERL_UNUSED_VAR(merr);
555              
556             ##############################################################################
557             # _rsft()
558              
559             void
560             _rsft(Class, Math::BigInt::LTM x, Math::BigInt::LTM y, unsigned long base_int)
561             PREINIT:
562             mp_err merr;
563             mp_int* BASE;
564             PPCODE:
565 9465           Newz(0, BASE, 1, mp_int);
566 9465           merr = mp_init(BASE);
567 9465           mp_set_ul(BASE, base_int);
568 9465           merr = mp_expt_n(BASE, mp_get_l(y), BASE);
569 9465           merr = mp_div(x, BASE, x, NULL);
570             PERL_UNUSED_VAR(merr);
571 9465           mp_clear(BASE);
572 9465           Safefree(BASE);
573 9465 50         XPUSHs(ST(1)); /* x */
574              
575             ##############################################################################
576             # _lsft()
577              
578             void
579             _lsft(Class, Math::BigInt::LTM x, Math::BigInt::LTM y, unsigned long base_int)
580             PREINIT:
581             mp_err merr;
582             mp_int* BASE;
583             PPCODE:
584 6039           Newz(0, BASE, 1, mp_int);
585 6039           merr = mp_init(BASE);
586 6039           mp_set_ul(BASE, base_int);
587 6039           merr = mp_expt_n(BASE, mp_get_l(y), BASE);
588 6039           merr = mp_mul(x, BASE, x);
589             PERL_UNUSED_VAR(merr);
590 6039           mp_clear(BASE);
591 6039           Safefree(BASE);
592 6039 50         XPUSHs(ST(1)); /* x */
593              
594             ##############################################################################
595             # _mul()
596              
597             void
598             _mul(Class, Math::BigInt::LTM x, Math::BigInt::LTM y)
599             PREINIT:
600             mp_err merr;
601             PPCODE:
602 6924           merr = mp_mul(x, y, x);
603             PERL_UNUSED_VAR(merr);
604 6924 50         XPUSHs(ST(1)); /* x */
605              
606             ##############################################################################
607             # _div(): x /= y or (x,rem) = x / y
608              
609             void
610             _div(Class, Math::BigInt::LTM x, Math::BigInt::LTM y)
611             PREINIT:
612             mp_err merr;
613             mp_int * rem;
614             PPCODE:
615 2880 100         if (GIMME_V == G_ARRAY) {
616 146           Newz(0, rem, 1, mp_int);
617 146           merr = mp_init(rem);
618 146           merr = mp_div(x, y, x, rem);
619 146 50         EXTEND(SP, 2);
620 146           PUSHs(ST(1)); /* x */
621 146           PUSHs(sv_2mortal(sv_from_mpi(rem)));
622             }
623             else {
624 2734           merr = mp_div(x, y, x, NULL);
625 2734 50         XPUSHs(ST(1)); /* x */
626             }
627             PERL_UNUSED_VAR(merr);
628              
629             ##############################################################################
630             # _mod() - x %= y
631              
632             void
633             _mod(Class, Math::BigInt::LTM x, Math::BigInt::LTM y)
634             PREINIT:
635             mp_err merr;
636             PPCODE:
637 252           merr = mp_mod(x, y, x);
638             PERL_UNUSED_VAR(merr);
639 252 50         XPUSHs(ST(1)); /* x */
640              
641             ##############################################################################
642             # _acmp() - cmp two numbers
643              
644             int
645             _acmp(Class, Math::BigInt::LTM m, Math::BigInt::LTM n)
646             CODE:
647 20205           RETVAL = mp_cmp(m, n);
648 20205 100         if ( RETVAL < 0) RETVAL = -1;
649 20205 100         if ( RETVAL > 0) RETVAL = 1;
650             OUTPUT:
651             RETVAL
652              
653             ##############################################################################
654             # _is_zero()
655              
656             int
657             _is_zero(Class, Math::BigInt::LTM x)
658             CODE:
659 74124 100         RETVAL = (mp_iszero(x) == MP_YES) ? 1 : 0;
660             OUTPUT:
661             RETVAL
662              
663             ##############################################################################
664             # _is_one()
665              
666             int
667             _is_one(Class, Math::BigInt::LTM x)
668             CODE:
669 936 100         RETVAL = (mp_cmp_d(x, 1) == MP_EQ) ? 1 : 0;
670             OUTPUT:
671             RETVAL
672              
673             ##############################################################################
674             # _is_two()
675              
676             int
677             _is_two(Class, Math::BigInt::LTM x)
678             CODE:
679 45 100         RETVAL = (mp_cmp_d(x, 2) == MP_EQ) ? 1 : 0;
680             OUTPUT:
681             RETVAL
682              
683             ##############################################################################
684             # _is_ten()
685              
686             int
687             _is_ten(Class, Math::BigInt::LTM x)
688             CODE:
689 2 50         RETVAL = (mp_cmp_d(x, 10) == MP_EQ) ? 1 : 0;
690             OUTPUT:
691             RETVAL
692              
693             ##############################################################################
694             # _pow() - x **= y
695              
696             void
697             _pow(Class, Math::BigInt::LTM x, Math::BigInt::LTM y)
698             PREINIT:
699             mp_err merr;
700             PPCODE:
701 200           merr = mp_expt_n(x, mp_get_l(y), x);
702             PERL_UNUSED_VAR(merr);
703 200 50         XPUSHs(ST(1)); /* x */
704              
705             ##############################################################################
706             # _gcd() - gcd(m,n)
707              
708             Math::BigInt::LTM
709             _gcd(Class, Math::BigInt::LTM x, Math::BigInt::LTM y)
710             PREINIT:
711             mp_err merr;
712             CODE:
713 18           Newz(0, RETVAL, 1, mp_int);
714 18           merr = mp_init(RETVAL);
715 18           merr = mp_gcd(x, y, RETVAL);
716             PERL_UNUSED_VAR(merr);
717             OUTPUT:
718             RETVAL
719              
720             ##############################################################################
721             # _and() - m &= n
722              
723             void
724             _and(Class, Math::BigInt::LTM x, Math::BigInt::LTM y)
725             PREINIT:
726             mp_err merr;
727             PPCODE:
728 26           merr = mp_and(x, y, x);
729             PERL_UNUSED_VAR(merr);
730 26 50         XPUSHs(ST(1)); /* x */
731              
732             ##############################################################################
733             # _xor() - m =^ n
734              
735             void
736             _xor(Class, Math::BigInt::LTM x, Math::BigInt::LTM y)
737             PREINIT:
738             mp_err merr;
739             PPCODE:
740 39           merr = mp_xor(x, y, x);
741             PERL_UNUSED_VAR(merr);
742 39 50         XPUSHs(ST(1)); /* x */
743              
744             ##############################################################################
745             # _or() - m =| n
746              
747             void
748             _or(Class, Math::BigInt::LTM x, Math::BigInt::LTM y)
749             PREINIT:
750             mp_err merr;
751             PPCODE:
752 41           merr = mp_or(x, y, x);
753             PERL_UNUSED_VAR(merr);
754 41 50         XPUSHs(ST(1)); /* x */
755              
756             ##############################################################################
757             # _copy()
758              
759             Math::BigInt::LTM
760             _copy(Class, Math::BigInt::LTM m)
761             PREINIT:
762             mp_err merr;
763             CODE:
764 23409           Newz(0, RETVAL, 1, mp_int);
765 23409           merr = mp_init(RETVAL);
766 23409           merr = mp_copy(m, RETVAL);
767             PERL_UNUSED_VAR(merr);
768             OUTPUT:
769             RETVAL
770              
771             ##############################################################################
772             # _is_odd() - test for number being odd
773              
774             int
775             _is_odd(Class, Math::BigInt::LTM n)
776             CODE:
777 171 100         RETVAL = (mp_isodd(n) == MP_YES) ? 1 : 0;
    100          
    100          
778             OUTPUT:
779             RETVAL
780              
781             ##############################################################################
782             # _is_even() - test for number being even
783              
784             int
785             _is_even(Class, Math::BigInt::LTM n)
786             CODE:
787 23 100         RETVAL = (mp_iseven(n) == MP_YES || mp_iszero(n) == MP_YES) ? 1 : 0;
    100          
    100          
    50          
    100          
788             OUTPUT:
789             RETVAL
790              
791             ##############################################################################
792             # _sqrt() - square root
793              
794             void
795             _sqrt(Class, Math::BigInt::LTM x)
796             PREINIT:
797             mp_err merr;
798             PPCODE:
799 119           merr = mp_sqrt(x, x);
800             PERL_UNUSED_VAR(merr);
801 119 50         XPUSHs(ST(1)); /* x */
802              
803             ##############################################################################
804             # _root() - integer roots
805              
806             void
807             _root(Class, Math::BigInt::LTM x, Math::BigInt::LTM y)
808             PREINIT:
809             mp_err merr;
810             PPCODE:
811 50           merr = mp_root_n(x, mp_get_l(y), x);
812             PERL_UNUSED_VAR(merr);
813 50 50         XPUSHs(ST(1)); /* x */
814              
815             ##############################################################################
816             # _lcm() - least common multiple
817             void
818             _lcm(Class, Math::BigInt::LTM x, Math::BigInt::LTM y)
819             PREINIT:
820             mp_err merr;
821             PPCODE:
822 2           merr = mp_lcm(x, y, x) ;
823             PERL_UNUSED_VAR(merr);
824 2 50         XPUSHs(ST(1)); /* x */
825              
826             ##############################################################################
827             # Storable hooks
828              
829             void
830             STORABLE_thaw(blank_obj, cloning, serialized, ...)
831             SV *blank_obj
832             SV *cloning = NO_INIT
833             SV *serialized
834             PREINIT:
835             mp_err merr;
836             SV *target;
837             mp_int *mpi;
838             PPCODE:
839             PERL_UNUSED_VAR(cloning);
840 1 50         if (SvROK(blank_obj) && sv_isa(blank_obj, "Math::BigInt::LTM")) {
    50          
841 1           Newz(0, mpi, 1, mp_int);
842 1           merr = mp_init(mpi);
843 1           merr = mp_read_radix(mpi, SvPV_nolen(serialized), 10);
844             PERL_UNUSED_VAR(merr);
845 1           target = SvRV(blank_obj);
846 1           SvIV_set(target, PTR2IV(mpi));
847 1           SvIOK_on(target);
848 1           PUSHs(target);
849 1           XSRETURN(1);
850             }
851             else
852 0           croak("Bad object for Math::BigInt::LTM::STORABLE_thaw call");
853              
854             SV *
855             STORABLE_freeze(self, cloning = NULL)
856             Math::BigInt::LTM self
857             SV *cloning = NO_INIT
858             PREINIT:
859             mp_err merr;
860             unsigned long len;
861             char *buf;
862             CODE:
863             PERL_UNUSED_VAR(cloning);
864 1 50         if (mp_iszero(self) == MP_YES) {
865 0           RETVAL = newSVpv("0", 0);
866             }
867             else {
868 1           len = mp_count_bits(self) / 3 + 3; /* decimal_size ~ (binary_size/3 + 1) +1 for sign +1 for NUL-byte */
869 1           Newz(0, buf, len, char);
870 1           merr = mp_to_radix(self, buf, len, NULL, 10);
871             PERL_UNUSED_VAR(merr);
872 1           RETVAL = newSVpv(buf, 0);
873 1           Safefree(buf);
874             }
875             OUTPUT:
876             RETVAL