CryptX
view release on metacpan or search on metacpan
inc/CryptX_BigInt_LTM.xs.inc view on Meta::CPAN
mp_err merr;
CODE:
Newz(0, RETVAL, 1, mp_int);
merr = mp_init(RETVAL);
mp_set_u32(RETVAL, 1);
PERL_UNUSED_VAR(merr);
OUTPUT:
RETVAL
##############################################################################
# _two()
Math::BigInt::LTM
_two(Class)
PREINIT:
mp_err merr;
CODE:
Newz(0, RETVAL, 1, mp_int);
merr = mp_init(RETVAL);
mp_set_u32(RETVAL, 2);
PERL_UNUSED_VAR(merr);
OUTPUT:
RETVAL
##############################################################################
# _ten()
Math::BigInt::LTM
_ten(Class)
PREINIT:
mp_err merr;
CODE:
Newz(0, RETVAL, 1, mp_int);
merr = mp_init(RETVAL);
mp_set_u32(RETVAL, 10);
PERL_UNUSED_VAR(merr);
OUTPUT:
RETVAL
##############################################################################
# _1ex()
Math::BigInt::LTM
_1ex(Class, int x)
PREINIT:
mp_err merr;
CODE:
Newz(0, RETVAL, 1, mp_int);
merr = mp_init(RETVAL);
mp_set_u32(RETVAL, 10);
merr = mp_expt_n(RETVAL, x, RETVAL);
PERL_UNUSED_VAR(merr);
OUTPUT:
RETVAL
##############################################################################
# DESTROY() - free memory of a GMP number
void
DESTROY(Math::BigInt::LTM n)
PPCODE:
if (n) {
mp_clear(n);
Safefree(n);
}
##############################################################################
# _str() - return string so that atof() and atoi() can use it
SV *
_str(Class, Math::BigInt::LTM n)
PREINIT:
mp_err merr;
int len;
char *buf;
CODE:
if (mp_iszero(n) == MP_YES) {
RETVAL = newSVpv("0", 0);
}
else {
len = mp_count_bits(n) / 3 + 3; /* decimal_size ~ (binary_size/3 + 1) +1 for sign +1 for NUL-byte */
Newz(0, buf, len, char);
merr = mp_to_radix(n, buf, len, NULL, 10);
RETVAL = newSVpv(buf, 0);
Safefree(buf);
}
PERL_UNUSED_VAR(merr);
OUTPUT:
RETVAL
##############################################################################
# _len() - return the length of the number in base 10 (costly)
int
_len(Class, Math::BigInt::LTM n)
PREINIT:
mp_err merr;
int len;
char *buf;
CODE:
if (mp_iszero(n) == MP_YES) {
RETVAL = 1;
}
else {
len = mp_count_bits(n) / 3 + 3; /* decimal_size ~ (binary_size/3 + 1) +1 for sign +1 for NUL-byte */
Newz(0, buf, len, char);
merr = mp_to_radix(n, buf, len, NULL, 10);
RETVAL = (int)strlen(buf);
Safefree(buf);
}
PERL_UNUSED_VAR(merr);
OUTPUT:
RETVAL
##############################################################################
# _alen() - return the approx. length of the number in base 10 (fast)
# _alen() might underestimate, but never overestimate the true value
int
_alen(Class, Math::BigInt::LTM n)
PREINIT:
inc/CryptX_BigInt_LTM.xs.inc view on Meta::CPAN
SV *
_to_bytes(Class, Math::BigInt::LTM n)
ALIAS:
_as_bytes = 1
PREINIT:
mp_err merr;
size_t len;
unsigned char *buf;
CODE:
PERL_UNUSED_VAR(ix);
len = mp_ubin_size(n);
if (len > 0) {
RETVAL = newSV(len);
SvPOK_on(RETVAL);
buf = (unsigned char*)SvPVX(RETVAL);
merr = mp_to_ubin(n, buf, len, NULL);
SvCUR_set(RETVAL, len);
}
else {
RETVAL = newSV(1);
SvPOK_on(RETVAL);
buf = (unsigned char*)SvPVX(RETVAL);
buf[0] = 0;
SvCUR_set(RETVAL, 1);
}
PERL_UNUSED_VAR(merr);
OUTPUT:
RETVAL
##############################################################################
# _modpow() - ($n ** $exp) % $mod
Math::BigInt::LTM
_modpow(Class, Math::BigInt::LTM n, Math::BigInt::LTM exp, Math::BigInt::LTM mod)
PREINIT:
mp_err merr;
CODE:
Newz(0, RETVAL, 1, mp_int);
merr = mp_init(RETVAL);
if (mp_cmp_d(mod, 1) == MP_EQ) {
mp_zero(RETVAL);
}
else {
merr = mp_exptmod(n, exp, mod, RETVAL);
}
PERL_UNUSED_VAR(merr);
OUTPUT:
RETVAL
##############################################################################
# _modinv() - compute the inverse of x % y
void
_modinv(Class, Math::BigInt::LTM x, Math::BigInt::LTM y)
PREINIT:
mp_err merr;
int rc;
SV* s;
mp_int* RETVAL;
PPCODE:
Newz(0, RETVAL, 1, mp_int);
merr = mp_init(RETVAL);
rc = mp_invmod(x, y, RETVAL);
EXTEND(SP, 2); /* we return two values */
if (rc != MP_OKAY) {
/* Inverse doesn't exist. Return both values undefined. */
PUSHs(&PL_sv_undef);
PUSHs(&PL_sv_undef);
}
else {
/* Inverse exists. When the modulus to mp_invert() is positive,
* the returned value is also positive. */
PUSHs(sv_2mortal(sv_from_mpi(RETVAL)));
s = sv_newmortal();
sv_setpvn(s, "+", 1);
PUSHs(s);
}
PERL_UNUSED_VAR(merr);
##############################################################################
# _add() - add $y to $x in place
void
_add(Class, Math::BigInt::LTM x, Math::BigInt::LTM y)
PREINIT:
mp_err merr;
PPCODE:
merr = mp_add(x, y, x);
PERL_UNUSED_VAR(merr);
XPUSHs(ST(1)); /* x */
##############################################################################
# _inc() - modify x inline by doing x++
void
_inc(Class, Math::BigInt::LTM x)
PREINIT:
mp_err merr;
PPCODE:
merr = mp_add_d(x, 1, x);
PERL_UNUSED_VAR(merr);
XPUSHs(ST(1)); /* x */
##############################################################################
# _dec() - modify x inline by doing x--
void
_dec(Class, Math::BigInt::LTM x)
PREINIT:
mp_err merr;
PPCODE:
merr = mp_sub_d(x, 1, x);
PERL_UNUSED_VAR(merr);
XPUSHs(ST(1)); /* x */
##############################################################################
# _sub() - $x - $y
# $x is always larger than $y! So overflow/underflow can not happen here.
void
_sub(Class, Math::BigInt::LTM x, Math::BigInt::LTM y, ...)
PREINIT:
mp_err merr;
PPCODE:
if ( items == 4 && SvTRUE(ST(3)) ) {
/* y -= x */
merr = mp_sub(x, y, y);
XPUSHs(ST(2)); /* y */
}
else {
/* x -= y */
merr = mp_sub(x, y, x);
XPUSHs(ST(1)); /* x */
}
PERL_UNUSED_VAR(merr);
##############################################################################
# _rsft()
void
_rsft(Class, Math::BigInt::LTM x, Math::BigInt::LTM y, unsigned long base_int)
PREINIT:
mp_err merr;
mp_int* BASE;
PPCODE:
Newz(0, BASE, 1, mp_int);
merr = mp_init(BASE);
mp_set_ul(BASE, base_int);
merr = mp_expt_n(BASE, mp_get_l(y), BASE);
merr = mp_div(x, BASE, x, NULL);
PERL_UNUSED_VAR(merr);
mp_clear(BASE);
Safefree(BASE);
XPUSHs(ST(1)); /* x */
##############################################################################
# _lsft()
void
_lsft(Class, Math::BigInt::LTM x, Math::BigInt::LTM y, unsigned long base_int)
PREINIT:
mp_err merr;
mp_int* BASE;
PPCODE:
Newz(0, BASE, 1, mp_int);
merr = mp_init(BASE);
mp_set_ul(BASE, base_int);
merr = mp_expt_n(BASE, mp_get_l(y), BASE);
merr = mp_mul(x, BASE, x);
PERL_UNUSED_VAR(merr);
mp_clear(BASE);
Safefree(BASE);
XPUSHs(ST(1)); /* x */
##############################################################################
# _mul()
void
_mul(Class, Math::BigInt::LTM x, Math::BigInt::LTM y)
PREINIT:
mp_err merr;
PPCODE:
merr = mp_mul(x, y, x);
PERL_UNUSED_VAR(merr);
XPUSHs(ST(1)); /* x */
##############################################################################
# _div(): x /= y or (x,rem) = x / y
void
_div(Class, Math::BigInt::LTM x, Math::BigInt::LTM y)
PREINIT:
mp_err merr;
mp_int * rem;
PPCODE:
if (GIMME_V == G_ARRAY) {
Newz(0, rem, 1, mp_int);
merr = mp_init(rem);
merr = mp_div(x, y, x, rem);
EXTEND(SP, 2);
PUSHs(ST(1)); /* x */
PUSHs(sv_2mortal(sv_from_mpi(rem)));
}
else {
merr = mp_div(x, y, x, NULL);
XPUSHs(ST(1)); /* x */
}
PERL_UNUSED_VAR(merr);
##############################################################################
# _mod() - x %= y
void
_mod(Class, Math::BigInt::LTM x, Math::BigInt::LTM y)
PREINIT:
mp_err merr;
PPCODE:
merr = mp_mod(x, y, x);
PERL_UNUSED_VAR(merr);
XPUSHs(ST(1)); /* x */
##############################################################################
# _acmp() - cmp two numbers
int
_acmp(Class, Math::BigInt::LTM m, Math::BigInt::LTM n)
CODE:
RETVAL = mp_cmp(m, n);
if ( RETVAL < 0) RETVAL = -1;
if ( RETVAL > 0) RETVAL = 1;
OUTPUT:
RETVAL
##############################################################################
# _is_zero()
int
_is_zero(Class, Math::BigInt::LTM x)
CODE:
RETVAL = (mp_iszero(x) == MP_YES) ? 1 : 0;
OUTPUT:
RETVAL
##############################################################################
# _is_one()
int
_is_one(Class, Math::BigInt::LTM x)
CODE:
RETVAL = (mp_cmp_d(x, 1) == MP_EQ) ? 1 : 0;
OUTPUT:
RETVAL
##############################################################################
# _is_two()
int
_is_two(Class, Math::BigInt::LTM x)
CODE:
RETVAL = (mp_cmp_d(x, 2) == MP_EQ) ? 1 : 0;
OUTPUT:
RETVAL
##############################################################################
# _is_ten()
int
_is_ten(Class, Math::BigInt::LTM x)
CODE:
RETVAL = (mp_cmp_d(x, 10) == MP_EQ) ? 1 : 0;
OUTPUT:
RETVAL
##############################################################################
# _pow() - x **= y
void
_pow(Class, Math::BigInt::LTM x, Math::BigInt::LTM y)
PREINIT:
mp_err merr;
PPCODE:
merr = mp_expt_n(x, mp_get_l(y), x);
PERL_UNUSED_VAR(merr);
XPUSHs(ST(1)); /* x */
##############################################################################
# _gcd() - gcd(m,n)
Math::BigInt::LTM
_gcd(Class, Math::BigInt::LTM x, Math::BigInt::LTM y)
PREINIT:
mp_err merr;
CODE:
Newz(0, RETVAL, 1, mp_int);
merr = mp_init(RETVAL);
merr = mp_gcd(x, y, RETVAL);
PERL_UNUSED_VAR(merr);
OUTPUT:
RETVAL
##############################################################################
# _and() - m &= n
void
_and(Class, Math::BigInt::LTM x, Math::BigInt::LTM y)
PREINIT:
mp_err merr;
PPCODE:
merr = mp_and(x, y, x);
PERL_UNUSED_VAR(merr);
XPUSHs(ST(1)); /* x */
##############################################################################
# _xor() - m =^ n
void
_xor(Class, Math::BigInt::LTM x, Math::BigInt::LTM y)
PREINIT:
mp_err merr;
PPCODE:
merr = mp_xor(x, y, x);
PERL_UNUSED_VAR(merr);
XPUSHs(ST(1)); /* x */
##############################################################################
# _or() - m =| n
void
_or(Class, Math::BigInt::LTM x, Math::BigInt::LTM y)
PREINIT:
mp_err merr;
PPCODE:
merr = mp_or(x, y, x);
PERL_UNUSED_VAR(merr);
XPUSHs(ST(1)); /* x */
##############################################################################
# _copy()
Math::BigInt::LTM
_copy(Class, Math::BigInt::LTM m)
PREINIT:
mp_err merr;
CODE:
Newz(0, RETVAL, 1, mp_int);
merr = mp_init(RETVAL);
merr = mp_copy(m, RETVAL);
PERL_UNUSED_VAR(merr);
OUTPUT:
RETVAL
##############################################################################
# _is_odd() - test for number being odd
int
_is_odd(Class, Math::BigInt::LTM n)
CODE:
RETVAL = (mp_isodd(n) == MP_YES) ? 1 : 0;
OUTPUT:
RETVAL
##############################################################################
# _is_even() - test for number being even
int
_is_even(Class, Math::BigInt::LTM n)
CODE:
RETVAL = (mp_iseven(n) == MP_YES || mp_iszero(n) == MP_YES) ? 1 : 0;
OUTPUT:
RETVAL
##############################################################################
# _sqrt() - square root
void
_sqrt(Class, Math::BigInt::LTM x)
PREINIT:
mp_err merr;
PPCODE:
merr = mp_sqrt(x, x);
PERL_UNUSED_VAR(merr);
XPUSHs(ST(1)); /* x */
##############################################################################
# _root() - integer roots
void
_root(Class, Math::BigInt::LTM x, Math::BigInt::LTM y)
PREINIT:
mp_err merr;
PPCODE:
merr = mp_root_n(x, mp_get_l(y), x);
PERL_UNUSED_VAR(merr);
XPUSHs(ST(1)); /* x */
##############################################################################
# _lcm() - least common multiple
void
_lcm(Class, Math::BigInt::LTM x, Math::BigInt::LTM y)
PREINIT:
mp_err merr;
PPCODE:
merr = mp_lcm(x, y, x) ;
PERL_UNUSED_VAR(merr);
XPUSHs(ST(1)); /* x */
##############################################################################
# Storable hooks
void
STORABLE_thaw(blank_obj, cloning, serialized, ...)
SV *blank_obj
SV *cloning = NO_INIT
SV *serialized
PREINIT:
mp_err merr;
SV *target;
mp_int *mpi;
PPCODE:
PERL_UNUSED_VAR(cloning);
if (SvROK(blank_obj) && sv_isa(blank_obj, "Math::BigInt::LTM")) {
Newz(0, mpi, 1, mp_int);
merr = mp_init(mpi);
merr = mp_read_radix(mpi, SvPV_nolen(serialized), 10);
PERL_UNUSED_VAR(merr);
target = SvRV(blank_obj);
SvIV_set(target, PTR2IV(mpi));
SvIOK_on(target);
PUSHs(target);
XSRETURN(1);
}
else
croak("Bad object for Math::BigInt::LTM::STORABLE_thaw call");
SV *
STORABLE_freeze(self, cloning = NULL)
Math::BigInt::LTM self
SV *cloning = NO_INIT
PREINIT:
mp_err merr;
unsigned long len;
char *buf;
CODE:
PERL_UNUSED_VAR(cloning);
if (mp_iszero(self) == MP_YES) {
RETVAL = newSVpv("0", 0);
}
else {
len = mp_count_bits(self) / 3 + 3; /* decimal_size ~ (binary_size/3 + 1) +1 for sign +1 for NUL-byte */
Newz(0, buf, len, char);
merr = mp_to_radix(self, buf, len, NULL, 10);
PERL_UNUSED_VAR(merr);
RETVAL = newSVpv(buf, 0);
Safefree(buf);
}
OUTPUT:
RETVAL
( run in 0.889 second using v1.01-cache-2.11-cpan-71847e10f99 )