File Coverage

inc/CryptX_BigInt_LTM.xs.inc
Criterion Covered Total %
statement 173 214 80.8
branch 85 172 49.4
condition n/a
subroutine n/a
pod n/a
total 258 386 66.8


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