static PyObject * GMPy_MPZ_Function_DoubleFac(PyObject *self, PyObject *other) { MPZ_Object *result = NULL; unsigned long n; n = c_ulong_From_Integer(other); if (n == (unsigned long)(-1) && PyErr_Occurred()) { return NULL; } if ((result = GMPy_MPZ_New(NULL))) { mpz_2fac_ui(result->z, n); } return (PyObject*)result; }
Integer factorial2(unsigned long n) { Integer result; mpz_2fac_ui(result.backend().data(), n); return result; }
int main (int argc, char *argv[]) { mpz_t ref[MULTIFAC_WHEEL], ref2[MULTIFAC_WHEEL2], res; unsigned long n, j, m, m2; unsigned long limit = 2222, step = 1; tests_start (); if (argc > 1 && argv[1][0] == 'x') limit = ULONG_MAX; else if (argc > 1) limit = atoi (argv[1]); /* for small limb testing */ limit = MIN (limit, MP_LIMB_T_MAX); for (m = 0; m < MULTIFAC_WHEEL; m++) mpz_init_set_ui(ref [m],1); for (m2 = 0; m2 < MULTIFAC_WHEEL2; m2++) mpz_init_set_ui(ref2 [m2],1); mpz_init (res); m = 0; m2 = 0; for (n = 0; n <= limit;) { mpz_mfac_uiui (res, n, MULTIFAC_WHEEL); MPZ_CHECK_FORMAT (res); if (mpz_cmp (ref[m], res) != 0) { printf ("mpz_mfac_uiui(%lu,%d) wrong\n", n, MULTIFAC_WHEEL); printf (" got "); mpz_out_str (stdout, 10, res); printf("\n"); printf (" want "); mpz_out_str (stdout, 10, ref[m]); printf("\n"); abort (); } mpz_mfac_uiui (res, n, MULTIFAC_WHEEL2); MPZ_CHECK_FORMAT (res); if (mpz_cmp (ref2[m2], res) != 0) { printf ("mpz_mfac_uiui(%lu,%d) wrong\n", n, MULTIFAC_WHEEL2); printf (" got "); mpz_out_str (stdout, 10, res); printf("\n"); printf (" want "); mpz_out_str (stdout, 10, ref2[m2]); printf("\n"); abort (); } if (n + step <= limit) for (j = 0; j < step; j++) { n++; m++; m2++; if (m >= MULTIFAC_WHEEL) m -= MULTIFAC_WHEEL; if (m2 >= MULTIFAC_WHEEL2) m2 -= MULTIFAC_WHEEL2; mpz_mul_ui (ref[m], ref[m], n); /* Compute a reference, with current library */ mpz_mul_ui (ref2[m2], ref2[m2], n); /* Compute a reference, with current library */ } else n += step; } mpz_fac_ui (ref[0], n); mpz_mfac_uiui (res, n, 1); MPZ_CHECK_FORMAT (res); if (mpz_cmp (ref[0], res) != 0) { printf ("mpz_mfac_uiui(%lu,1) wrong\n", n); printf (" got "); mpz_out_str (stdout, 10, res); printf("\n"); printf (" want "); mpz_out_str (stdout, 10, ref[0]); printf("\n"); abort (); } mpz_2fac_ui (ref[0], n); mpz_mfac_uiui (res, n, 2); MPZ_CHECK_FORMAT (res); if (mpz_cmp (ref[0], res) != 0) { printf ("mpz_mfac_uiui(%lu,1) wrong\n", n); printf (" got "); mpz_out_str (stdout, 10, res); printf("\n"); printf (" want "); mpz_out_str (stdout, 10, ref[0]); printf("\n"); abort (); } n++; mpz_2fac_ui (ref[0], n); mpz_mfac_uiui (res, n, 2); MPZ_CHECK_FORMAT (res); if (mpz_cmp (ref[0], res) != 0) { printf ("mpz_mfac_uiui(%lu,2) wrong\n", n); printf (" got "); mpz_out_str (stdout, 10, res); printf("\n"); printf (" want "); mpz_out_str (stdout, 10, ref[0]); printf("\n"); abort (); } for (m = 0; m < MULTIFAC_WHEEL; m++) mpz_clear (ref[m]); for (m2 = 0; m2 < MULTIFAC_WHEEL2; m2++) mpz_clear (ref2[m2]); mpz_clear (res); tests_end (); exit (0); }
int main (int argc, char *argv[]) { unsigned long n, m; unsigned long limit = 2222; mpz_t df[2], f, r; tests_start (); if (argc > 1 && argv[1][0] == 'x') limit = ULONG_MAX; else if (argc > 1) limit = atoi (argv[1]); /* for small limb testing */ limit = MIN (limit, MP_LIMB_T_MAX); mpz_init_set_ui (df[0], 1); /* 0!! = 1 */ mpz_init_set_ui (df[1], 1); /* -1!! = 1 */ mpz_init_set_ui (f, 1); /* 0! = 1 */ mpz_init (r); for (n = 0, m = 0; n < limit; n++) { mpz_fac_ui (r, n); MPZ_CHECK_FORMAT (r); if (mpz_cmp (f, r) != 0) { printf ("mpz_fac_ui(%lu) wrong\n", n); printf (" got "); mpz_out_str (stdout, 10, r); printf("\n"); printf (" want "); mpz_out_str (stdout, 10, f); printf("\n"); abort (); } mpz_2fac_ui (r, n); MPZ_CHECK_FORMAT (r); if (mpz_cmp (df[m], r) != 0) { printf ("mpz_2fac_ui(%lu) wrong\n", n); printf (" got "); mpz_out_str (stdout, 10, r); printf("\n"); printf (" want "); mpz_out_str (stdout, 10, df[m]); printf("\n"); abort (); } m ^= 1; mpz_mul_ui (df[m], df[m], n+1); /* (n+1)!! = (n-1)!! * (n+1) */ mpz_mul_ui (f, f, n+1); /* (n+1)! = n! * (n+1) */ } n = 1048573; /* a prime */ if (n > MP_LIMB_T_MAX) n = 65521; /* a smaller prime :-) */ mpz_fac_ui (f, n - 1); m = mpz_fdiv_ui (f, n); if ( m != n - 1) { printf ("mpz_fac_ui(%lu) wrong\n", n - 1); printf (" Wilson's theorem not verified: got %lu, expected %lu.\n",m ,n - 1); abort (); } mpz_clear (df[0]); mpz_clear (df[1]); mpz_clear (f); mpz_clear (r); tests_end (); exit (0); }
void mpz_mfac_uiui (mpz_ptr x, unsigned long n, unsigned long m) { ASSERT (n <= GMP_NUMB_MAX); ASSERT (m != 0); if (n < 3 || n - 3 < m - 1) { /* (n < 3 || n - 1 <= m || m == 0) */ PTR (x)[0] = n + (n == 0); SIZ (x) = 1; } else { /* m < n - 1 < GMP_NUMB_MAX */ mp_limb_t g, sn; mpz_t t; sn = n; g = mpn_gcd_1 (&sn, 1, m); if (g != 1) { n/=g; m/=g; } if (m <= 2) { /* fac or 2fac */ if (m == 1) { if (g > 2) { mpz_init (t); mpz_fac_ui (t, n); sn = n; } else { if (g == 2) mpz_2fac_ui (x, n << 1); else mpz_fac_ui (x, n); return; } } else { /* m == 2 */ if (g != 1) { mpz_init (t); mpz_2fac_ui (t, n); sn = n / 2 + 1; } else { mpz_2fac_ui (x, n); return; } } } else { /* m >= 3, gcd(n,m) = 1 */ mp_limb_t *factors; mp_limb_t prod, max_prod, j; TMP_DECL; sn = n / m + 1; j = 0; prod = n; n -= m; max_prod = GMP_NUMB_MAX / n; TMP_MARK; factors = TMP_ALLOC_LIMBS (sn / log_n_max (n) + 2); for (; n > m; n -= m) FACTOR_LIST_STORE (n, prod, max_prod, factors, j); factors[j++] = n; factors[j++] = prod; if (g > 1) { mpz_init (t); mpz_prodlimbs (t, factors, j); } else mpz_prodlimbs (x, factors, j); TMP_FREE; } if (g > 1) { mpz_t p; mpz_init (p); mpz_ui_pow_ui (p, g, sn); /* g^sn */ mpz_mul (x, p, t); mpz_clear (p); mpz_clear (t); } } }