Example #1
0
/*------------------------------------------------------------------------*/
static void
search_coeffs_core(msieve_obj *obj, poly_search_t *poly, 
			uint32 deadline)
{
	uint32 i, j;
	uint32 degree = poly->degree;
	uint32 num_poly = poly->num_poly;
	uint32 mult = 0;

	switch (degree) {
	case 4: mult = 4 * 4 * 4 * 4; break;
	case 5: mult = 5 * 5 * 5 * 5 * 5; break;
	case 6: mult = 6 * 6 * 6 * 6 * 6 * 6; break;
	}

	for (i = 0; i < num_poly; i++) {
		curr_poly_t *c = poly->batch + i;

		mpz_mul_ui(c->trans_N, poly->N, (mp_limb_t)mult);
		for (j = 0; j < degree - 1; j++)
			mpz_mul(c->trans_N, c->trans_N, c->high_coeff);

		mpz_root(c->trans_m0, c->trans_N, (mp_limb_t)degree);

		mpz_tdiv_q(poly->m0, poly->N, c->high_coeff);
		mpz_root(poly->m0, poly->m0, (mp_limb_t)degree);
		c->sieve_size = c->coeff_max / mpz_get_d(poly->m0) * 
				c->p_size_max * c->p_size_max / degree;
		mpz_set_d(c->mp_sieve_size, c->sieve_size);
	}

	sieve_lattice(obj, poly, 2000, 2001, 100000, 
			num_poly * deadline);
}
Example #2
0
int
main (int argc, char **argv)
{
  mpz_t x2;
  mpz_t root1;
  mp_size_t x2_size;
  int i;
  int reps = 5000;
  unsigned long nth;
  gmp_randstate_ptr rands;
  mpz_t bs;
  unsigned long bsi, size_range;

  tests_start ();
  rands = RANDS;

  mpz_init (bs);

  if (argc == 2)
     reps = atoi (argv[1]);

  mpz_init (x2);
  mpz_init (root1);

  /* This triggers a gcc 4.3.2 bug */
  mpz_set_str (x2, "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80000000000000000000000000000000000000000000000000000000000000002", 16);
  mpz_root (root1, x2, 2);
  check_one (root1, x2, 2, -1);

  for (i = 0; i < reps; i++)
    {
      mpz_urandomb (bs, rands, 32);
      size_range = mpz_get_ui (bs) % 12 + 2;

      mpz_urandomb (bs, rands, size_range);
      x2_size = mpz_get_ui (bs) + 10;
      mpz_rrandomb (x2, rands, x2_size);

      mpz_urandomb (bs, rands, 15);
      nth = mpz_getlimbn (bs, 0) % mpz_sizeinbase (x2, 2) + 2;

      mpz_root (root1, x2, nth);

      mpz_urandomb (bs, rands, 4);
      bsi = mpz_get_ui (bs);
      if ((bsi & 1) != 0)
	{
	  /* With 50% probability, set x2 near a perfect power.  */
	  mpz_pow_ui (x2, root1, nth);
	  if ((bsi & 2) != 0)
	    {
	      mpz_sub_ui (x2, x2, bsi >> 2);
	      mpz_abs (x2, x2);
	    }
	  else
Example #3
0
// Factor using lehman method.
int _factor_lehman_method(mpz_class &rop, const mpz_class &n)
{
    if (n < 21)
        throw std::runtime_error("Require n >= 21 to use lehman method");

    int ret_val = 0;
    mpz_class u_bound;

    mpz_root(u_bound.get_mpz_t(), n.get_mpz_t(), 3);
    u_bound = u_bound + 1;

    Sieve::iterator pi(u_bound.get_ui());
    unsigned p;
    while ((p = pi.next_prime()) <= u_bound.get_ui()) {
        if (n % p == 0) {
            rop = n / p;
            ret_val = 1;
            break;
        }
    }

    if (!ret_val) {

        mpz_class k, a, b, l;
        mpf_class t;

        k = 1;

        while (k <= u_bound) {
            t = 2 * sqrt(k * n);
            mpz_set_f(a.get_mpz_t(), t.get_mpf_t());
            mpz_root(b.get_mpz_t(), n.get_mpz_t(), 6);
            mpz_root(l.get_mpz_t(), k.get_mpz_t(), 2);
            b = b / (4 * l);
            b = b + a;

            while (a <= b) {
                l = a * a - 4 * k * n;
                if (mpz_perfect_square_p(l.get_mpz_t())) {
                    mpz_sqrt(b.get_mpz_t(), l.get_mpz_t());
                    b = a + b;
                    mpz_gcd(rop.get_mpz_t(), n.get_mpz_t(), b.get_mpz_t());
                    ret_val = 1;
                    break;
                }
                a = a + 1;
            }
            if (ret_val)
                break;
            k = k + 1;
        }
    }

    return ret_val;
}
Example #4
0
Sieve::Sieve(mpz_class pN)
{
	N = pN;
	mpz_root(N_sqrt.get_mpz_t(), N.get_mpz_t(), 2);
	floatingthreshhold = THRESHHOLD;
	numFoundInSweepp = 0;
	numtriedInSweep = 0;
	SetUp();
}
Example #5
0
/*------------------------------------------------------------------------*/
static void
stage1_bounds_update(poly_search_t *poly, poly_coeff_t *c)
{
	/* determine the parametrs for the collision search,
	   given one leading algebraic coefficient a_d */

	uint32 degree = poly->degree;
	double N = mpz_get_d(poly->N);
	double high_coeff = mpz_get_d(c->high_coeff);
	double m0 = pow(N / high_coeff, 1./degree);
	double skewness_min, coeff_max;

	/* we don't know the optimal skewness for this polynomial
	   but at least can bound the skewness. The value of the
	   third-highest coefficient is from Kleinjung's 2006
	   poly selection algorithm as published in Math. Comp. */

	switch (degree) {
	case 4:
		skewness_min = sqrt(m0 / poly->norm_max);
		coeff_max = poly->norm_max;
		break;

	case 5:
		skewness_min = pow(m0 / poly->norm_max, 2./3.);
		coeff_max = poly->norm_max / sqrt(skewness_min);
		break;

	case 6:
		skewness_min = sqrt(m0 / poly->norm_max);
		coeff_max = poly->norm_max / skewness_min;
		break;

	default:
		printf("error: unexpected poly degree %d\n", degree);
		exit(-1);
	}

	c->degree = degree;
	c->m0 = m0;
	c->coeff_max = coeff_max;
	c->p_size_max = coeff_max / skewness_min;

	/* we perform the collision search on a transformed version
	   of N and the low-order rational coefficient m. In the
	   transformed coordinates, a_d is 1 and a_{d-1} is 0. When
	   a hit is found, we undo the transformation to recover
	   the correction to m that makes the new polynomial 'work' */

	mpz_mul_ui(c->trans_N, c->high_coeff, degree);
	mpz_pow_ui(c->trans_N, c->trans_N, degree - 1);
	mpz_mul_ui(c->trans_N, c->trans_N, degree);
	mpz_mul(c->trans_N, c->trans_N, poly->N);
	mpz_root(c->trans_m0, c->trans_N, degree);
}
Example #6
0
static PyObject *
GMPy_MPZ_Function_Iroot(PyObject *self, PyObject *args)
{
    unsigned long n;
    int exact;
    MPZ_Object *root = NULL, *tempx = NULL;
    PyObject *result = NULL;

    if ((PyTuple_GET_SIZE(args) != 2) ||
        ((!IS_INTEGER(PyTuple_GET_ITEM(args, 0))) ||
         (!IS_INTEGER(PyTuple_GET_ITEM(args, 1))))) {

        TYPE_ERROR("iroot() requires 'int','int' arguments");
        return NULL;
    }

    n = c_ulong_From_Integer(PyTuple_GET_ITEM(args, 1));
    if ((n == 0) || ((n == (unsigned long)(-1)) && PyErr_Occurred())) {
        VALUE_ERROR("n must be > 0");
        return NULL;
    }

    if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL))) {
        /* LCOV_EXCL_START */
        return NULL;
        /* LCOV_EXCL_STOP */
    }

    if (mpz_sgn(tempx->z) < 0) {
        VALUE_ERROR("iroot() of negative number");
        Py_DECREF((PyObject*)tempx);
        return NULL;
    }



    if (!(result = PyTuple_New(2)) ||
        !(root = GMPy_MPZ_New(NULL))) {

        /* LCOV_EXCL_START */
        Py_DECREF((PyObject*)tempx);
        Py_XDECREF((PyObject*)root);
        Py_XDECREF(result);
        return NULL;
        /* LCOV_EXCL_STOP */
    }

    exact = mpz_root(root->z, tempx->z, n);
    Py_DECREF((PyObject*)tempx);

    PyTuple_SET_ITEM(result, 0, (PyObject*)root);
    PyTuple_SET_ITEM(result, 1, (PyObject*)PyBool_FromLong(exact));
    return result;
}
Example #7
0
int
main (int argc, char **argv)
{
  mpz_t x2;
  mpz_t x;
  mpz_t temp, temp2;
  mp_size_t x2_size;
  int i;
  int reps = 1000;
  unsigned long nth;
  gmp_randstate_ptr rands;
  mpz_t bs;
  unsigned long bsi, size_range;

  tests_start ();
  rands = RANDS;

  mpz_init (bs);

  if (argc == 2)
     reps = atoi (argv[1]);

  mpz_init (x2);
  mpz_init (x);
  mpz_init (temp);
  mpz_init (temp2);

  for (i = 0; i < reps; i++)
    {
      mpz_urandomb (bs, rands, 32);
      size_range = mpz_get_ui (bs) % 12 + 2;

      mpz_urandomb (bs, rands, size_range);
      x2_size = mpz_get_ui (bs) + 10;
      mpz_rrandomb (x2, rands, x2_size);

      mpz_urandomb (bs, rands, 15);
      nth = mpz_getlimbn (bs, 0) % mpz_sizeinbase (x2, 2) + 2;

      mpz_root (x, x2, nth);

      mpz_urandomb (bs, rands, 4);
      bsi = mpz_get_ui (bs);
      if ((bsi & 1) != 0)
	{
	  /* With 50% probability, set x2 near a perfect power.  */
	  mpz_pow_ui (x2, x, nth);
	  if ((bsi & 2) != 0)
	    {
	      mpz_sub_ui (x2, x2, bsi >> 2);
	      mpz_abs (x2, x2);
	    }
	  else
Example #8
0
int mpz_premier(mpz_t _a)
{
    mpz_t _root_temp;
        mpz_init(_root_temp);
        mpz_root(_root_temp,_a,2);
        mpz_add_ui(_root_temp,_root_temp,1);
    mpz_t _i; mpz_init(_i);
    mpz_t _k; mpz_init(_k);
    mpz_set_ui(_i,2);
    while (mpz_cmp(_i,_root_temp)< 0)
        { mpz_mod(_k,_a,_i); mpz_add_ui(_i,_i,1); if (mpz_cmp_ui(_k,0)==0) {return 0;} }
    return 1;
}
Example #9
0
uint64_t lpow(mpz_t n, uint64_t k, uint64_t l)
{
  //Returns floor(n^(k/l))
  assert(n>0); assert(l>0);
  mpz_t x;
  mpz_init(x);
  mpz_set(x,n);
  mpz_pow_ui(x, x, k);
  mpz_root(x, x, l);
  uint64_t y = mpz_get_ui(x);
  mpz_clear(x);
  return y;
}
Example #10
0
//------------------------------------------------------------------------------
// Name: cbrt
//------------------------------------------------------------------------------
knumber_base *knumber_integer::cbrt() {

	mpz_t x;
	mpz_init_set(x, mpz_);
	if(mpz_root(x, x, 3)) {
		mpz_swap(mpz_, x);
		mpz_clear(x);
		return this;
	}

	mpz_clear(x);
	knumber_float *f = new knumber_float(this);
	delete this;
	return f->cbrt();
}
Example #11
0
int i_nth_root(const Ptr<RCP<const Integer>> &r, const Integer &a,
        unsigned long int n)
{
    if (n == 0)
        throw std::runtime_error("i_nth_root: Can not find Zeroth root");

    int ret_val;
    mpz_t t;
    mpz_init(t);

    ret_val = mpz_root(t, a.as_mpz().get_mpz_t(), n);
    *r = integer(mpz_class(t));

    mpz_clear(t);

    return ret_val;
}
Example #12
0
int first_test(mpz_t n){

	int test = 1;
	int sortie = 0;
	mpz_t nb, max,mod;

       	mpz_init (nb);
       	mpz_init (max);
	mpz_init (mod);

	mpz_root(max, n, 2); //need debug
	//gmp_printf ("\nDebug racine carré : %Zd\n", max);
	//mpz_out_str(stdout, 10, max);

	mpz_set_str(nb,"2",10);
	//gmp_printf ("\nDebug compteur : %Zd\n", nb);

	if(mpz_cmp_si(n,0)== 0 || mpz_cmp_si(n,1)== 0){
		test = 0;
		sortie = 1;
	}

	for(sortie = 0;sortie!=1 && mpz_cmp(nb,max)<=0;mpz_add_ui(nb,nb,1)){

		//printf("test : %i\n", test);
		mpz_mod(mod,n,nb);
		//gmp_printf("Debug tour num %Zd : n = %Zd, nb = %Zd, n mod nb = %Zd\n",nb,n,nb,mod);

		if(mpz_cmp_si(mod,0)== 0){
			//printf("Debug : Sortie\n");
			test = 0;
			sortie = 1;
		}
	}


	mpz_clear(nb);
	mpz_clear(max);
	mpz_clear(mod);
	//printf("test : %i\n", test);
	return test;

}
Example #13
0
int main()
{
  mpz_class x;
  mpz_class y;
  mpz_class z;

  x="125";
  y="987654321123456790";

  //mpz_pow_ui(x.get_mpz_t(),x.get_mpz_t(),2);	//Power of a no.
  //x=sqrt(x);//Square root of a no.
  mpz_root(z.get_mpz_t(),x.get_mpz_t(),3);//Nth root of a no.
  //z=x+y;
  int r=cmp(x,y);//Compare two no.s.
 
  std::cout << "\n    " << x << "\n+\n    " << y;
  std::cout << "\n--------------------\n" << z << "\n\n";
  std::cout <<"result="<<r<<"\n";
}
Example #14
0
File: prime.c Project: pbos/optimus
void sieve_factor(mpz_t num)
{
	mpz_t gmp_root;
	mpz_init(gmp_root);
	mpz_sqrt(gmp_root, num);

	if(mpz_root(gmp_root, num, 2) != 0)
	{
		mpz_set(factors[num_factors++], gmp_root);
		mpz_set(factors[num_factors++], gmp_root);
		mpz_clear(gmp_root);
		return;
	}

	fail = true;

	find_candidates(num, gmp_root);

	mpz_clear(gmp_root);
}
Example #15
0
uint64_t lpow(mpz_t n, uint64_t k, uint64_t l)
{
  //Returns floor(n^(k/l))
  mpz_t x;
  mpz_init(x);
  mpz_set(x,n);
  mpz_pow_ui(x, x, k);
  mpz_root(x, x, l);
  uint64_t  m = mpz_get_ui(x);
  //Check
  /*  mpz_t M, M1, N, C1, C2;
 mpz_inits(M, M1, N, C1, C2, NULL);
 mpz_set_ui(M, m); mpz_set_ui(M1, m+1); mpz_set_ui(N, n);
 mpz_pow_ui(C1, M, l); mpz_pow_ui(C2, N, k);
 assert(mpz_cmp(C1, C2) <= 0);
 mpz_pow_ui(C1, M1, l);
 assert(mpz_cmp(C1, C2) > 0);

 mpz_clears(x, M, M1, N, C1, C2, NULL );*/
  return m;
}
Example #16
0
File: gen-fac.c Project: da2ce7/gmp
/* returns 0 on success		*/
int
gen_consts (int numb, int nail, int limb)
{
  mpz_t x, mask, y, last;
  unsigned long a, b;
  unsigned long ofl, ofe;

  printf ("/* This file is automatically generated by gen-fac.c */\n\n");
  printf ("#if GMP_NUMB_BITS != %d\n", numb);
  printf ("Error , error this data is for %d GMP_NUMB_BITS only\n", numb);
  printf ("#endif\n");
#if 0
  printf ("#if GMP_LIMB_BITS != %d\n", limb);
  printf ("Error , error this data is for %d GMP_LIMB_BITS only\n", limb);
  printf ("#endif\n");
#endif

  printf
    ("/* This table is 0!,1!,2!,3!,...,n! where n! has <= GMP_NUMB_BITS bits */\n");
  printf
    ("#define ONE_LIMB_FACTORIAL_TABLE CNST_LIMB(0x1),CNST_LIMB(0x1");
  mpz_init_set_ui (x, 1);
  mpz_init (last);
  for (b = 2;; b++)
    {
      mpz_mul_ui (x, x, b);	/* so b!=a       */
      if (mpz_sizeinbase (x, 2) > numb)
	break;
      printf ("),CNST_LIMB(0x");
      mpz_out_str (stdout, 16, x);
    }
  printf (")\n");

  printf
    ("\n/* This table is 0!,1!,2!/2,3!/2,...,n!/2^sn where n!/2^sn is an */\n");
  printf
    ("/* odd integer for each n, and n!/2^sn has <= GMP_NUMB_BITS bits */\n");
  printf
    ("#define ONE_LIMB_ODD_FACTORIAL_TABLE CNST_LIMB(0x1),CNST_LIMB(0x1),CNST_LIMB(0x1");
  mpz_set_ui (x, 1);
  for (b = 3;; b++)
    {
      for (a = b; (a & 1) == 0; a >>= 1);
      mpz_swap (last, x);
      mpz_mul_ui (x, last, a);
      if (mpz_sizeinbase (x, 2) > numb)
	break;
      printf ("),CNST_LIMB(0x");
      mpz_out_str (stdout, 16, x);
    }
  printf (")\n");
  printf
    ("#define ODD_FACTORIAL_TABLE_MAX CNST_LIMB(0x");
  mpz_out_str (stdout, 16, last);
  printf (")\n");

  ofl = b - 1;
  printf
    ("#define ODD_FACTORIAL_TABLE_LIMIT (%lu)\n", ofl);
  mpz_init2 (mask, numb + 1);
  mpz_setbit (mask, numb);
  mpz_sub_ui (mask, mask, 1);
  printf
    ("\n/* Previous table, continued, values modulo 2^GMP_NUMB_BITS */\n");
  printf
    ("#define ONE_LIMB_ODD_FACTORIAL_EXTTABLE CNST_LIMB(0x");
  mpz_and (x, x, mask);
  mpz_out_str (stdout, 16, x);
  mpz_init (y);
  mpz_bin_uiui (y, b, b/2);
  b++;
  for (;; b++)
    {
      for (a = b; (a & 1) == 0; a >>= 1);
      if (a == b) {
	mpz_divexact_ui (y, y, a/2+1);
	mpz_mul_ui (y, y, a);
      } else
	mpz_mul_2exp (y, y, 1);
      if (mpz_sizeinbase (y, 2) > numb)
	break;
      mpz_mul_ui (x, x, a);
      mpz_and (x, x, mask);
      printf ("),CNST_LIMB(0x");
      mpz_out_str (stdout, 16, x);
    }
  printf (")\n");
  ofe = b - 1;
  printf
    ("#define ODD_FACTORIAL_EXTTABLE_LIMIT (%lu)\n", ofe);

  printf
    ("\n/* This table is 1!!,3!!,...,(2n+1)!! where (2n+1)!! has <= GMP_NUMB_BITS bits */\n");
  printf
    ("#define ONE_LIMB_ODD_DOUBLEFACTORIAL_TABLE CNST_LIMB(0x1");
  mpz_set_ui (x, 1);
  for (b = 3;; b+=2)
    {
      mpz_swap (last, x);
      mpz_mul_ui (x, last, b);
      if (mpz_sizeinbase (x, 2) > numb)
	break;
      printf ("),CNST_LIMB(0x");
      mpz_out_str (stdout, 16, x);
    }
  printf (")\n");
  printf
    ("#define ODD_DOUBLEFACTORIAL_TABLE_MAX CNST_LIMB(0x");
  mpz_out_str (stdout, 16, last);
  printf (")\n");

  printf
    ("#define ODD_DOUBLEFACTORIAL_TABLE_LIMIT (%lu)\n", b - 2);

  printf
    ("\n/* This table x_1, x_2,... contains values s.t. x_n^n has <= GMP_NUMB_BITS bits */\n");
  printf
    ("#define NTH_ROOT_NUMB_MASK_TABLE (GMP_NUMB_MASK");
  for (b = 2;b <= 8; b++)
    {
      mpz_root (x, mask, b);
      printf ("),CNST_LIMB(0x");
      mpz_out_str (stdout, 16, x);
    }
  printf (")\n");

  mpz_add_ui (mask, mask, 1);
  printf
    ("\n/* This table contains inverses of odd factorials, modulo 2^GMP_NUMB_BITS */\n");
  printf
    ("\n/* It begins with (2!/2)^-1=1 */\n");
  printf
    ("#define ONE_LIMB_ODD_FACTORIAL_INVERSES_TABLE CNST_LIMB(0x1");
  mpz_set_ui (x, 1);
  for (b = 3;b <= ofe - 2; b++)
    {
      for (a = b; (a & 1) == 0; a >>= 1);
      mpz_mul_ui (x, x, a);
      mpz_invert (y, x, mask);
      printf ("),CNST_LIMB(0x");
      mpz_out_str (stdout, 16, y);
    }
  printf (")\n");

  ofe = (ofe / 16 + 1) * 16;

  printf
    ("\n/* This table contains 2n-popc(2n) for small n */\n");
  printf
    ("\n/* It begins with 2-1=1 (n=1) */\n");
  printf
    ("#define TABLE_2N_MINUS_POPC_2N 1");
  for (b = 4; b <= ofe; b += 2)
    {
      mpz_set_ui (x, b);
      printf (",%lu",b - mpz_popcount (x));
    }
  printf ("\n");
  printf
    ("#define TABLE_LIMIT_2N_MINUS_POPC_2N %lu\n", ofe + 1);


  ofl = (ofl + 1) / 2;
  printf
    ("#define ODD_CENTRAL_BINOMIAL_OFFSET (%lu)\n", ofl);
  printf
    ("\n/* This table contains binomial(2k,k)/2^t */\n");
  printf
    ("\n/* It begins with ODD_CENTRAL_BINOMIAL_TABLE_MIN */\n");
  printf
    ("#define ONE_LIMB_ODD_CENTRAL_BINOMIAL_TABLE ");
  for (b = ofl;; b++)
    {
      mpz_bin_uiui (x, 2 * b, b);
      mpz_remove_twos (x);
      if (mpz_sizeinbase (x, 2) > numb)
	break;
      if (b != ofl)
	printf ("),");
      printf("CNST_LIMB(0x");
      mpz_out_str (stdout, 16, x);
    }
  printf (")\n");

  ofe = b - 1;
  printf
    ("#define ODD_CENTRAL_BINOMIAL_TABLE_LIMIT (%lu)\n", ofe);

  printf
    ("\n/* This table contains the inverses of elements in the previous table. */\n");
  printf
    ("#define ONE_LIMB_ODD_CENTRAL_BINOMIAL_INVERSE_TABLE CNST_LIMB(0x");
  for (b = ofl; b <= ofe; b++)
    {
      mpz_bin_uiui (x, 2 * b, b);
      mpz_remove_twos (x);
      mpz_invert (x, x, mask);
      mpz_out_str (stdout, 16, x);
      if (b != ofe)
	printf ("),CNST_LIMB(0x");
    }
  printf (")\n");

  printf
    ("\n/* This table contains the values t in the formula binomial(2k,k)/2^t */\n");
  printf
    ("#define CENTRAL_BINOMIAL_2FAC_TABLE ");
  for (b = ofl; b <= ofe; b++)
    {
      mpz_bin_uiui (x, 2 * b, b);
      printf ("%d", mpz_remove_twos (x));
      if (b != ofe)
	printf (",");
    }
  printf ("\n");

  return 0;
}
Example #17
0
int main()
{
    unsigned int i,j,a,*SV;
    unsigned char logpi;
    int k,S,r,s1,s2,s,NS,logm,ptr,threshold,epri;
    long M,la,lptr;

    qsieve=gmpinit(-36,0);

    if(initv()<0) return 0;

    hmod=2*mlf+1;
    mpz_set_si(TA, hmod);
    while(!mpz_probab_prime_p(TA, qsieve->NTRY)) mpz_sub_ui(TA, TA, 2); //TT=不大于TT的素数
    hmod=qsieve_getsize(TA);
    hmod2=hmod-2;
    for(k=0;k<hmod;k++) hash[k]=(-1);

    M=50*(long)mm;
    NS=(int)(M/SSIZE);
    if(M%SSIZE!=0) NS++;
    M=SSIZE*(long)NS; // M为不小于50*mm的SSIZE的倍数中最小的 from 以上四行
    logm=0;
    la=M;
    while((la/=2)>0) logm++; // 以2为底
    rp[0]=logp[0]=0;
    for(k=1;k<=mm;k++) //求k*N在每个素数下的二次剩余解,与每个素数的ln(pi)
    {
        r=mpz_tdiv_q_ui(TA, D, epr[k]);
        rp[k]=qsieve_sqrmp(r,epr[k]);
        logp[k]=0;
        r=epr[k];
        while((r/=2)>0) logp[k]++;
    }

    r=mpz_tdiv_q_ui(TA, D, 8);
    if(r==5) logp[1]++;
    if(r==1) logp[1]+=2;

    threshold=logm+mpz_sizeinbase(R, 2)-2*logp[mm];

    jj=0;
    nlp=0;
    mpz_mul_si(DG, D, 2);
    mpz_root(DG, DG, 2);

    mpz_set_si(TA, M);
    qsieve_divide(DG,TA,DG);
    mpz_root(DG, DG, 2);
    if(mpz_tdiv_q_ui(TA, DG, 2)==0) mpz_add_ui(DG, DG, 1);
    if(mpz_tdiv_q_ui(TA, DG, 4)==1) mpz_add_ui(DG, DG, 2); // 令DG等于大于等于DG的数中模4余3的最小的数
    printf("  0%");

    while(1) //不断尝试新的多项式,可以并行计算
    {
        r=qsieve->NTRY;
        qsieve->NTRY=1;
        do
        {
            do {
               mpz_add_ui(DG, DG, 4);
            } while(!(mpz_probab_prime_p(DG, qsieve->NTRY) ? TRUE : FALSE));
            mpz_sub_ui(TA, DG, 1);
            mpz_tdiv_q_ui(TA, TA, 2);
            mpz_powm_sec(TA, D, TA, DG);
        } while(qsieve_getsize(TA)!=1); //直到DD是二次剩余
        qsieve->NTRY=r;
        mpz_add_ui(TA, DG, 1);
        mpz_tdiv_q_ui(TA, TA, 4);
        mpz_powm_sec(B, D, TA, DG);
        mpz_neg(TA, D);
        qsieve_muladddiv(B,B,TA,DG,TA,TA);
        mpz_neg(TA, TA);

        mpz_mul_si(A, B, 2);
        qsieve_extgcd(A,DG,A,A,A);
        qsieve_muladddiv(A,TA,TA,DG,DG,A);
        mpz_mul(TA, A, DG);
        mpz_add(B, B, TA);
        mpz_mul(A, DG, DG);
        qsieve_extgcd(DG,D,IG,IG,IG);
        
        r1[0]=r2[0]=0;
        for(k=1;k<=mm;k++) //s1和s2是两个解
        {
            s=mpz_tdiv_q_ui(TA, B, epr[k]);
            r=mpz_tdiv_q_ui(TA, A, epr[k]);
            r=qsieve_getinvers(r,epr[k]);

            s1=(epr[k]-s+rp[k]);
            s2=(epr[k]-s+epr[k]-rp[k]);
            if(s1 > s2)
            {
                int t = s1;
                s1 = s2;
                s2 = t;
            }
            r1[k]=(int)((((long long)s1)*((long long)r)) % ((long long)epr[k]));
            r2[k]=(int)((((long long)s2)*((long long)r)) % ((long long)epr[k]));
        }
        
        for(ptr=(-NS);ptr<NS;ptr++)
        {
            la=(long)ptr*SSIZE;
            SV=(unsigned int *)sieve;
            for(i=0; i<SSIZE/sizeof(int); i++) *SV++=0;
            for(k=1; k<=mm; k++)
            {
                epri=epr[k];
                logpi=logp[k];
                r=(int)(la%epri);
                s1=(r1[k]-r)%epri;
                if(s1<0) s1+=epri;
                s2=(r2[k]-r)%epri;
                if(s2<0) s2+=epri;

			/* 这部分是筛法的主要部分,数组下标表示多项式P(x)的参数x 
				s1与s2是两个P(x)=0(mod p)的解 */
                for(j=s1;j<SSIZE;j+=epri) sieve[j]+=logpi;
                if(s1==s2) continue;
                for(j=s2;j<SSIZE;j+=epri) sieve[j]+=logpi;
            }

            for(a=0;a<SSIZE;a++) //找那些没有被筛掉的数
            {
                if(sieve[a]<threshold) continue;
                lptr=la+a;
                mpz_set_si(TA, lptr);
                S=0;
                mpz_mul(TA, A, TA);
                mpz_add(TA, TA, B);
                qsieve_muladddiv(TA,IG,TA,D,D,P);
                if(qsieve_getsize(P)<0) mpz_add(P, P, D);
                qsieve_muladddiv(P,P,P,D,D,V);
                mpz_abs(TA, TA);
                if(qsieve_compare(TA,R)<0) S=1;
                if(S==1) mpz_sub(V, D, V);
                if(V!=TA) mpz_set(TA, V);
                e[0]=S;
                for(k=1;k<=mm;k++) e[k]=0;
                if(!factored(lptr,TA)) continue;
                if(gotcha())
                {
                    mpz_gcd(P, TA, N);
                    qsieve_getsize(P);
                    printf("\b\b\b\b100%\nFactors are\n");
                    qsieve_outnum(P,stdout);
                    qsieve_divide(N,P,N);
                    qsieve_outnum(N,stdout);
                    return 0;
                }
            }
        }
    }
    return 0;
}
Example #18
0
/* Evaluate the expression E and put the result in R.  */
void
mpz_eval_expr (mpz_ptr r, expr_t e)
{
  mpz_t lhs, rhs;

  switch (e->op)
    {
    case LIT:
      mpz_set (r, e->operands.val);
      return;
    case PLUS:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_add (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
    case MINUS:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_sub (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
    case MULT:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_mul (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
    case DIV:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_fdiv_q (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
    case MOD:
      mpz_init (rhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_abs (rhs, rhs);
      mpz_eval_mod_expr (r, e->operands.ops.lhs, rhs);
      mpz_clear (rhs);
      return;
    case REM:
      /* Check if lhs operand is POW expression and optimize for that case.  */
      if (e->operands.ops.lhs->op == POW)
	{
	  mpz_t powlhs, powrhs;
	  mpz_init (powlhs);
	  mpz_init (powrhs);
	  mpz_init (rhs);
	  mpz_eval_expr (powlhs, e->operands.ops.lhs->operands.ops.lhs);
	  mpz_eval_expr (powrhs, e->operands.ops.lhs->operands.ops.rhs);
	  mpz_eval_expr (rhs, e->operands.ops.rhs);
	  mpz_powm (r, powlhs, powrhs, rhs);
	  if (mpz_cmp_si (rhs, 0L) < 0)
	    mpz_neg (r, r);
	  mpz_clear (powlhs);
	  mpz_clear (powrhs);
	  mpz_clear (rhs);
	  return;
	}

      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_fdiv_r (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
#if __GNU_MP_VERSION >= 2
    case INVMOD:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_invert (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
#endif
    case POW:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      if (mpz_cmpabs_ui (lhs, 1) <= 0)
	{
	  /* For 0^rhs and 1^rhs, we just need to verify that
	     rhs is well-defined.  For (-1)^rhs we need to
	     determine (rhs mod 2).  For simplicity, compute
	     (rhs mod 2) for all three cases.  */
	  expr_t two, et;
	  two = malloc (sizeof (struct expr));
	  two -> op = LIT;
	  mpz_init_set_ui (two->operands.val, 2L);
	  makeexp (&et, MOD, e->operands.ops.rhs, two);
	  e->operands.ops.rhs = et;
	}

      mpz_eval_expr (rhs, e->operands.ops.rhs);
      if (mpz_cmp_si (rhs, 0L) == 0)
	/* x^0 is 1 */
	mpz_set_ui (r, 1L);
      else if (mpz_cmp_si (lhs, 0L) == 0)
	/* 0^y (where y != 0) is 0 */
	mpz_set_ui (r, 0L);
      else if (mpz_cmp_ui (lhs, 1L) == 0)
	/* 1^y is 1 */
	mpz_set_ui (r, 1L);
      else if (mpz_cmp_si (lhs, -1L) == 0)
	/* (-1)^y just depends on whether y is even or odd */
	mpz_set_si (r, (mpz_get_ui (rhs) & 1) ? -1L : 1L);
      else if (mpz_cmp_si (rhs, 0L) < 0)
	/* x^(-n) is 0 */
	mpz_set_ui (r, 0L);
      else
	{
	  unsigned long int cnt;
	  unsigned long int y;
	  /* error if exponent does not fit into an unsigned long int.  */
	  if (mpz_cmp_ui (rhs, ~(unsigned long int) 0) > 0)
	    goto pow_err;

	  y = mpz_get_ui (rhs);
	  /* x^y == (x/(2^c))^y * 2^(c*y) */
#if __GNU_MP_VERSION >= 2
	  cnt = mpz_scan1 (lhs, 0);
#else
	  cnt = 0;
#endif
	  if (cnt != 0)
	    {
	      if (y * cnt / cnt != y)
		goto pow_err;
	      mpz_tdiv_q_2exp (lhs, lhs, cnt);
	      mpz_pow_ui (r, lhs, y);
	      mpz_mul_2exp (r, r, y * cnt);
	    }
	  else
	    mpz_pow_ui (r, lhs, y);
	}
      mpz_clear (lhs); mpz_clear (rhs);
      return;
    pow_err:
      error = "result of `pow' operator too large";
      mpz_clear (lhs); mpz_clear (rhs);
      longjmp (errjmpbuf, 1);
    case GCD:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_gcd (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
#if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1
    case LCM:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_lcm (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
#endif
    case AND:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_and (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
    case IOR:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_ior (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
#if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1
    case XOR:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      mpz_xor (r, lhs, rhs);
      mpz_clear (lhs); mpz_clear (rhs);
      return;
#endif
    case NEG:
      mpz_eval_expr (r, e->operands.ops.lhs);
      mpz_neg (r, r);
      return;
    case NOT:
      mpz_eval_expr (r, e->operands.ops.lhs);
      mpz_com (r, r);
      return;
    case SQRT:
      mpz_init (lhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      if (mpz_sgn (lhs) < 0)
	{
	  error = "cannot take square root of negative numbers";
	  mpz_clear (lhs);
	  longjmp (errjmpbuf, 1);
	}
      mpz_sqrt (r, lhs);
      return;
#if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1
    case ROOT:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      if (mpz_sgn (rhs) <= 0)
	{
	  error = "cannot take non-positive root orders";
	  mpz_clear (lhs); mpz_clear (rhs);
	  longjmp (errjmpbuf, 1);
	}
      if (mpz_sgn (lhs) < 0 && (mpz_get_ui (rhs) & 1) == 0)
	{
	  error = "cannot take even root orders of negative numbers";
	  mpz_clear (lhs); mpz_clear (rhs);
	  longjmp (errjmpbuf, 1);
	}

      {
	unsigned long int nth = mpz_get_ui (rhs);
	if (mpz_cmp_ui (rhs, ~(unsigned long int) 0) > 0)
	  {
	    /* If we are asked to take an awfully large root order, cheat and
	       ask for the largest order we can pass to mpz_root.  This saves
	       some error prone special cases.  */
	    nth = ~(unsigned long int) 0;
	  }
	mpz_root (r, lhs, nth);
      }
      mpz_clear (lhs); mpz_clear (rhs);
      return;
#endif
    case FAC:
      mpz_eval_expr (r, e->operands.ops.lhs);
      if (mpz_size (r) > 1)
	{
	  error = "result of `!' operator too large";
	  longjmp (errjmpbuf, 1);
	}
      mpz_fac_ui (r, mpz_get_ui (r));
      return;
#if __GNU_MP_VERSION >= 2
    case POPCNT:
      mpz_eval_expr (r, e->operands.ops.lhs);
      { long int cnt;
	cnt = mpz_popcount (r);
	mpz_set_si (r, cnt);
      }
      return;
    case HAMDIST:
      { long int cnt;
	mpz_init (lhs); mpz_init (rhs);
	mpz_eval_expr (lhs, e->operands.ops.lhs);
	mpz_eval_expr (rhs, e->operands.ops.rhs);
	cnt = mpz_hamdist (lhs, rhs);
	mpz_clear (lhs); mpz_clear (rhs);
	mpz_set_si (r, cnt);
      }
      return;
#endif
    case LOG2:
      mpz_eval_expr (r, e->operands.ops.lhs);
      { unsigned long int cnt;
	if (mpz_sgn (r) <= 0)
	  {
	    error = "logarithm of non-positive number";
	    longjmp (errjmpbuf, 1);
	  }
	cnt = mpz_sizeinbase (r, 2);
	mpz_set_ui (r, cnt - 1);
      }
      return;
    case LOG:
      { unsigned long int cnt;
	mpz_init (lhs); mpz_init (rhs);
	mpz_eval_expr (lhs, e->operands.ops.lhs);
	mpz_eval_expr (rhs, e->operands.ops.rhs);
	if (mpz_sgn (lhs) <= 0)
	  {
	    error = "logarithm of non-positive number";
	    mpz_clear (lhs); mpz_clear (rhs);
	    longjmp (errjmpbuf, 1);
	  }
	if (mpz_cmp_ui (rhs, 256) >= 0)
	  {
	    error = "logarithm base too large";
	    mpz_clear (lhs); mpz_clear (rhs);
	    longjmp (errjmpbuf, 1);
	  }
	cnt = mpz_sizeinbase (lhs, mpz_get_ui (rhs));
	mpz_set_ui (r, cnt - 1);
	mpz_clear (lhs); mpz_clear (rhs);
      }
      return;
    case FERMAT:
      {
	unsigned long int t;
	mpz_init (lhs);
	mpz_eval_expr (lhs, e->operands.ops.lhs);
	t = (unsigned long int) 1 << mpz_get_ui (lhs);
	if (mpz_cmp_ui (lhs, ~(unsigned long int) 0) > 0 || t == 0)
	  {
	    error = "too large Mersenne number index";
	    mpz_clear (lhs);
	    longjmp (errjmpbuf, 1);
	  }
	mpz_set_ui (r, 1);
	mpz_mul_2exp (r, r, t);
	mpz_add_ui (r, r, 1);
	mpz_clear (lhs);
      }
      return;
    case MERSENNE:
      mpz_init (lhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      if (mpz_cmp_ui (lhs, ~(unsigned long int) 0) > 0)
	{
	  error = "too large Mersenne number index";
	  mpz_clear (lhs);
	  longjmp (errjmpbuf, 1);
	}
      mpz_set_ui (r, 1);
      mpz_mul_2exp (r, r, mpz_get_ui (lhs));
      mpz_sub_ui (r, r, 1);
      mpz_clear (lhs);
      return;
    case FIBONACCI:
      { mpz_t t;
	unsigned long int n, i;
	mpz_init (lhs);
	mpz_eval_expr (lhs, e->operands.ops.lhs);
	if (mpz_sgn (lhs) <= 0 || mpz_cmp_si (lhs, 1000000000) > 0)
	  {
	    error = "Fibonacci index out of range";
	    mpz_clear (lhs);
	    longjmp (errjmpbuf, 1);
	  }
	n = mpz_get_ui (lhs);
	mpz_clear (lhs);

#if __GNU_MP_VERSION > 2 || __GNU_MP_VERSION_MINOR >= 1
	mpz_fib_ui (r, n);
#else
	mpz_init_set_ui (t, 1);
	mpz_set_ui (r, 1);

	if (n <= 2)
	  mpz_set_ui (r, 1);
	else
	  {
	    for (i = 3; i <= n; i++)
	      {
		mpz_add (t, t, r);
		mpz_swap (t, r);
	      }
	  }
	mpz_clear (t);
#endif
      }
      return;
    case RANDOM:
      {
	unsigned long int n;
	mpz_init (lhs);
	mpz_eval_expr (lhs, e->operands.ops.lhs);
	if (mpz_sgn (lhs) <= 0 || mpz_cmp_si (lhs, 1000000000) > 0)
	  {
	    error = "random number size out of range";
	    mpz_clear (lhs);
	    longjmp (errjmpbuf, 1);
	  }
	n = mpz_get_ui (lhs);
	mpz_clear (lhs);
	mpz_urandomb (r, rstate, n);
      }
      return;
    case NEXTPRIME:
      {
	mpz_eval_expr (r, e->operands.ops.lhs);
	mpz_nextprime (r, r);
      }
      return;
    case BINOM:
      mpz_init (lhs); mpz_init (rhs);
      mpz_eval_expr (lhs, e->operands.ops.lhs);
      mpz_eval_expr (rhs, e->operands.ops.rhs);
      {
	unsigned long int k;
	if (mpz_cmp_ui (rhs, ~(unsigned long int) 0) > 0)
	  {
	    error = "k too large in (n over k) expression";
	    mpz_clear (lhs); mpz_clear (rhs);
	    longjmp (errjmpbuf, 1);
	  }
	k = mpz_get_ui (rhs);
	mpz_bin_ui (r, lhs, k);
      }
      mpz_clear (lhs); mpz_clear (rhs);
      return;
    case TIMING:
      {
	int t0;
	t0 = cputime ();
	mpz_eval_expr (r, e->operands.ops.lhs);
	printf ("time: %d\n", cputime () - t0);
      }
      return;
    default:
      abort ();
    }
}
Example #19
0
void factor_perfect_power(fact_obj_t *fobj, mpz_t b)
{
	// check if (b^1/i)^i == b for i = 2 to bitlen(b)
	uint32 bits = mpz_sizeinbase(b,2);
	uint32 i;
	FILE *flog;
	mpz_t base, ans;

	mpz_init(base);
	mpz_init(ans);

	//open the log file
	flog = fopen(fobj->flogname,"a");
	if (flog == NULL)
	{
		printf("fopen error: %s\n", strerror(errno));
		printf("could not open %s for writing\n",fobj->flogname);
		return;
	}

	for (i=2; i<bits; i++)
	{
		mpz_root(base, b, i);
		mpz_pow_ui(ans, base, i);
		if (mpz_cmp(ans, b) == 0)
		{
			// found a base.  				
			if (is_mpz_prp(base))
			{
				uint32 j;
				//gmp_printf("\nAdding prime base %Zd to factor list...\n", base);
				for (j=0; j<i; j++)
				{
					add_to_factor_list(fobj, base);
					mpz_tdiv_q(b, b, base);
					logprint(flog,"prp%d = %s\n",
						gmp_base10(base),
						mpz_conv2str(&gstr1.s, 10, base));
				}
			}
			else
			{
				// if composite, factor it and then multiply
				// all factors by i (the exponent).
				fact_obj_t *fobj_refactor;
				uint32 j;

				gmp_printf("\nFactoring composite base %Zd...\n", base);

				// load the new fobj with this number
				fobj_refactor = (fact_obj_t *)malloc(sizeof(fact_obj_t));
				init_factobj(fobj_refactor);
				mpz_set(fobj_refactor->N, base);

				// recurse on factor
				factor(fobj_refactor);

				// add all factors found during the refactorization
				for (j=0; j< fobj_refactor->num_factors; j++)
				{
					int k, c;
					//gmp_printf("\nAdding prime base %Zd to factor list...\n", 
					//	fobj_refactor->fobj_factors[j].factor);

					for (k=0; k < fobj_refactor->fobj_factors[j].count; k++)
					{
						// add i copies of it, since this was a perfect power
						for (c = 0; c < i; c++)
						{
							add_to_factor_list(fobj, fobj_refactor->fobj_factors[j].factor);
							mpz_tdiv_q(b, b, fobj_refactor->fobj_factors[j].factor);
							logprint(flog,"prp%d = %s\n",
								gmp_base10(fobj_refactor->fobj_factors[j].factor),
								mpz_conv2str(&gstr1.s, 10, fobj_refactor->fobj_factors[j].factor));
						}
					}
				}

				// free temps
				free_factobj(fobj_refactor);
				free(fobj_refactor);
			}
			break;
		}
	}

	mpz_clear(base);
	mpz_clear(ans);
	fclose(flog);

	return;
}
Example #20
0
int initv(void)
{
    int i,d,pak,k,maxp;
    double dp;

    mpz_inits(N, TA, D, R, V, P, X, Y, DG, IG, A, B, TB, TC, TD, NULL);

    nbts=8*sizeof(int);

    printf("Input N= \n");
    d=mpz_inp_str(N, stdin, 10); //待分解的整数
    if((mpz_probab_prime_p(N, qsieve->NTRY) ? TRUE : FALSE))
    {
        printf("N is prime!\n");
        return (-1);
    }

    if(d<8) mm=d; // 分解基的理想大小
    else if(d>20) mm=(d*d*d*d)/4096; 
    else mm=25;

    dp=(double)2*(double)(mm+100); // dp:生成素数的数量 +100 *2均是为了更加保险
    maxp=(int)(dp*(log(dp*log(dp)))); // 罗素上界 maxp
    qsieve_gprime(maxp);

    epr=(int *)qsieve_alloc(mm+1,sizeof(int));

    k=knuth(mm,epr,N,D);

    if(mpz_root(R, D, 2)) //检查完全平方数
    {
        printf("Factors are\n");
        qsieve_outnum(R,stdout);
        qsieve_divide(N,R,N);
        qsieve_outnum(N,stdout);
        return -1;
    }

    qsieve_gprime(0);

    mlf=2*mm;
//各种开空间,初始化
    r1=(int *)qsieve_alloc((mm+1),sizeof(int));
    r2=(int *)qsieve_alloc((mm+1),sizeof(int));
    rp=(int *)qsieve_alloc((mm+1),sizeof(int));
    b=(int *)qsieve_alloc((mm+1),sizeof(int));
    e=(int *)qsieve_alloc((mm+1),sizeof(int));

    logp=(unsigned char *)qsieve_alloc(mm+1,1);

    pr=(int *)qsieve_alloc((mlf+1),sizeof(int));
    hash=(int *)qsieve_alloc((2*mlf+1),sizeof(int));

    sieve=(unsigned char *)qsieve_alloc(SSIZE+1,1);

    x=(mpz_t *)qsieve_alloc(mm+1,sizeof(mpz_t));
    y=(mpz_t *)qsieve_alloc(mm+1,sizeof(mpz_t));
    z=(mpz_t *)qsieve_alloc(mlf+1,sizeof(mpz_t));
    w=(mpz_t *)qsieve_alloc(mlf+1,sizeof(mpz_t));

    for(i=0;i<=mm;i++)
    {
        mpz_init(x[i]);
        mpz_init(y[i]);
    }
    for(i=0;i<=mlf;i++)
    {
        mpz_init(z[i]);
        mpz_init(w[i]);
    }

    EE=(unsigned int **)qsieve_alloc(mm+1,sizeof(unsigned int *));
    G=(unsigned int **)qsieve_alloc(mlf+1,sizeof(unsigned int *));

    pak=1+mm/(8*sizeof(int));
    for(i=0;i<=mm;i++)
    {
        b[i]=(-1);
        EE[i]=(unsigned int *)qsieve_alloc(pak,sizeof(int));
    }

    for(i=0;i<=mlf;i++) G[i]=(unsigned int *)qsieve_alloc(pak,sizeof(int));
    return 1;
}
Example #21
0
      res = mpz_root (root1, x2, nth);

      mpz_urandomb (bs, rands, 4);
      bsi = mpz_get_ui (bs);
      if ((bsi & 1) != 0)
	{
	  /* With 50% probability, set x2 near a perfect power.  */
	  mpz_pow_ui (x2, root1, nth);
	  if ((bsi & 2) != 0)
	    {
	      mpz_sub_ui (x2, x2, bsi >> 2);
	      mpz_abs (x2, x2);
	    }
	  else
	    mpz_add_ui (x2, x2, bsi >> 2);
	  res = mpz_root (root1, x2, nth);
	}

      check_one (root1, x2, nth, res, i);

      if (((nth & 1) != 0) && ((bsi & 2) != 0))
	{
	  mpz_neg (x2, x2);
	  mpz_neg (root1, root1);
	  check_one (root1, x2, nth, res, i);
	}
    }

  mpz_clear (bs);
  mpz_clear (x2);
  mpz_clear (root1);
Example #22
0
BigFixedPoint BigFixedPoint::root(int root) const
{
    mpz_class res;
    mpz_root(res.get_mpz_t(), number.get_mpz_t(), root);
    return BigFixedPoint(res, decimalPlaces/root);
}
Example #23
0
/* Recursive routine to prove via ECPP */
static int ecpp_down(int i, mpz_t Ni, int facstage, IV* dlist, mpz_t* sfacs, int* nsfacs, char** prooftextptr)
{
  mpz_t a, b, u, v, m, q, minfactor, sqrtn, mD, t, t2;
  mpz_t mlist[6];
  UV nm1a;
  IV np1lp, np1lq;
  struct ec_affine_point P;
  int k, dnum, nidigits, facresult, curveresult, downresult, stage, D;
  int verbose = get_verbose_level();

  nidigits = mpz_sizeinbase(Ni, 10);

  k = _GMP_is_prob_prime(Ni);
  if (k == 0)  return 0;
  if (k == 2) {
    /* No need to put anything in the proof */
    if (verbose) printf("%*sN[%d] (%d dig)  PRIME\n", i, "", i, nidigits);
    return 2;
  }
  downresult = 0;

  if (verbose) {
    printf("%*sN[%d] (%d dig)", i, "", i, nidigits);
    if (facstage > 1) printf(" FS %d", facstage);
    fflush(stdout);
  }

  mpz_init(a);  mpz_init(b);
  mpz_init(u);  mpz_init(v);
  mpz_init(m);  mpz_init(q);
  mpz_init(mD); mpz_init(minfactor);  mpz_init(sqrtn);
  mpz_init(t);  mpz_init(t2);
  mpz_init(P.x);mpz_init(P.y);
  for (k = 0; k < 6; k++)
    mpz_init(mlist[k]);

  /* Any factors q found must be strictly > minfactor.
   * See Atkin and Morain, 1992, section 6.4 */
  mpz_root(minfactor, Ni, 4);
  mpz_add_ui(minfactor, minfactor, 1);
  mpz_mul(minfactor, minfactor, minfactor);
  mpz_sqrt(sqrtn, Ni);

  for (stage = (i == 0) ? facstage : 1; stage <= facstage; stage++) {
    int next_stage = (stage > 1) ? stage : 1;
    for (dnum = 0; dlist[dnum] != 0; dnum++) {
      int poly_type;  /* just for debugging/verbose */
      int poly_degree;
      D = -dlist[dnum];
      if (D > 1) continue;  /* Marked for skip */

      if (D == 1) {   /* n-1 test */
        mpz_sub_ui(m, Ni, 1);          /* m = N-1 */
        mpz_sub_ui(t2, sqrtn, 1);
        mpz_tdiv_q_2exp(t2, t2, 1);    /* t2 = minfactor */

        facresult = check_for_factor2(q, m, t2, t, stage, sfacs, nsfacs, 0);
        if (facresult <= 0)
          continue;
        if (verbose)
          { printf(" n-1\n"); fflush(stdout); }
        downresult = ecpp_down(i+1, q, next_stage, dlist, sfacs, nsfacs, prooftextptr);
        if (downresult == 0)     /* composite */
          goto end_down;
        if (downresult == 1) {   /* nothing found at this stage */
          if (verbose) {
            printf("%*sN[%d] (%d dig)", i, "", i, nidigits);
            if (facstage > 1) printf(" FS %d", facstage);
            fflush(stdout);
          }
          continue;
        }
        if (verbose)
          { printf("%*sN[%d] (%d dig) n-1", i, "", i, nidigits); fflush(stdout); }
        curveresult = _GMP_primality_bls_3(Ni, q, &nm1a);
        if (verbose) { printf("  %d\n", curveresult); fflush(stdout); }
        if ( ! curveresult ) {
          /* This ought not happen */
          dlist[dnum] = -2; /* skip this D value from now on */
          if (verbose) gmp_printf("\n  Could not prove n-1 with N = %Zd\n", D, Ni);
          downresult = 0;
          continue;
        }
        goto end_down;
      }
      if (D == -1) {  /* n+1 test */
        mpz_add_ui(m, Ni, 1);          /* m = N+1 */
        mpz_add_ui(t2, sqrtn, 1);
        mpz_tdiv_q_2exp(t2, t2, 1);    /* t2 = minfactor */

        facresult = check_for_factor2(q, m, t2, t, stage, sfacs, nsfacs, 0);
        if (facresult <= 0)
          continue;
        if (verbose)
          { printf(" n+1\n"); fflush(stdout); }
        downresult = ecpp_down(i+1, q, next_stage, dlist, sfacs, nsfacs, prooftextptr);
        if (downresult == 0)     /* composite */
          goto end_down;
        if (downresult == 1) {   /* nothing found at this stage */
          if (verbose) {
            printf("%*sN[%d] (%d dig)", i, "", i, nidigits);
            if (facstage > 1) printf(" FS %d", facstage);
            fflush(stdout);
          }
          continue;
        }
        if (verbose)
          { printf("%*sN[%d] (%d dig) n-1", i, "", i, nidigits); fflush(stdout); }
        curveresult = _GMP_primality_bls_15(Ni, q, &np1lp, &np1lq);
        if (verbose) { printf("  %d\n", curveresult); fflush(stdout); }
        if ( ! curveresult ) {
          /* This ought not happen */
          dlist[dnum] = -2; /* skip this D value from now on */
          if (verbose) gmp_printf("\n  Could not prove n-1 with N = %Zd\n", D, Ni);
          downresult = 0;
          continue;
        }
        goto end_down;
      }

      if ( (-D % 4) != 3 && (-D % 16) != 4 && (-D % 16) != 8 )
        croak("Invalid discriminant '%d' in list\n", D);
      /* D must also be squarefree in odd divisors, but assume it. */
      /* Make sure we can get a class polynomial for this D. */
      poly_degree = poly_class_poly(D, NULL, &poly_type);
      if (poly_degree == 0)  continue;
      /* We'll save time in the long run by not looking at big polys once
       * we've found a good path from the start.  TODO: Needs more tuning. */
      if (stage == 0 && i >= 0 && poly_degree > 2) break;
      if (facstage == 1) {
        if (i >  2 && nidigits < 1100 && poly_degree > 24)  break;
        if (i >  3 && nidigits <  950 && poly_degree > 15)  break;
        if (i >  4 && nidigits <  800 && poly_degree > 11)  break;
        if (i >  8 && nidigits <  700 && poly_degree >  9)  break;
        if (i > 16 && nidigits <  600 && poly_degree >  8)  break;
      }
      mpz_set_si(mD, D);
      /* (D/N) must be 1, and we have to have a u,v solution */
      if (mpz_jacobi(mD, Ni) != 1)
        continue;
      if ( ! modified_cornacchia(u, v, mD, Ni) )
        continue;

      if (verbose > 1)
        { printf(" %d", D); fflush(stdout); }

      choose_m(mlist, D, u, v, Ni, t, t2);
      for (k = 0; k < 6; k++) {
        facresult = check_for_factor2(q, mlist[k], minfactor, t, stage, sfacs, nsfacs, poly_degree);
        /* -1 = couldn't find, 0 = no big factors, 1 = found */
        if (facresult <= 0)
          continue;
        mpz_set(m, mlist[k]);
        if (verbose)
          { printf(" %d (%s %d)\n", D, (poly_type == 1) ? "Hilbert" : "Weber", poly_degree); fflush(stdout); }
        /* Great, now go down. */
        downresult = ecpp_down(i+1, q, next_stage, dlist, sfacs, nsfacs, prooftextptr);
        if (downresult == 0)     /* composite */
          goto end_down;
        if (downresult == 1) {   /* nothing found at this stage */
          if (verbose) {
            printf("%*sN[%d] (%d dig)", i, "", i, nidigits);
            if (facstage > 1) printf(" FS %d", facstage);
            fflush(stdout);
          }
          continue;
        }

        /* Awesome, we found the q chain and are in STAGE 2 */
        if (verbose)
          { printf("%*sN[%d] (%d dig) %d (%s %d)", i, "", i, nidigits, D, (poly_type == 1) ? "Hilbert" : "Weber", poly_degree); fflush(stdout); }

        curveresult = find_curve(a, b, P.x, P.y, D, m, q, Ni);
        if (verbose) { printf("  %d\n", curveresult); fflush(stdout); }
        if (curveresult == 1) {
          /* Oh no!  We can't find a point on the curve.  Something is right
           * messed up, and we've wasted a lot of time.  Sigh. */
          dlist[dnum] = -2; /* skip this D value from now on */
          if (verbose) gmp_printf("\n  Invalidated D = %d with N = %Zd\n", D, Ni);
          downresult = 0;
          continue;
        }
        /* We found it was composite or proved it */
        goto end_down;
      } /* k loop for D */
    } /* D */
  } /* fac stage */
  /* Nothing at this level */
  downresult = 1;
  if (verbose) { printf(" ---\n"); fflush(stdout); }

end_down:

  if (downresult == 2) {
    if (0 && verbose > 1) {
      if (D == 1) {
        gmp_printf("\n");
        gmp_printf("Type BLS3\n");
        gmp_printf("N  %Zd\n", Ni);
        gmp_printf("Q  %Zd\n", q);
        gmp_printf("A  %lu\n", (unsigned long) nm1a);
        gmp_printf("\n");
        fflush(stdout);
      } else if (D == -1) {
        gmp_printf("\n");
        gmp_printf("Type BLS15\n");
        gmp_printf("N  %Zd\n", Ni);
        gmp_printf("Q  %Zd\n", q);
        gmp_printf("LP %ld\n", (signed long) np1lp);
        gmp_printf("LQ %ld\n", (signed long) np1lq);
        gmp_printf("\n");
        fflush(stdout);
      } else {
        gmp_printf("\n");
        gmp_printf("Type ECPP\n");
        gmp_printf("N  %Zd\n", Ni);
        gmp_printf("A  %Zd\n", a);
        gmp_printf("B  %Zd\n", b);
        gmp_printf("M  %Zd\n", m);
        gmp_printf("Q  %Zd\n", q);
        gmp_printf("X  %Zd\n", P.x);
        gmp_printf("Y  %Zd\n", P.y);
        gmp_printf("\n");
        fflush(stdout);
      }
    }
    /* Prepend our proof to anything that exists. */
    if (prooftextptr != 0) {
      char *proofstr, *proofptr;
      int curprooflen = (*prooftextptr == 0) ? 0 : strlen(*prooftextptr);

      if (D == 1) {
        int myprooflen = 20 + 2*(4 + mpz_sizeinbase(Ni, 10)) + 1*21;
        New(0, proofstr, myprooflen + curprooflen + 1, char);
        proofptr = proofstr;
        proofptr += gmp_sprintf(proofptr, "Type BLS3\nN  %Zd\nQ  %Zd\nA  %"UVuf"\n", Ni, q, nm1a);
      } else if (D == -1) {
BigNumberBase BigNumberBase::pow(const BigNumberBase& powNum, int32_t prec, PrecFlag flag)
{
	if (prec == -1)
	{
		prec = Calc::PRECISE;
	}
	BigNumberBase result;
	if (BigNumberBase::Compare(powNum, "0") == EQUAL)
	{
		result = "1";
		result.setPrec(prec, flag);
		return result;
	}
	
	BigNumberBase powNumTemp = powNum;
	bool powIsMinus = (BigNumberBase::Compare(powNumTemp, "0") == SMALL);
	if (powIsMinus)
	{
		powNumTemp = mul(powNumTemp, "-1");
		std::string sds = powNumTemp.toString();
		sds = sds;
	}
	powNumTemp.m_prec = 0;
	unsigned long int index = strtoul(powNumTemp.toString().c_str(), nullptr, 10);
	unsigned long int indexNum = (unsigned long int)::pow(10, powNum.m_prec);
	
	bool isMinus = (BigNumberBase::Compare(*this, "0") == SMALL);
	if (isMinus)
	{
		//先判断是否有效
		unsigned long int indexBk = index;
		unsigned long int indexNumBk = indexNum;
		while (indexBk % 2 == 0 && indexNumBk % 2 == 0)
		{
			indexBk = indexBk / 2;
			indexNumBk = indexNumBk / 2;
		}
		if (indexBk % 2 == 0)
		{
			isMinus = false;
		}
		else
		{
			BigNumberBase resultBk = result;
			mpz_pow_ui(resultBk.m_gmp->m_integer, m_gmp->m_integer, indexBk);
			mpz_root(resultBk.m_gmp->m_integer, resultBk.m_gmp->m_integer, indexNumBk);
			isMinus = true;
		}
		*this = mul(*this, "-1");
	}
	
	mpz_pow_ui(result.m_gmp->m_integer, m_gmp->m_integer, index);
	GmpInt::TenExp(result.m_gmp->m_integer, (unsigned long int)::pow(10, powNum.m_prec) * (prec + Calc::PRECISE));
	unsigned long int exp = (unsigned long int)::pow(10, powNum.m_prec);
	mpz_root(result.m_gmp->m_integer, result.m_gmp->m_integer, exp);
	result.m_prec = prec + Calc::PRECISE;

	BigNumberBase divisorMultiple = "1";
	GmpInt::TenExp(divisorMultiple.m_gmp->m_integer, m_prec);
	mpz_pow_ui(divisorMultiple.m_gmp->m_integer, divisorMultiple.m_gmp->m_integer, index);
	GmpInt::TenExp(divisorMultiple.m_gmp->m_integer, exp * (prec + Calc::PRECISE));
	mpz_root(divisorMultiple.m_gmp->m_integer, divisorMultiple.m_gmp->m_integer, exp);
	divisorMultiple.m_prec = prec + Calc::PRECISE;

	result = result.div(divisorMultiple, prec + Calc::PRECISE, flag);

	if (powIsMinus)
	{
		BigNumberBase minusRoot = "1";
		result = minusRoot.div(result, prec + Calc::PRECISE, flag);
	}

	result.setPrec(prec);
	if (isMinus)
	{
		result = mul(result, "-1");
	}
	
	return result;
}
Example #25
0
void poly_init(QS_t * qs_inf, poly_t * poly_inf, mpz_t N)
{
   unsigned long num_primes = qs_inf->num_primes;
   unsigned long s = (qs_inf->bits-1)/28+1;
   if (s <= 2) s = 3;
	prime_t * factor_base = qs_inf->factor_base;
   unsigned long fact_approx, fact, span;
   unsigned long sieve_size = qs_inf->sieve_size;
   unsigned long small_primes = qs_inf->small_primes;
   long min; 
   
   poly_inf->s = s;
     
   poly_inf->B = (unsigned long*) flint_stack_alloc(qs_inf->prec+1);  
   poly_inf->B_terms = (unsigned long*) flint_stack_alloc(s*(qs_inf->prec+1));  
   poly_inf->A = (unsigned long*) flint_stack_alloc(qs_inf->prec+1);  
   poly_inf->target_A = (unsigned long*) flint_stack_alloc(qs_inf->prec+1);  
   
   poly_inf->A_ind = (unsigned long*) flint_stack_alloc(s);  
   poly_inf->A_modp = (unsigned long*) flint_stack_alloc(s);  
   poly_inf->A_inv2B = (uint32_t**) flint_stack_alloc(s); 
   poly_inf->inv_p2 = (double*) flint_stack_alloc_bytes(s*sizeof(double));  
   poly_inf->A_inv = (uint32_t *) flint_stack_alloc_bytes(num_primes*sizeof(uint32_t));  
   poly_inf->soln1 = (uint32_t *) flint_stack_alloc_bytes(num_primes*sizeof(uint32_t)); 
   poly_inf->soln2 = (uint32_t *) flint_stack_alloc_bytes(num_primes*sizeof(uint32_t)); 
   poly_inf->posn1 = (uint32_t *) flint_stack_alloc_bytes(num_primes*sizeof(uint32_t)); 
   poly_inf->posn2 = (uint32_t *) flint_stack_alloc_bytes(num_primes*sizeof(uint32_t)); 
   
   uint32_t ** A_inv2B = poly_inf->A_inv2B;
   
   A_inv2B[0] = (uint32_t *) flint_stack_alloc_bytes(num_primes*s*sizeof(uint32_t));
   
   mpz_init(poly_inf->A_mpz);
   mpz_init(poly_inf->B_mpz);
   mpz_init(poly_inf->C);
   
   for (unsigned long i = 1; i < s; i++)
   {
      A_inv2B[i] = A_inv2B[i-1] + num_primes;
   } 
 
   mpz_t temp;
   mpz_init(temp); 
   
   mpz_mul_ui(temp, N, 2*qs_inf->k);
   mpz_sqrt(temp, temp);
   
   mpz_div_ui(temp, temp, 47*sieve_size/100);
   mpz_to_fmpz(poly_inf->target_A, temp);
   
   mpz_root(temp, temp, s);
   fact_approx = mpz_get_ui(temp);
   
   for (fact = 0; fact_approx >= factor_base[fact].p; fact++); 
   
   span = num_primes/s/s/2;
   if (span < 6*s) span = 6*s;
   min = fact - span/2;
   if (min < (long) small_primes) min = small_primes;
   if (min + span >= qs_inf->num_primes - 1) span = num_primes - min - 1;
   fact = min + span/2;

#if POLY_PARAMS   
   printf("min = FB[%ld], span = %ld, number of factors = %ld\n", min, span, s);
#endif
   
   poly_inf->min = min;
   poly_inf->fact = fact;
   poly_inf->span = span;
          
   mpz_clear(temp); 
}
void PellSolution (int num, int CurrentIndex, mpz_t *x) // Find x of theFundamental solutions of Pell's solution
{
     static int m, d, a;
     static int iterations [MAXITERATION];
     int i;
     static mpz_t CurrentDenominator, PvDenominator, PpvDenominator;
     static mpz_t Numerator; // Store denominators of the current try and the 2 convergents before the current try.

     static mpz_t ADenominator, DenominatorSq, NumeratorSq;
     static mpz_t comp_ADenominator, comp_DenominatorSq, comp_NumeratorSq;
     // These variables are calculation intermediates. The exact uses can be found in the comments below
     
     if (CurrentIndex < MAXITERATION) {
          if (CurrentIndex == 0) {
               mpz_init (CurrentDenominator);
               mpz_init (PvDenominator);
               mpz_init (PpvDenominator);
               mpz_init (ADenominator);
               mpz_init (DenominatorSq);
               mpz_init (NumeratorSq);
               mpz_init (comp_ADenominator);
               mpz_init (comp_DenominatorSq);
               mpz_init (comp_NumeratorSq);
               mpz_init (Numerator); // Initialisation
               for (i = 0; i < MAXITERATION; i++)
                    iterations [i] = 0; //Re-initialise iteration lists
               if ((int) sqrt(num) == sqrt(num)) {
                    return;
               } else {
                    m = 0, d = 1; a = sqrt(num);
                    mpz_set_ui (CurrentDenominator, 1);
                    mpz_set_ui (PpvDenominator, 0);
                    mpz_set_ui (PvDenominator, 0);
               }
          } else {
               m = d * a - m;
               d = (num - m * m) / d;
               a = (sqrt(num) + m) / d; // Core computations of this algorithm: Same as Problem 64
               if (CurrentIndex == 1)
                    mpz_set_ui (CurrentDenominator, a);
               else {
                    mpz_mul_ui (ADenominator, PvDenominator, a);
                    mpz_add (CurrentDenominator, ADenominator, PpvDenominator);
               }
          }
          mpz_pow_ui (DenominatorSq, CurrentDenominator, 2);
          mpz_mul_ui (DenominatorSq, DenominatorSq, num);
          mpz_add_ui (NumeratorSq, DenominatorSq, 1);
          mpz_root (Numerator, NumeratorSq, 2); // cond is the sqrt of CondSq with fractional parts truncated
          // numerator = sqrt (pow (denominators, 2) * num + 1); (1)
          mpz_pow_ui (comp_NumeratorSq, Numerator, 2);
          mpz_pow_ui (comp_DenominatorSq, CurrentDenominator, 2);
          mpz_mul_ui (comp_ADenominator, comp_DenominatorSq, num);
          mpz_add_ui (comp_ADenominator, comp_ADenominator, 1);
          // pow (denominators, 2) * num + 1; (2)
          // (1), (2) are derived from Pell's identity x^2 - Dy^2 = 1. Since (x/y) is the approximation of sqrt(D), x is numerator and y and denominator. Hence x = sqrt (1 + Dy^2) --- (1). We only keep the integer part of x.
          if (mpz_cmp (comp_NumeratorSq, comp_ADenominator) == 0) {
               // (1) == (2) implies that numerator w/o fraction parts is equal to cond itself, which implies that numerator does not have fractional part and is hence an integer. Given that denominator is set to be integer, this pair of Den and Num is a solution to the Pell's equation
               mpz_set (*x, Numerator);
               return;
          } else {
               iterations [CurrentIndex] = a;
               mpz_set (PpvDenominator, PvDenominator);
               mpz_set (PvDenominator, CurrentDenominator);
               mpz_set_ui (CurrentDenominator, 0); // Push one back
               PellSolution(num, CurrentIndex + 1, x);
          }
     } else {
          printf ("Number %d:Maximum Iteration Reached\n", num);
          return;
     }
}
Example #27
0
std::vector<mpz_class> Sieve::Factor()
{
	unsigned long int first = 0;
	int iter = 0;

#ifdef PRINT
					std::cout << "beginning to factor"<< std::endl;
					std::cout << "num smooth required: " << numsmoothrequired << std::endl;
					std::cout << "MAXSWEEPS: " << MAXSWEEPS << std::endl;
#endif
	while (numsmooth < numsmoothrequired && iter++ < MAXSWEEPS)
	{
		Sweep(first);
		updateThreshhold();
		first += SIEVESIZE;
	}
#ifdef PRINT
					std::cout << iter <<  " sweeps done"<< std::endl;
#endif
	std::vector<mpz_class> factors;
	std::vector<int> nullvec;
#ifdef PRINT
					std::cout << "num smooth found: " << numsmooth << std::endl;
					std::cout << "num tried: " << numtried << std::endl;
#endif
	if (numsmooth == numsmoothrequired)
	{
		mpz_class a, b, ab, factor1;
		matrixptr->gauss();
		for (int i = 0; i < 20 && matrixptr->hasMoreSolutions(); ++i)
		{
			nullvec = matrixptr->getNextSolution();
			a = 1;
			b = 1;
			for (int j = 0; j < nullvec.size(); j++)
			{
				if (nullvec[j] == 1)
				{
					a = (a * smooth_x[j]);
					b = (b * smooth_y[j]);
				}
			}
			mpz_root(b.get_mpz_t(), b.get_mpz_t(), 2);
			ab = a - b;
			mpz_abs(ab.get_mpz_t(), ab.get_mpz_t());
			mpz_gcd(factor1.get_mpz_t(), ab.get_mpz_t(), N.get_mpz_t());

			if (factor1 != 1 && factor1 != N)
			{
				bool exists = false;
				for (std::vector<mpz_class>::iterator it = factors.begin(); it != factors.end(); ++it)
				{
					if ((*it) == factor1)
					{
						exists = true;
						break;
					}
				}
				if (!exists)
				{
					factors.push_back(factor1);
					i = 0;
				}
			}
		}
	}
	return factors;
}
/*
Hauptfunktion
*/
int main (void) {

  // Zahl von der Konsole einlesen und in number speichern
  char *n = (char*) malloc((MAXDIGITS+1)*sizeof(char));
  size_t maxDigits = MAXDIGITS;
  printf("Bitte gib eine zu pruefende Zahl ein: ");
  getline(&n, &maxDigits, stdin);
  int ret = mpz_init_set_str(number, n, 10);

  // Speicher wieder freigeben und Fehlerpruefung
  if (n != NULL) free(n);
  if (ret < 0) {
    printf("Fehler bei der Zuweisung der eingegebenen Zahl! Abbruch.\n");
    mpz_clear(number);
    return ret;
  }

  mpz_out_str(stdout, 10, number);
  printf(" ist... ");
  // 0 und 1 sind keine Primzahlen
  // 2 und 3 sind es hingegen
  if (mpz_cmp_si(number,0) == 0 || mpz_cmp_si(number,1) == 0) {
    printf("keine Primzahl.\n");
    mpz_clear(number);
    return EXIT_SUCCESS;
  } else if (mpz_cmp_si(number,2) == 0 || mpz_cmp_si(number,3) == 0) {
    printf("eine Primzahl.\n");
    mpz_clear(number);
    return EXIT_SUCCESS;
  }

  // Gerade Zahlen koennen sofort als nicht-prim erkannt werden
  mpz_t rest;
  mpz_init(rest);
  if (mpz_mod_ui(rest, number, 2) == 0) {
    printf("keine Primzahl.\n");
    mpz_clear(number);
    mpz_clear(rest);
    return EXIT_SUCCESS;
  } else mpz_clear(rest);

  // Grenzen fuer die Kandidaten moeglicher Teiler festlegen
  mpz_t bis;
  mpz_init(bis);
  // maximaler Teiler ist sqrt(number)
  mpz_root(bis, number, 2);
  mpz_add_ui(bis, bis, 1);

  // ist die Zahl kleiner als INT_MAX, brauchen wir nur einen Thread
  // -> Test ohnehin wenig aufwendig
  // -> auch fuer sehr triviale Festlegung der Suchgrenzen notwendig/hilfreich (s.u.)
  if (mpz_cmp_ui(number, INT_MAX) < 0) ANZTHREADS = 1;

  // ein paar Vorbereitungen
  pthread_t *threads = (pthread_t*) malloc(ANZTHREADS*sizeof(pthread_t));
  anf = (mpz_t*) malloc(ANZTHREADS*sizeof(mpz_t));
  ende = (mpz_t*) malloc(ANZTHREADS*sizeof(mpz_t));
  int i = 0;
  int *nr = (int*) malloc(ANZTHREADS*sizeof(int));;

  // Threads erzeugen
  // Achtung: so klappt es nur, wenn ANZTHREADS < sqrt(number)+3
  // Hinweis: Wenn number<INT_MAX, dann gilt eh ANZTHREADS==1 (s.o.)
  for (i = 0; i < ANZTHREADS; i++) {

    // Suchgrenzen fuer die Threads festlegen
    mpz_init(anf[i]);
    mpz_init(ende[i]);
    if (i == 0) {
      mpz_add_ui(anf[i], anf[i], 3);
    } else {
      mpz_cdiv_q_ui(anf[i], bis, ANZTHREADS);
      mpz_mul_ui(anf[i], anf[i], i);
    }
    mpz_cdiv_q_ui(ende[i], bis, ANZTHREADS);
    mpz_mul_ui(ende[i], ende[i], i+1);

    // Jeder Thread fuehrt "pruefeTeiler" aus.
    // Seine Ordnungsnummer wird ihm als Parameter uebergeben
    // -> dient zum Auslesen der Suchgrenzen des jeweiligen Threads
    nr[i]=i;
    pthread_create(&(threads[i]), NULL, pruefeTeiler, &nr[i]);
  }

  // Warten bis alle Threads zurueckgekehrt sind
  for (i = 0; i < ANZTHREADS; i++) {
    pthread_join(threads[i], NULL);
  }

  // Ergebnis ausgeben
  if (found) {
    printf("keine Primzahl.\n");
  } else {
    printf("eine Primzahl.\n");
  }

  // aufraeumen
  mpz_clear(bis);
  mpz_clear(number);
  for (i = 0; i < ANZTHREADS; i++) {
    mpz_clear(anf[i]);
    mpz_clear(ende[i]);
  }
  if (threads != NULL) free(threads);
  if (anf != NULL) free(anf);
  if (ende != NULL) free(ende);
  if (nr != NULL) free(nr);

  // Ende
  return EXIT_SUCCESS;
}
Example #29
0
int
mpfr_cbrt (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
{
  mpz_t m;
  mpfr_exp_t e, r, sh;
  mpfr_prec_t n, size_m, tmp;
  int inexact, negative;
  MPFR_SAVE_EXPO_DECL (expo);

  MPFR_LOG_FUNC (
    ("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (x), mpfr_log_prec, x, rnd_mode),
    ("y[%Pu]=%.*Rg inexact=%d", mpfr_get_prec (y), mpfr_log_prec, y,
     inexact));

  /* special values */
  if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
    {
      if (MPFR_IS_NAN (x))
        {
          MPFR_SET_NAN (y);
          MPFR_RET_NAN;
        }
      else if (MPFR_IS_INF (x))
        {
          MPFR_SET_INF (y);
          MPFR_SET_SAME_SIGN (y, x);
          MPFR_RET (0);
        }
      /* case 0: cbrt(+/- 0) = +/- 0 */
      else /* x is necessarily 0 */
        {
          MPFR_ASSERTD (MPFR_IS_ZERO (x));
          MPFR_SET_ZERO (y);
          MPFR_SET_SAME_SIGN (y, x);
          MPFR_RET (0);
        }
    }

  /* General case */
  MPFR_SAVE_EXPO_MARK (expo);
  mpz_init (m);

  e = mpfr_get_z_2exp (m, x);                /* x = m * 2^e */
  if ((negative = MPFR_IS_NEG(x)))
    mpz_neg (m, m);
  r = e % 3;
  if (r < 0)
    r += 3;
  /* x = (m*2^r) * 2^(e-r) = (m*2^r) * 2^(3*q) */

  MPFR_MPZ_SIZEINBASE2 (size_m, m);
  n = MPFR_PREC (y) + (rnd_mode == MPFR_RNDN);

  /* we want 3*n-2 <= size_m + 3*sh + r <= 3*n
     i.e. 3*sh + size_m + r <= 3*n */
  sh = (3 * (mpfr_exp_t) n - (mpfr_exp_t) size_m - r) / 3;
  sh = 3 * sh + r;
  if (sh >= 0)
    {
      mpz_mul_2exp (m, m, sh);
      e = e - sh;
    }
  else if (r > 0)
    {
      mpz_mul_2exp (m, m, r);
      e = e - r;
    }

  /* invariant: x = m*2^e, with e divisible by 3 */

  /* we reuse the variable m to store the cube root, since it is not needed
     any more: we just need to know if the root is exact */
  inexact = mpz_root (m, m, 3) == 0;

  MPFR_MPZ_SIZEINBASE2 (tmp, m);
  sh = tmp - n;
  if (sh > 0) /* we have to flush to 0 the last sh bits from m */
    {
      inexact = inexact || ((mpfr_exp_t) mpz_scan1 (m, 0) < sh);
      mpz_fdiv_q_2exp (m, m, sh);
      e += 3 * sh;
    }

  if (inexact)
    {
      if (negative)
        rnd_mode = MPFR_INVERT_RND (rnd_mode);
      if (rnd_mode == MPFR_RNDU || rnd_mode == MPFR_RNDA
          || (rnd_mode == MPFR_RNDN && mpz_tstbit (m, 0)))
        inexact = 1, mpz_add_ui (m, m, 1);
      else
        inexact = -1;
    }

  /* either inexact is not zero, and the conversion is exact, i.e. inexact
     is not changed; or inexact=0, and inexact is set only when
     rnd_mode=MPFR_RNDN and bit (n+1) from m is 1 */
  inexact += mpfr_set_z (y, m, MPFR_RNDN);
  MPFR_SET_EXP (y, MPFR_GET_EXP (y) + e / 3);

  if (negative)
    {
      MPFR_CHANGE_SIGN (y);
      inexact = -inexact;
    }

  mpz_clear (m);
  MPFR_SAVE_EXPO_FREE (expo);
  return mpfr_check_range (y, inexact, rnd_mode);
}
Example #30
0
int
mpz_perfect_power_p (mpz_srcptr u)
{
  unsigned long int prime;
  unsigned long int n, n2;
  int i;
  unsigned long int rem;
  mpz_t u2, q;
  int exact;
  mp_size_t uns;
  mp_size_t usize = SIZ (u);
  TMP_DECL;

  if (mpz_cmpabs_ui (u, 1) <= 0)
    return 1;			/* -1, 0, and +1 are perfect powers */

  n2 = mpz_scan1 (u, 0);
  if (n2 == 1)
    return 0;			/* 2 divides exactly once.  */

  TMP_MARK;

  uns = ABS (usize) - n2 / BITS_PER_MP_LIMB;
  MPZ_TMP_INIT (q, uns);
  MPZ_TMP_INIT (u2, uns);

  mpz_tdiv_q_2exp (u2, u, n2);
  mpz_abs (u2, u2);

  if (mpz_cmp_ui (u2, 1) == 0)
    {
      TMP_FREE;
      /* factoring completed; consistent power */
      return ! (usize < 0 && POW2P(n2));
    }

  if (isprime (n2))
    goto n2prime;

  for (i = 1; primes[i] != 0; i++)
    {
      prime = primes[i];

      if (mpz_cmp_ui (u2, prime) < 0)
	break;

      if (mpz_divisible_ui_p (u2, prime))	/* divisible by this prime? */
	{
	  rem = mpz_tdiv_q_ui (q, u2, prime * prime);
	  if (rem != 0)
	    {
	      TMP_FREE;
	      return 0;		/* prime divides exactly once, reject */
	    }
	  mpz_swap (q, u2);
	  for (n = 2;;)
	    {
	      rem = mpz_tdiv_q_ui (q, u2, prime);
	      if (rem != 0)
		break;
	      mpz_swap (q, u2);
	      n++;
	    }

	  n2 = gcd (n2, n);
	  if (n2 == 1)
	    {
	      TMP_FREE;
	      return 0;		/* we have multiplicity 1 of some factor */
	    }

	  if (mpz_cmp_ui (u2, 1) == 0)
	    {
	      TMP_FREE;
	      /* factoring completed; consistent power */
	      return ! (usize < 0 && POW2P(n2));
	    }

	  /* As soon as n2 becomes a prime number, stop factoring.
	     Either we have u=x^n2 or u is not a perfect power.  */
	  if (isprime (n2))
	    goto n2prime;
	}
    }

  if (n2 == 0)
    {
      /* We found no factors above; have to check all values of n.  */
      unsigned long int nth;
      for (nth = usize < 0 ? 3 : 2;; nth++)
	{
	  if (! isprime (nth))
	    continue;
#if 0
	  exact = mpz_padic_root (q, u2, nth, PTH);
	  if (exact)
#endif
	    exact = mpz_root (q, u2, nth);
	  if (exact)
	    {
	      TMP_FREE;
	      return 1;
	    }
	  if (mpz_cmp_ui (q, SMALLEST_OMITTED_PRIME) < 0)
	    {
	      TMP_FREE;
	      return 0;
	    }
	}
    }
  else
    {
      unsigned long int nth;

      if (usize < 0 && POW2P(n2))
	{
	  TMP_FREE;
	  return 0;
	}

      /* We found some factors above.  We just need to consider values of n
	 that divides n2.  */
      for (nth = 2; nth <= n2; nth++)
	{
	  if (! isprime (nth))
	    continue;
	  if (n2 % nth != 0)
	    continue;
#if 0
	  exact = mpz_padic_root (q, u2, nth, PTH);
	  if (exact)
#endif
	    exact = mpz_root (q, u2, nth);
	  if (exact)
	    {
	      if (! (usize < 0 && POW2P(nth)))
		{
		  TMP_FREE;
		  return 1;
		}
	    }
	  if (mpz_cmp_ui (q, SMALLEST_OMITTED_PRIME) < 0)
	    {
	      TMP_FREE;
	      return 0;
	    }
	}

      TMP_FREE;
      return 0;
    }

n2prime:
  if (usize < 0 && POW2P(n2))
    {
      TMP_FREE;
      return 0;
    }

  exact = mpz_root (NULL, u2, n2);
  TMP_FREE;
  return exact;
}