gmp.xs
来自「a very popular packet of cryptography to」· XS 代码 · 共 2,874 行 · 第 1/5 页
XS
2,874 行
break; case USE_MPF: RETVAL = mpf_get_si (SvMPF(sv)); break; default: croak ("GMP::get_si invalid argument"); }OUTPUT: RETVALvoidget_str (sv, ...) SV *svPREINIT: char *str; mp_exp_t exp; mpz_ptr z; mpq_ptr q; mpf f; int base; int ndigits;PPCODE: TRACE (printf ("GMP::get_str\n")); if (items >= 2) base = coerce_long (ST(1)); else base = 10; TRACE (printf (" base=%d\n", base)); if (items >= 3) ndigits = coerce_long (ST(2)); else ndigits = 10; TRACE (printf (" ndigits=%d\n", ndigits)); EXTEND (SP, 2); switch (use_sv (sv)) { case USE_IVX: mpz_set_si (tmp_mpz_0, SvIVX(sv)); get_tmp_mpz_0: z = tmp_mpz_0; goto get_mpz; case USE_UVX: mpz_set_ui (tmp_mpz_0, SvUVX(sv)); goto get_tmp_mpz_0; case USE_NVX: /* only digits in the original double, not in the coerced form */ if (ndigits == 0) ndigits = DBL_DIG; mpf_set_d (tmp_mpf_0->m, SvNVX(sv)); f = tmp_mpf_0->m; goto get_mpf; case USE_PVX: { /* get_str on a string is not much more than a base conversion */ STRLEN len; str = SvPV (sv, len); if (mpz_set_str (tmp_mpz_0, str, 0) == 0) { z = tmp_mpz_0; goto get_mpz; } else if (mpq_set_str (tmp_mpq_0, str, 0) == 0) { q = tmp_mpq_0; goto get_mpq; } else { /* FIXME: Would like perhaps a precision equivalent to the number of significant digits of the string, in its given base. */ tmp_mpf_set_prec (tmp_mpf_0, strlen(str)); if (mpf_set_str (tmp_mpf_0->m, str, 10) == 0) { f = tmp_mpf_0->m; goto get_mpf; } else croak ("GMP::get_str invalid string format"); } } break; case USE_MPZ: z = SvMPZ(sv)->m; get_mpz: str = mpz_get_str (NULL, base, z); push_str: PUSHs (sv_2mortal (newSVpv (str, 0))); break; case USE_MPQ: q = SvMPQ(sv)->m; get_mpq: str = mpq_get_str (NULL, base, q); goto push_str; case USE_MPF: f = SvMPF(sv); get_mpf: str = mpf_get_str (NULL, &exp, base, 0, f); PUSHs (sv_2mortal (newSVpv (str, 0))); PUSHs (sv_2mortal (newSViv (exp))); break; default: croak ("GMP::get_str invalid argument"); }boolinteger_p (sv) SV *svCODE: switch (use_sv (sv)) { case USE_IVX: case USE_UVX: RETVAL = 1; break; case USE_NVX: RETVAL = double_integer_p (SvNVX(sv)); break; case USE_PVX: { /* FIXME: Maybe this should be done by parsing the string, not by an actual conversion. */ STRLEN len; const char *str = SvPV (sv, len); if (mpq_set_str (tmp_mpq_0, str, 0) == 0) RETVAL = x_mpq_integer_p (tmp_mpq_0); else { /* enough for all digits of the string */ tmp_mpf_set_prec (tmp_mpf_0, strlen(str)+64); if (mpf_set_str (tmp_mpf_0->m, str, 10) == 0) RETVAL = mpf_integer_p (tmp_mpf_0->m); else croak ("GMP::integer_p invalid string format"); } } break; case USE_MPZ: RETVAL = 1; break; case USE_MPQ: RETVAL = x_mpq_integer_p (SvMPQ(sv)->m); break; case USE_MPF: RETVAL = mpf_integer_p (SvMPF(sv)); break; default: croak ("GMP::integer_p invalid argument"); }OUTPUT: RETVALintsgn (sv) SV *svCODE: switch (use_sv (sv)) { case USE_IVX: RETVAL = SGN (SvIVX(sv)); break; case USE_UVX: RETVAL = (SvUVX(sv) > 0); break; case USE_NVX: RETVAL = SGN (SvNVX(sv)); break; case USE_PVX: { /* FIXME: Maybe this should be done by parsing the string, not by an actual conversion. */ STRLEN len; const char *str = SvPV (sv, len); if (mpq_set_str (tmp_mpq_0, str, 0) == 0) RETVAL = mpq_sgn (tmp_mpq_0); else { /* enough for all digits of the string */ tmp_mpf_set_prec (tmp_mpf_0, strlen(str)+64); if (mpf_set_str (tmp_mpf_0->m, str, 10) == 0) RETVAL = mpf_sgn (tmp_mpf_0->m); else croak ("GMP::sgn invalid string format"); } } break; case USE_MPZ: RETVAL = mpz_sgn (SvMPZ(sv)->m); break; case USE_MPQ: RETVAL = mpq_sgn (SvMPQ(sv)->m); break; case USE_MPF: RETVAL = mpf_sgn (SvMPF(sv)); break; default: croak ("GMP::sgn invalid argument"); }OUTPUT: RETVAL# currently undocumentedvoidshrink ()CODE:#define x_mpz_shrink(z) \ mpz_set_ui (z, 0L); _mpz_realloc (z, 1)#define x_mpq_shrink(q) \ x_mpz_shrink (mpq_numref(q)); x_mpz_shrink (mpq_denref(q)) x_mpz_shrink (tmp_mpz_0); x_mpz_shrink (tmp_mpz_1); x_mpz_shrink (tmp_mpz_2); x_mpq_shrink (tmp_mpq_0); x_mpq_shrink (tmp_mpq_1); tmp_mpf_shrink (tmp_mpf_0); tmp_mpf_shrink (tmp_mpf_1);malloced_stringsprintf_internal (fmt, sv) const_string fmt SV *svCODE: assert (strlen (fmt) >= 3); assert (SvROK(sv)); assert ((sv_derived_from (sv, mpz_class) && fmt[strlen(fmt)-2] == 'Z') || (sv_derived_from (sv, mpq_class) && fmt[strlen(fmt)-2] == 'Q') || (sv_derived_from (sv, mpf_class) && fmt[strlen(fmt)-2] == 'F')); TRACE (printf ("GMP::sprintf_internal\n"); printf (" fmt |%s|\n", fmt); printf (" sv |%p|\n", SvMPZ(sv))); /* cheat a bit here, SvMPZ works for mpq and mpf too */ gmp_asprintf (&RETVAL, fmt, SvMPZ(sv)); TRACE (printf (" result |%s|\n", RETVAL));OUTPUT: RETVAL#------------------------------------------------------------------------------MODULE = GMP PACKAGE = GMP::Mpzmpzmpz (...)ALIAS: GMP::Mpz::new = 1PREINIT: SV *sv;CODE: TRACE (printf ("%s new, ix=%ld, items=%d\n", mpz_class, ix, (int) items)); RETVAL = new_mpz(); switch (items) { case 0: mpz_set_ui (RETVAL->m, 0L); break; case 1: sv = ST(0); TRACE (printf (" use %d\n", use_sv (sv))); switch (use_sv (sv)) { case USE_IVX: mpz_set_si (RETVAL->m, SvIVX(sv)); break; case USE_UVX: mpz_set_ui (RETVAL->m, SvUVX(sv)); break; case USE_NVX: mpz_set_d (RETVAL->m, SvNVX(sv)); break; case USE_PVX: my_mpz_set_svstr (RETVAL->m, sv); break; case USE_MPZ: mpz_set (RETVAL->m, SvMPZ(sv)->m); break; case USE_MPQ: mpz_set_q (RETVAL->m, SvMPQ(sv)->m); break; case USE_MPF: mpz_set_f (RETVAL->m, SvMPF(sv)); break; default: goto invalid; } break; default: invalid: croak ("%s new: invalid arguments", mpz_class); }OUTPUT: RETVALvoidoverload_constant (str, pv, d1, ...) const_string_assume str SV *pv dummy d1PREINIT: mpz z;PPCODE: TRACE (printf ("%s constant: %s\n", mpz_class, str)); z = new_mpz(); if (mpz_set_str (z->m, str, 0) == 0) { PUSHs (MPX_NEWMORTAL (z, mpz_class_hv)); } else { free_mpz (z); PUSHs(pv); }mpzoverload_copy (z, d1, d2) mpz_assume z dummy d1 dummy d2CODE: RETVAL = new_mpz(); mpz_set (RETVAL->m, z->m);OUTPUT: RETVALvoidDESTROY (z) mpz_assume zCODE: TRACE (printf ("%s DESTROY %p\n", mpz_class, z)); free_mpz (z);malloced_stringoverload_string (z, d1, d2) mpz_assume z dummy d1 dummy d2CODE: TRACE (printf ("%s overload_string %p\n", mpz_class, z)); RETVAL = mpz_get_str (NULL, 10, z->m);OUTPUT: RETVALmpzoverload_add (xv, yv, order) SV *xv SV *yv SV *orderALIAS: GMP::Mpz::overload_sub = 1 GMP::Mpz::overload_mul = 2 GMP::Mpz::overload_div = 3 GMP::Mpz::overload_rem = 4 GMP::Mpz::overload_and = 5 GMP::Mpz::overload_ior = 6 GMP::Mpz::overload_xor = 7PREINIT: static_functable const struct { void (*op) (mpz_ptr, mpz_srcptr, mpz_srcptr); } table[] = { { mpz_add }, /* 0 */ { mpz_sub }, /* 1 */ { mpz_mul }, /* 2 */ { mpz_tdiv_q }, /* 3 */ { mpz_tdiv_r }, /* 4 */ { mpz_and }, /* 5 */ { mpz_ior }, /* 6 */ { mpz_xor }, /* 7 */ };CODE: assert_table (ix); if (order == &PL_sv_yes) SV_PTR_SWAP (xv, yv); RETVAL = new_mpz(); (*table[ix].op) (RETVAL->m, coerce_mpz (tmp_mpz_0, xv), coerce_mpz (tmp_mpz_1, yv));OUTPUT: RETVALvoidoverload_addeq (x, y, o) mpz_assume x mpz_coerce y order_noswap oALIAS: GMP::Mpz::overload_subeq = 1 GMP::Mpz::overload_muleq = 2 GMP::Mpz::overload_diveq = 3 GMP::Mpz::overload_remeq = 4 GMP::Mpz::overload_andeq = 5 GMP::Mpz::overload_ioreq = 6 GMP::Mpz::overload_xoreq = 7PREINIT: static_functable const struct { void (*op) (mpz_ptr, mpz_srcptr, mpz_srcptr); } table[] = { { mpz_add }, /* 0 */ { mpz_sub }, /* 1 */ { mpz_mul }, /* 2 */ { mpz_tdiv_q }, /* 3 */ { mpz_tdiv_r }, /* 4 */ { mpz_and }, /* 5 */ { mpz_ior }, /* 6 */ { mpz_xor }, /* 7 */ };PPCODE: assert_table (ix); (*table[ix].op) (x->m, x->m, y); XPUSHs (ST(0));mpzoverload_lshift (zv, nv, order) SV *zv SV *nv SV *orderALIAS: GMP::Mpz::overload_rshift = 1 GMP::Mpz::overload_pow = 2PREINIT: static_functable const struct { void (*op) (mpz_ptr, mpz_srcptr, unsigned long); } table[] = { { mpz_mul_2exp }, /* 0 */ { mpz_div_2exp }, /* 1 */ { mpz_pow_ui }, /* 2 */ };CODE: assert_table (ix); if (order == &PL_sv_yes) SV_PTR_SWAP (zv, nv); RETVAL = new_mpz(); (*table[ix].op) (RETVAL->m, coerce_mpz (RETVAL->m, zv), coerce_ulong (nv));OUTPUT: RETVALvoidoverload_lshifteq (z, n, o) mpz_assume z ulong_coerce n order_noswap oALIAS: GMP::Mpz::overload_rshifteq = 1 GMP::Mpz::overload_poweq = 2PREINIT: static_functable const struct { void (*op) (mpz_ptr, mpz_srcptr, unsigned long); } table[] = { { mpz_mul_2exp }, /* 0 */ { mpz_div_2exp }, /* 1 */ { mpz_pow_ui }, /* 2 */ };PPCODE: assert_table (ix); (*table[ix].op) (z->m, z->m, n); XPUSHs(ST(0));mpzoverload_abs (z, d1, d2) mpz_assume z dummy d1 dummy d2ALIAS: GMP::Mpz::overload_neg = 1 GMP::Mpz::overload_com = 2 GMP::Mpz::overload_sqrt = 3PREINIT: static_functable const struct { void (*op) (mpz_ptr w, mpz_srcptr x); } table[] = { { mpz_abs }, /* 0 */ { mpz_neg }, /* 1 */ { mpz_com }, /* 2 */ { mpz_sqrt }, /* 3 */ };CODE: assert_table (ix); RETVAL = new_mpz(); (*table[ix].op) (RETVAL->m, z->m);OUTPUT: RETVALvoidoverload_inc (z, d1, d2) mpz_assume z dummy d1 dummy d2ALIAS: GMP::Mpz::overload_dec = 1PREINIT: static_functable const struct { void (*op) (mpz_ptr w, mpz_srcptr x, unsigned long y); } table[] = { { mpz_add_ui }, /* 0 */ { mpz_sub_ui }, /* 1 */ };CODE: assert_table (ix); (*table[ix].op) (z->m, z->m, 1L);intoverload_spaceship (xv, yv, order) SV *xv SV *yv SV *orderPREINIT: mpz x;CODE: TRACE (printf ("%s overload_spaceship\n", mpz_class)); MPZ_ASSUME (x, xv); switch (use_sv (yv)) { case USE_IVX: RETVAL = mpz_cmp_si (x->m, SvIVX(yv)); break; case USE_UVX: RETVAL = mpz_cmp_ui (x->m, SvUVX(yv)); break; case USE_PVX: RETVAL = mpz_cmp (x->m, coerce_mpz (tmp_mpz_0, yv)); break; case USE_NVX: RETVAL = mpz_cmp_d (x->m, SvNVX(yv)); break; case USE_MPZ: RETVAL = mpz_cmp (x->m, SvMPZ(yv)->m);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?