gmp.xs
来自「a very popular packet of cryptography to」· XS 代码 · 共 2,874 行 · 第 1/5 页
XS
2,874 行
break; case USE_MPQ: RETVAL = x_mpz_cmp_q (x->m, SvMPQ(yv)->m); break; case USE_MPF: RETVAL = x_mpz_cmp_f (x->m, SvMPF(yv)); break; default: croak ("%s <=>: invalid operand", mpz_class); } RETVAL = SGN (RETVAL); if (order == &PL_sv_yes) RETVAL = -RETVAL;OUTPUT: RETVALbooloverload_bool (z, d1, d2) mpz_assume z dummy d1 dummy d2ALIAS: GMP::Mpz::overload_not = 1CODE: RETVAL = (mpz_sgn (z->m) != 0) ^ ix;OUTPUT: RETVALmpzbin (n, k) mpz_coerce n ulong_coerce kALIAS: GMP::Mpz::root = 1PREINIT: /* mpz_root returns an int, hence the cast */ static_functable const struct { void (*op) (mpz_ptr, mpz_srcptr, unsigned long); } table[] = { { mpz_bin_ui }, /* 0 */ { (void (*)(mpz_ptr, mpz_srcptr, unsigned long)) mpz_root }, /* 1 */ };CODE: assert_table (ix); RETVAL = new_mpz(); (*table[ix].op) (RETVAL->m, n, k);OUTPUT: RETVALvoidcdiv (a, d) mpz_coerce a mpz_coerce dALIAS: GMP::Mpz::fdiv = 1 GMP::Mpz::tdiv = 2PREINIT: static_functable const struct { void (*op) (mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr); } table[] = { { mpz_cdiv_qr }, /* 0 */ { mpz_fdiv_qr }, /* 1 */ { mpz_tdiv_qr }, /* 2 */ }; mpz q, r;PPCODE: assert_table (ix); q = new_mpz(); r = new_mpz(); (*table[ix].op) (q->m, r->m, a, d); EXTEND (SP, 2); PUSHs (MPX_NEWMORTAL (q, mpz_class_hv)); PUSHs (MPX_NEWMORTAL (r, mpz_class_hv));voidcdiv_2exp (a, d) mpz_coerce a ulong_coerce dALIAS: GMP::Mpz::fdiv_2exp = 1 GMP::Mpz::tdiv_2exp = 2PREINIT: static_functable const struct { void (*q) (mpz_ptr, mpz_srcptr, unsigned long); void (*r) (mpz_ptr, mpz_srcptr, unsigned long); } table[] = { { mpz_cdiv_q_2exp, mpz_cdiv_r_2exp }, /* 0 */ { mpz_fdiv_q_2exp, mpz_fdiv_r_2exp }, /* 1 */ { mpz_tdiv_q_2exp, mpz_tdiv_r_2exp }, /* 2 */ }; mpz q, r;PPCODE: assert_table (ix); q = new_mpz(); r = new_mpz(); (*table[ix].q) (q->m, a, d); (*table[ix].r) (r->m, a, d); EXTEND (SP, 2); PUSHs (MPX_NEWMORTAL (q, mpz_class_hv)); PUSHs (MPX_NEWMORTAL (r, mpz_class_hv));boolcongruent_p (a, c, d) mpz_coerce a mpz_coerce c mpz_coerce dPREINIT:CODE: RETVAL = mpz_congruent_p (a, c, d);OUTPUT: RETVALboolcongruent_2exp_p (a, c, d) mpz_coerce a mpz_coerce c ulong_coerce dPREINIT:CODE: RETVAL = mpz_congruent_2exp_p (a, c, d);OUTPUT: RETVALmpzdivexact (a, d) mpz_coerce a mpz_coerce dALIAS: GMP::Mpz::mod = 1PREINIT: static_functable const struct { void (*op) (mpz_ptr, mpz_srcptr, mpz_srcptr); } table[] = { { mpz_divexact }, /* 0 */ { mpz_mod }, /* 1 */ };CODE: assert_table (ix); RETVAL = new_mpz(); (*table[ix].op) (RETVAL->m, a, d);OUTPUT: RETVALbooldivisible_p (a, d) mpz_coerce a mpz_coerce dCODE: RETVAL = mpz_divisible_p (a, d);OUTPUT: RETVALbooldivisible_2exp_p (a, d) mpz_coerce a ulong_coerce dCODE: RETVAL = mpz_divisible_2exp_p (a, d);OUTPUT: RETVALbooleven_p (z) mpz_coerce zALIAS: GMP::Mpz::odd_p = 1 GMP::Mpz::perfect_square_p = 2 GMP::Mpz::perfect_power_p = 3PREINIT: static_functable const struct { int (*op) (mpz_srcptr z); } table[] = { { x_mpz_even_p }, /* 0 */ { x_mpz_odd_p }, /* 1 */ { mpz_perfect_square_p }, /* 2 */ { mpz_perfect_power_p }, /* 3 */ };CODE: assert_table (ix); RETVAL = (*table[ix].op) (z);OUTPUT: RETVALmpzfac (n) ulong_coerce nALIAS: GMP::Mpz::fib = 1 GMP::Mpz::lucnum = 2PREINIT: static_functable const struct { void (*op) (mpz_ptr r, unsigned long n); } table[] = { { mpz_fac_ui }, /* 0 */ { mpz_fib_ui }, /* 1 */ { mpz_lucnum_ui }, /* 2 */ };CODE: assert_table (ix); RETVAL = new_mpz(); (*table[ix].op) (RETVAL->m, n);OUTPUT: RETVALvoidfib2 (n) ulong_coerce nALIAS: GMP::Mpz::lucnum2 = 1PREINIT: static_functable const struct { void (*op) (mpz_ptr r, mpz_ptr r2, unsigned long n); } table[] = { { mpz_fib2_ui }, /* 0 */ { mpz_lucnum2_ui }, /* 1 */ }; mpz r, r2;PPCODE: assert_table (ix); r = new_mpz(); r2 = new_mpz(); (*table[ix].op) (r->m, r2->m, n); EXTEND (SP, 2); PUSHs (MPX_NEWMORTAL (r, mpz_class_hv)); PUSHs (MPX_NEWMORTAL (r2, mpz_class_hv));mpzgcd (x, ...) mpz_coerce xALIAS: GMP::Mpz::lcm = 1PREINIT: static_functable const struct { void (*op) (mpz_ptr w, mpz_srcptr x, mpz_srcptr y); void (*op_ui) (mpz_ptr w, mpz_srcptr x, unsigned long y); } table[] = { /* cast to ignore ulong return from mpz_gcd_ui */ { mpz_gcd, (void (*) (mpz_ptr, mpz_srcptr, unsigned long)) mpz_gcd_ui }, /* 0 */ { mpz_lcm, mpz_lcm_ui }, /* 1 */ }; int i; SV *yv;CODE: assert_table (ix); RETVAL = new_mpz(); if (items == 1) mpz_set (RETVAL->m, x); else { for (i = 1; i < items; i++) { yv = ST(i); if (SvIOK(yv)) (*table[ix].op_ui) (RETVAL->m, x, ABS(SvIVX(yv))); else (*table[ix].op) (RETVAL->m, x, coerce_mpz (tmp_mpz_1, yv)); x = RETVAL->m; } }OUTPUT: RETVALvoidgcdext (a, b) mpz_coerce a mpz_coerce bPREINIT: mpz g, x, y; SV *sv;PPCODE: g = new_mpz(); x = new_mpz(); y = new_mpz(); mpz_gcdext (g->m, x->m, y->m, a, b); EXTEND (SP, 3); PUSHs (MPX_NEWMORTAL (g, mpz_class_hv)); PUSHs (MPX_NEWMORTAL (x, mpz_class_hv)); PUSHs (MPX_NEWMORTAL (y, mpz_class_hv));unsigned longhamdist (x, y) mpz_coerce x mpz_coerce yCODE: RETVAL = mpz_hamdist (x, y);OUTPUT: RETVALmpzinvert (a, m) mpz_coerce a mpz_coerce mCODE: RETVAL = new_mpz(); if (! mpz_invert (RETVAL->m, a, m)) { free_mpz (RETVAL); XSRETURN_UNDEF; }OUTPUT: RETVALintjacobi (a, b) mpz_coerce a mpz_coerce bCODE: RETVAL = mpz_jacobi (a, b);OUTPUT: RETVALintkronecker (a, b) SV *a SV *bCODE: if (SvIOK(b)) RETVAL = mpz_kronecker_si (coerce_mpz(tmp_mpz_0,a), SvIVX(b)); else if (SvIOK(a)) RETVAL = mpz_si_kronecker (SvIVX(a), coerce_mpz(tmp_mpz_0,b)); else RETVAL = mpz_kronecker (coerce_mpz(tmp_mpz_0,a), coerce_mpz(tmp_mpz_1,b));OUTPUT: RETVALvoidmpz_export (order, size, endian, nails, z) int order size_t size int endian size_t nails mpz_coerce zPREINIT: size_t numb, count, bytes, actual_count; char *data; SV *sv;PPCODE: numb = 8*size - nails; count = (mpz_sizeinbase (z, 2) + numb-1) / numb; bytes = count * size; New (GMP_MALLOC_ID, data, bytes+1, char); mpz_export (data, &actual_count, order, size, endian, nails, z); assert (count == actual_count); data[bytes] = '\0'; sv = sv_newmortal(); sv_usepvn_mg (sv, data, bytes); PUSHs(sv);mpzmpz_import (order, size, endian, nails, sv) int order size_t size int endian size_t nails SV *svPREINIT: size_t count; const char *data; STRLEN len;CODE: data = SvPV (sv, len); if ((len % size) != 0) croak ("%s mpz_import: string not a multiple of the given size", mpz_class); count = len / size; RETVAL = new_mpz(); mpz_import (RETVAL->m, count, order, size, endian, nails, data);OUTPUT: RETVALmpznextprime (z) mpz_coerce zCODE: RETVAL = new_mpz(); mpz_nextprime (RETVAL->m, z);OUTPUT: RETVALunsigned longpopcount (x) mpz_coerce xCODE: RETVAL = mpz_popcount (x);OUTPUT: RETVALmpzpowm (b, e, m) mpz_coerce b mpz_coerce e mpz_coerce mCODE: RETVAL = new_mpz(); mpz_powm (RETVAL->m, b, e, m);OUTPUT: RETVALboolprobab_prime_p (z, n) mpz_coerce z ulong_coerce nCODE: RETVAL = mpz_probab_prime_p (z, n);OUTPUT: RETVAL# No attempt to coerce here, only an mpz makes sense.voidrealloc (z, limbs) mpz z int limbsCODE: _mpz_realloc (z->m, limbs);voidremove (z, f) mpz_coerce z mpz_coerce fPREINIT: SV *sv; mpz rem; unsigned long mult;PPCODE: rem = new_mpz(); mult = mpz_remove (rem->m, z, f); EXTEND (SP, 2); PUSHs (MPX_NEWMORTAL (rem, mpz_class_hv)); PUSHs (sv_2mortal (newSViv (mult)));voidroote (z, n) mpz_coerce z ulong_coerce nPREINIT: SV *sv; mpz root; int exact;PPCODE: root = new_mpz(); exact = mpz_root (root->m, z, n); EXTEND (SP, 2); PUSHs (MPX_NEWMORTAL (root, mpz_class_hv)); sv = (exact ? &PL_sv_yes : &PL_sv_no); sv_2mortal(sv); PUSHs(sv);# In the past scan0 and scan1 were described as returning ULONG_MAX which# could be obtained in perl with ~0. That wasn't true on 64-bit systems# (eg. alpha) with perl 5.005, since in that version IV and UV were still# 32-bits.## We changed in gmp 4.1.3 to just say ~0 for the not-found return. It's# likely most people have used ~0 rather than POSIX::ULONG_MAX(), so this# change should match existing usage. It only actually makes a difference# in old perl, since recent versions have gone to 64-bits for IV and UV, the# same as a ulong.## In perl 5.005 we explicitly mask the mpz return down to 32-bits to get ~0.# UV_MAX is no good, it reflects the size of the UV type (64-bits), rather# than the size of the values one ought to be storing in an SV (32-bits).gmp_UVscan0 (z, start) mpz_coerce z ulong_coerce startALIAS: GMP::Mpz::scan1 = 1PREINIT: static_functable const struct { unsigned long (*op) (mpz_srcptr, unsigned long); } table[] = { { mpz_scan0 }, /* 0 */ { mpz_scan1 }, /* 1 */ };CODE: assert_table (ix); RETVAL = (*table[ix].op) (z, start); if (PERL_LT (5,6)) RETVAL &= 0xFFFFFFFF;OUTPUT: RETVALvoidsetbit (sv, bit) SV *sv ulong_coerce bitALIAS: GMP::Mpz::clrbit = 1PREINIT: static_functable const struct { void (*op) (mpz_ptr, unsigned long); } table[] = { { mpz_setbit }, /* 0 */ { mpz_clrbit }, /* 1 */ }; int use; mpz z;CODE: use = use_sv (sv); if (use == USE_MPZ && SvREFCNT(SvRV(sv)) == 1 && ! SvSMAGICAL(sv)) { /* our operand is a non-magical mpz with a reference count of 1, so we can just modify it */ (*table[ix].op) (SvMPZ(sv)->m, bit); } else { /* otherwise we need to make a new mpz, from whatever we have, and operate on that, possibly invoking magic when storing back */ SV *new_sv; mpz z = new_mpz (); mpz_ptr coerce_ptr = coerce_mpz_using (z->m, sv, use); if (coerce_ptr != z->m) mpz_set (z->m, coerce_ptr); (*table[ix].op) (z->m, bit); new_sv = sv_bless (sv_setref_pv (sv_newmortal(), NULL, z), mpz_class_hv); SvSetMagicSV (sv, new_sv); }voidsqrtrem (z) mpz_coerce zPREINIT: SV *sv; mpz root; mpz rem;PPCODE: root = new_mpz(); rem = new_mpz(); mpz_sqrtrem (root->m, rem->m, z); EXTEND (SP, 2); PUSHs (MPX_NEWMORTAL (root, mpz_class_hv)); PUSHs (MPX_NEWMORTAL (rem, mpz_class_hv));size_tsizeinbase (z, base) mpz_coerce z int baseCODE: RETVAL = mpz_sizeinbase (z, base);OUTPUT: RETVAL
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?