Пример #1
0
/* computes R(n) = exp(-n)/n * sum(k!/(-n)^k, k=0..n-2)
   with error at most 4*ulp(x). Assumes n>=2.
   Since x <= exp(-n)/n <= 1/8, then 4*ulp(x) <= ulp(1).
*/
static void
mpfr_const_euler_R (mpfr_t x, unsigned long n)
{
  unsigned long k, m;
  mpz_t a, s;
  mpfr_t y;

  MPFR_ASSERTN (n >= 2); /* ensures sum(k!/(-n)^k, k=0..n-2) >= 2/3 */

  /* as we multiply the sum by exp(-n), we need only PREC(x) - n/LOG2 bits */
  m = MPFR_PREC(x) - (unsigned long) ((double) n / LOG2);

  mpz_init_set_ui (a, 1);
  mpz_mul_2exp (a, a, m);
  mpz_init_set (s, a);

  for (k = 1; k <= n; k++)
    {
      mpz_mul_ui (a, a, k);
      mpz_fdiv_q_ui (a, a, n);
      /* the error e(k) on a is e(k) <= 1 + k/n*e(k-1) with e(0)=0,
         i.e. e(k) <= k */
      if (k % 2)
        mpz_sub (s, s, a);
      else
        mpz_add (s, s, a);
    }
  /* the error on s is at most 1+2+...+n = n*(n+1)/2 */
  mpz_fdiv_q_ui (s, s, n); /* err <= 1 + (n+1)/2 */
  MPFR_ASSERTN (MPFR_PREC(x) >= mpz_sizeinbase(s, 2));
  mpfr_set_z (x, s, MPFR_RNDD); /* exact */
  mpfr_div_2ui (x, x, m, MPFR_RNDD);
  /* now x = 1/n * sum(k!/(-n)^k, k=0..n-2) <= 1/n */
  /* err(x) <= (n+1)/2^m <= (n+1)*exp(n)/2^PREC(x) */

  mpfr_init2 (y, m);
  mpfr_set_si (y, -(long)n, MPFR_RNDD); /* assumed exact */
  mpfr_exp (y, y, MPFR_RNDD); /* err <= ulp(y) <= exp(-n)*2^(1-m) */
  mpfr_mul (x, x, y, MPFR_RNDD);
  /* err <= ulp(x) + (n + 1 + 2/n) / 2^prec(x)
     <= ulp(x) + (n + 1 + 2/n) ulp(x)/x since x*2^(-prec(x)) < ulp(x)
     <= ulp(x) + (n + 1 + 2/n) 3/(2n) ulp(x) since x >= 2/3*n for n >= 2
     <= 4 * ulp(x) for n >= 2 */
  mpfr_clear (y);

  mpz_clear (a);
  mpz_clear (s);
}
Пример #2
0
int main( void )
{
    
    mpz_t num, digit;
    unsigned long long sum;

    mpz_init( num );
    mpz_init( digit );
    sum = 0;

    /******************************************************
     *  void mpz_fac_ui (mpz_t rop, unsigned long int op)
     *  
     *  -> Sets 'rop'  to 'op!'
     *
     ******************************************************/
    mpz_fac_ui( num, 100 );
    

    while( mpz_sgn( num ) ) // while num > 0
    {
        sum += mpz_mod_ui( digit, num, 10 );
        mpz_fdiv_q_ui( num, num, 10 );
    }

    printf( "Answer: %llu\n", sum );

    mpz_clear( num );
    return 0;
}
Пример #3
0
int main(void)
{
    mpz_t base;
    mpz_t exponent;
    mpz_t arrows;
    mpz_t result;

    mpz_init(base);
    mpz_init(exponent);
    mpz_init(arrows);
    mpz_init(result);

    mpz_set_ui(base, 2L);
    mpz_set_ui(arrows, 2L);
    mpz_set_ui(exponent, 5L);

    arrow(result, base, exponent, arrows);

    gmp_printf("%Zd\n", result);

    int digit = 0;
    while (mpz_cmp_ui(result, 1L) >= 0) {
        digit++;
        mpz_fdiv_q_ui(result, result, 10UL);
    }
    gmp_printf("%d digits\n%", digit);

    return 0;
}
Пример #4
0
void decode_all(int* array, header h, int level)
{
	if(!level)
	{
		return finish(array);
	}
	
	int* new_array = malloc(sizeof(int)*headers[level-1].size);
	int index = 0;
	mpz_t number, spill;
	mpz_init(number);
	mpz_init(spill);	
	for(int i = 0; i < h.size; i++)
	{
		mpz_ui_pow_ui(spill, 2, M);
		mpz_set(number, remainders[level-1][i]);
		mpz_addmul_ui(number, spill, array[i]);
		int min = headers[level-1].chunksize > (headers[level-1].size - index)?(headers[level-1].size - index):headers[level-1].chunksize;
		
		for(int j = 0; j < min; j++)
		{
			new_array[index + min - j - 1] = mpz_fdiv_q_ui(number, number, headers[level-1].K);
		}
		index += min;
	} 
	return decode_all(new_array, headers[level - 1], level - 1);
}
Пример #5
0
void calcterm(int n,mpz_t r) {
	int i;
	mpz_set_ui(r,0);
	for(i=1;(long long)i*i<=n;i++) if(n%i==0) {
		calc(i,n,r);
		if(i!=n/i) calc(n/i,n,r);
	}
	mpz_fdiv_q_ui(r,r,2*n);
}
Пример #6
0
/* assuming b[0]...b[2(n-1)] are computed, computes and stores B[2n]*(2n+1)!

   t/(exp(t)-1) = sum(B[j]*t^j/j!, j=0..infinity)
   thus t = (exp(t)-1) * sum(B[j]*t^j/j!, n=0..infinity).
   Taking the coefficient of degree n+1 > 1, we get:
   0 = sum(1/(n+1-k)!*B[k]/k!, k=0..n)
   which gives:
   B[n] = -sum(binomial(n+1,k)*B[k], k=0..n-1)/(n+1).

   Let C[n] = B[n]*(n+1)!.
   Then C[n] = -sum(binomial(n+1,k)*C[k]*n!/(k+1)!,  k=0..n-1),
   which proves that the C[n] are integers.
*/
mpz_t*
mpfr_bernoulli_internal (mpz_t *b, unsigned long n)
{
  if (n == 0)
    {
      b = (mpz_t *) (*__gmp_allocate_func) (sizeof (mpz_t));
      mpz_init_set_ui (b[0], 1);
    }
  else
    {
      mpz_t t;
      unsigned long k;

      b = (mpz_t *) (*__gmp_reallocate_func)
        (b, n * sizeof (mpz_t), (n + 1) * sizeof (mpz_t));
      mpz_init (b[n]);
      /* b[n] = -sum(binomial(2n+1,2k)*C[k]*(2n)!/(2k+1)!,  k=0..n-1) */
      mpz_init_set_ui (t, 2 * n + 1);
      mpz_mul_ui (t, t, 2 * n - 1);
      mpz_mul_ui (t, t, 2 * n);
      mpz_mul_ui (t, t, n);
      mpz_fdiv_q_ui (t, t, 3); /* exact: t=binomial(2*n+1,2*k)*(2*n)!/(2*k+1)!
                               for k=n-1 */
      mpz_mul (b[n], t, b[n-1]);
      for (k = n - 1; k-- > 0;)
        {
          mpz_mul_ui (t, t, 2 * k + 1);
          mpz_mul_ui (t, t, 2 * k + 2);
          mpz_mul_ui (t, t, 2 * k + 2);
          mpz_mul_ui (t, t, 2 * k + 3);
          mpz_fdiv_q_ui (t, t, 2 * (n - k) + 1);
          mpz_fdiv_q_ui (t, t, 2 * (n - k));
          mpz_addmul (b[n], t, b[k]);
        }
      /* take into account C[1] */
      mpz_mul_ui (t, t, 2 * n + 1);
      mpz_fdiv_q_2exp (t, t, 1);
      mpz_sub (b[n], b[n], t);
      mpz_neg (b[n], b[n]);
      mpz_clear (t);
    }
  return b;
}
Пример #7
0
void
fmpz_fdiv_q(fmpz_t f, const fmpz_t g, const fmpz_t h)
{
    fmpz c1 = *g;
    fmpz c2 = *h;

    if (fmpz_is_zero(h))
    {
        printf("Exception: division by zero in fmpz_fdiv_q\n");
        abort();
    }

    if (!COEFF_IS_MPZ(c1))      /* g is small */
    {
        if (!COEFF_IS_MPZ(c2))  /* h is also small */
        {
            fmpz q = c1 / c2;       /* compute C quotient */
            fmpz r = c1 - c2 * q;   /* compute remainder */

            if (r && (c2 ^ r) < 0L)
                --q;

            fmpz_set_si(f, q);
        }
        else                    /* h is large and g is small */
        {
            if ((c1 > 0L && fmpz_sgn(h) < 0) || (c1 < 0L && fmpz_sgn(h) > 0))  /* signs are the same */
                fmpz_set_si(f, -1L);   /* quotient is negative, round down to minus one */
            else 
                fmpz_zero(f);
        }
    }
    else                        /* g is large */
    {
        __mpz_struct *mpz_ptr = _fmpz_promote(f);

        if (!COEFF_IS_MPZ(c2))  /* h is small */
        {
            if (c2 > 0)         /* h > 0 */
            {
                mpz_fdiv_q_ui(mpz_ptr, COEFF_TO_PTR(c1), c2);
            }
            else
            {
                mpz_cdiv_q_ui(mpz_ptr, COEFF_TO_PTR(c1), -c2);
                mpz_neg(mpz_ptr, mpz_ptr);
            }
        }
        else                    /* both are large */
        {
            mpz_fdiv_q(mpz_ptr, COEFF_TO_PTR(c1), COEFF_TO_PTR(c2));
        }
        _fmpz_demote_val(f);    /* division by h may result in small value */
    }
}
Пример #8
0
void C_BigInt::divideInPlace (const uint32_t inDivisor, uint32_t & outRemainder) {
  mpz_t quotient ;
  mpz_init (quotient) ;
  if (mpz_sgn (mGMPint) >= 0) {
    outRemainder = (uint32_t) mpz_fdiv_q_ui (quotient, mGMPint, inDivisor) ;
  }else{
    outRemainder = (uint32_t) mpz_cdiv_q_ui (quotient, mGMPint, inDivisor) ;
  }
  mpz_swap (quotient, mGMPint) ;
  mpz_clear (quotient) ;
}
Пример #9
0
static char generator_rule_PAIR(Generator *gen) {
        GeneratorState *state = gen->tip;
        unsigned long val;

        /*
         * PAIR ::= basic TYPE
         */

        val = mpz_fdiv_q_ui(state->seed, state->seed, _GENERATOR_BASIC_N);
        state->rule = GENERATOR_RULE_TYPE;
        return generator_map_basic(val);
}
Пример #10
0
static PyObject *
GMPy_MPZ_IFloorDiv_Slot(PyObject *self, PyObject *other)
{
    MPZ_Object *rz;

    if (!(rz =  GMPy_MPZ_New(NULL)))
        return NULL;

    if (CHECK_MPZANY(other)) {
        if (mpz_sgn(MPZ(other)) == 0) {
            ZERO_ERROR("mpz division by zero");
            return NULL;
        }
        mpz_fdiv_q(rz->z, MPZ(self), MPZ(other));
        return (PyObject*)rz;
    }

    if (PyIntOrLong_Check(other)) {
        int error;
        long temp = GMPy_Integer_AsLongAndError(other, &error);

        if (!error) {
            if (temp == 0) {
                ZERO_ERROR("mpz division by zero");
                return NULL;
            }
            else if(temp > 0) {
                mpz_fdiv_q_ui(rz->z, MPZ(self), temp);
            }
            else {
                mpz_cdiv_q_ui(rz->z, MPZ(self), -temp);
                mpz_neg(rz->z, rz->z);
            }
        }
        else {
            mpz_t tempz;
            mpz_inoc(tempz);
            mpz_set_PyIntOrLong(tempz, other);
            mpz_fdiv_q(rz->z, MPZ(self), tempz);
            mpz_cloc(tempz);
        }
        return (PyObject*)rz;
    }

    Py_RETURN_NOTIMPLEMENTED;
}
Пример #11
0
void SchurRing::dimension(const int *exp, mpz_t result) const
    // exp: 0..nvars_
    // Return in 'result' the dimension of the irreducible
    // GL(nvars_) representation having highest weight
    // 'exp'
{
  int i,j;

  mpz_set_ui(result, 1);
  for (i=1; i<nvars_; i++)
    for (j=i+1; j<=nvars_; j++)
      if (exp[i] != exp[j])
        mpz_mul_ui(result, result, exp[i] - exp[j] + j - i);

  for (i=1; i<nvars_; i++)
    for (j=i+1; j<=nvars_; j++)
      if (exp[i] != exp[j])
        mpz_fdiv_q_ui(result, result, j - i);
}
Пример #12
0
static PyObject *
Pyxmpz_inplace_floordiv(PyObject *a, PyObject *b)
{
    mpz_t tempz;
    mpir_si temp_si;
    int overflow;

    if (PyIntOrLong_Check(b)) {
        temp_si = PyLong_AsSIAndOverflow(b, &overflow);
        if (overflow) {
            mpz_inoc(tempz);
            mpz_set_PyIntOrLong(tempz, b);
            mpz_fdiv_q(Pyxmpz_AS_MPZ(a), Pyxmpz_AS_MPZ(a), tempz);
            mpz_cloc(tempz);
        }
        else if(temp_si == 0) {
            ZERO_ERROR("xmpz division by zero");
            return NULL;
        }
        else if(temp_si > 0) {
            mpz_fdiv_q_ui(Pyxmpz_AS_MPZ(a), Pyxmpz_AS_MPZ(a), temp_si);
        }
        else {
            mpz_cdiv_q_ui(Pyxmpz_AS_MPZ(a), Pyxmpz_AS_MPZ(a), -temp_si);
            mpz_neg(Pyxmpz_AS_MPZ(a), Pyxmpz_AS_MPZ(a));
        }
        Py_INCREF(a);
        return a;
    }

    if (CHECK_MPZANY(b)) {
        if (mpz_sgn(Pyxmpz_AS_MPZ(b)) == 0) {
            ZERO_ERROR("xmpz division by zero");
            return NULL;
        }
        mpz_fdiv_q(Pyxmpz_AS_MPZ(a), Pyxmpz_AS_MPZ(a), Pyxmpz_AS_MPZ(b));
        Py_INCREF(a);
        return a;
    }

    Py_RETURN_NOTIMPLEMENTED;
}
Пример #13
0
void calcterm2(int n,mpz_t r) {
	mpz_t z;
	calcterm(n,r);
	mpz_init(z);
	if(n&1) {
		mpz_ui_pow_ui(z,2,n/2);
		mpz_add(r,r,z);
	} else {
		mpz_ui_pow_ui(z,2,n/2-1);
		mpz_add(r,r,z);
		if(n>=4) {
			mpz_ui_pow_ui(z,2,n/2-2);
			mpz_add(r,r,z);
		}
		mpz_set_ui(z,0);
		calcterm(n/2,z);
		mpz_fdiv_q_ui(z,z,2);
		mpz_sub(r,r,z);
	}
	mpz_clear(z);
}
/*
 * fun introot n =
 * if n = 0
 *    then 0
 * else increase (2 * introot (n div 4), n)
 */
void
introot (mpz_t r, const mpz_t n)
{
  unsigned long int i = 0;
  unsigned long int size = mpz_sizeinbase (n, 4);
  mpz_t *stack = malloc (size * sizeof (mpz_t));

  mpz_set (r, n);
  for (i = 1; i <= size; i++)
    {
      mpz_init_set (*(stack + size - i), r);
      mpz_fdiv_q_ui (r, r, 4);
    }
  for (i = 0; i < size; i++)
    {
      mpz_mul_ui (r, r, 2);
      increase (r, *(stack + i));
      mpz_clear (*(stack + i));
    }
  free (stack);
}
Пример #15
0
/* 
 * ===  FUNCTION  ======================================================================
 *         Name:  convertToChar
 *  Description:  
 * =====================================================================================
 */
char *convertToChar(mpz_t *arr, int arr_size, int block_size, int *ret_size) {
    char *result;
    int res_size = arr_size * block_size + 1, i, j;

    result = (char *) malloc (sizeof(char) * res_size);
    
    mpz_t tmp;
    mpz_init(tmp);

    for (i=0; i<arr_size; i++) {
        mpz_set(tmp, arr[i]);
        for (j=0; j<block_size; j++) {
            result[block_size - 1 - j + i *block_size] = (char) mpz_fdiv_ui(tmp, NB_CHAR);
            mpz_fdiv_q_ui(tmp, tmp, NB_CHAR);
        }
    }

    *ret_size = res_size;
    result[res_size - 1] = '\0';
    return result;
}		/* -----  end of function convertToChar  ----- */
Пример #16
0
static PyObject *
GMPy_XMPZ_IFloorDiv_Slot(PyObject *self, PyObject *other)
{
    if (PyIntOrLong_Check(other)) {
        int error;
        native_si temp = GMPy_Integer_AsNative_siAndError(other, &error);

        if (!error) {
            if (temp == 0) {
                ZERO_ERROR("xmpz division by zero");
                return NULL;
            }
            else if(temp > 0) {
                mpz_fdiv_q_ui(MPZ(self), MPZ(self), temp);
            }
            else {
                mpz_cdiv_q_ui(MPZ(self), MPZ(self), -temp);
                mpz_neg(MPZ(self), MPZ(self));
            }
        }
        else {
            mpz_set_PyIntOrLong(global.tempz, other);
            mpz_fdiv_q(MPZ(self), MPZ(self), global.tempz);
        }
        Py_INCREF(self);
        return self;
    }

    if (CHECK_MPZANY(other)) {
        if (mpz_sgn(MPZ(other)) == 0) {
            ZERO_ERROR("xmpz division by zero");
            return NULL;
        }
        mpz_fdiv_q(MPZ(self), MPZ(self), MPZ(other));
        Py_INCREF(self);
        return self;
    }

    Py_RETURN_NOTIMPLEMENTED;
}
Пример #17
0
/* Test all bin(n,k) cases, with 0 <= k <= n + 1 <= count.  */
void
bin_smallexaustive (unsigned int count)
{
  mpz_t          want;
  unsigned long  n, k;

  mpz_init (want);

  for (n = 0; n < count; n++)
    {
      mpz_set_ui (want, 1);
      for (k = 0; k <= n; k++)
	{
	  try_mpz_bin_uiui (want, n, k);
	  mpz_mul_ui (want, want, n - k);
	  mpz_fdiv_q_ui (want, want, k + 1);
	}
      try_mpz_bin_uiui (want, n, k);
    }

  mpz_clear (want);
}
Пример #18
0
int main( void )
{
    unsigned int a, b;
    
    unsigned long long sum, max;
    max = 0;

    mpz_t num, curr, digit;
    mpz_init(num);
    mpz_init(curr);
    mpz_init(digit);
    for( a = 1; a < 100; a++ )
    {
        for( b = 2; b < 100; b++ )
        {
            mpz_ui_pow_ui(num, a, b);
            mpz_set( curr, num );
            
            sum = 0;

            while( mpz_sgn(curr) )
            {
                sum += mpz_mod_ui(digit, curr, 10);
                mpz_fdiv_q_ui(curr, curr, 10);
            }

            max = ( sum > max ) ? sum : max;

        }
    }

    printf("Answer: %llu\n", max);

    mpz_clear(digit);
    mpz_clear(num);
    mpz_clear(curr);
    return 0;
}
Пример #19
0
static char generator_rule_TUPLE(Generator *gen) {
        GeneratorState *next, *state = gen->tip;
        unsigned long val;

        /*
         * TUPLE ::= TYPE | TYPE TUPLE
         */

        val = mpz_fdiv_q_ui(state->seed, state->seed, 2);
        switch (val) {
        case 0:
                state->rule = GENERATOR_RULE_TYPE;
                return generator_rule_TYPE(gen);
        case 1:
                next = generator_push(gen);
                next->rule = GENERATOR_RULE_TYPE;
                generator_inverse_pi(gen, state->seed, next->seed, state->seed);
                return generator_rule_TYPE(gen);
        default:
                assert(0);
                return 0;
        }
}
Пример #20
0
int main(long argc, char *argv[])
{
  if(argc != 4)
  {
      printf("three arguments required\n");
      exit(1);
  }
  mpz_t n, buffer1, buffer2;
  mpz_init(n); mpz_init(buffer1); mpz_init(buffer2);
  mpz_ui_pow_ui(n, atol(argv[2]), atol(argv[3]));
  mpz_mul_ui(n, n, atol(argv[1]));

  uint64_t crn = lpow(n, 1, 3);
  uint64_t srn = lpow(n, 1, 2);
  uint64_t ttrn = lpow(n, 2, 3);
  uint64_t start_block = 1;
  uint64_t finish_block = ttrn/crn;

  size_t psize = (size_t)(((1.26*crn)/log(crn) + 1) * sizeof(uint64_t));
  uint64_t* primes = (uint64_t*)malloc(psize);
  assert(primes!=NULL);
  uint64_t pi_crn = sieve(crn, primes);

  int8_t* mu = malloc(sizeof(int8_t) * (crn+1));                            //mu will run from 1 to crn with s[0] not used
  assert(mu != NULL);
  memset(mu, 1, sizeof(int8_t) * (crn+1));

  uint64_t* lpf = malloc(sizeof(uint64_t) * (crn+1));                        //lpf will run from 1 to crn with s[0] not used
  assert(lpf != NULL);
  memset(lpf, 0, sizeof(uint64_t) * (crn+1));

  uint64_t i, j;

  for(i=1; i<=pi_crn; i++)
    for(j=primes[i]; j<=crn; j+=primes[i])
      {
	mu[j] = -mu[j];
	if(lpf[j] == 0) lpf[j] = primes[i];
      }
  for(i=1; i<=pi_crn; i++)
    for(j=sqr(primes[i]); j<=crn; j+=sqr(primes[i])) mu[j]=0;               //remove numbers that are not squarefree

  uint64_t blocksize = crn;
  uint64_t num_blocks = ttrn/blocksize;
  assert(start_block <= finish_block);
  assert(finish_block <= num_blocks);

  mpz_t S2_result;
  mpz_init(S2_result);

  uint64_t* s = malloc((crn/64+2)*sizeof(uint64_t));
  assert(s != NULL);

  uint64_t* phi = malloc((pi_crn+1)*sizeof(uint64_t));
  memset(phi, 0, (pi_crn+1)*sizeof(uint64_t));

  uint64_t p, f, m, k, start, q, block_id, first_m, last_m, L, U, first_f;

  for(block_id = start_block; block_id <= finish_block; block_id++)
    {
      memset(s, ~0, sizeof(uint64_t) * (crn/64+2));
      L = (block_id -1)*blocksize + 1;
      U = L + blocksize;
      for(i=1; i<=pi_crn; i++)
	{
	  p = primes[i];
	  mpz_fdiv_q_ui(buffer1, n, L*p);
	  mpz_fdiv_q_ui(buffer2, n, U*p);
	  first_m = mpz_get_ui(buffer1);
	  last_m = mpz_get_ui(buffer2);
	  if(first_m > crn) first_m = crn;
	  if(last_m > first_m) last_m = first_m;
	  if(p > first_m) break;
	  start = L;
	  for(m = first_m; m > last_m && p*m > crn ; m--)
	    {
	      if(mu[m] != 0 && p < lpf[m] && p*m > crn && m <= crn)
		{
		  mpz_fdiv_q_ui(buffer1, n, p*m);
		  q = mpz_get_ui(buffer1);
		  assert(q>=L);
		  assert(q<=U);

		  phi[i] += count_bits(s, start - L, q - L);

		  start = q+1;
		  if(mu[m] > 0) mpz_sub_ui(S2_result, S2_result, mu[m] * phi[i]);
		  else mpz_add_ui(S2_result, S2_result, -mu[m] * phi[i]);
		}
	    }
	  phi[i] += count_bits(s, start - L, U -1 - L);
	  sieve_step(start, U, phi,s, L, p);
	}
    }

  uint64_t short_block_length = ttrn % blocksize;

  if(short_block_length>0)
    {
      //short block
      L = L + blocksize;
      U = L + short_block_length; 

      memset(s, ~0, sizeof(uint64_t) * (crn/64+2));
      for(i=1; i<=pi_crn; i++)
	{
	  start = L;
	  p = primes[i];
	  mpz_fdiv_q_ui(buffer1, n, L*p);
	  mpz_fdiv_q_ui(buffer2, n, U*p);
	  first_m = mpz_get_ui(buffer1);
	  last_m = mpz_get_ui(buffer2);
	  if(first_m > crn) first_m = crn;
	  if(last_m > first_m) last_m = first_m;
	  if(p > first_m) break;
	  for(m=first_m; m>last_m && p*m>crn ; m--)
	  {
	      if(mu[m]!=0 && p<lpf[m] && p*m>crn && m<=crn)
	      {
		  mpz_fdiv_q_ui(buffer1, n, p*m);
		  q = mpz_get_ui(buffer1);
		  assert(q>=L);
		  assert(q<=U);
		  phi[i] += count_bits(s, start - L, q - L);
		  start = q+1;
		  if(mu[m] > 0) mpz_sub_ui(S2_result, S2_result, mu[m]*phi[i]);
		  else mpz_add_ui(S2_result, S2_result, -mu[m]*phi[i]);
	      }
	  }
	  sieve_step(start, U, phi,s, L, p);
	}
    }

  mpz_out_str (stdout, 10, S2_result);
  printf("\n");
  mpz_clears(buffer1, buffer2, n, S2_result, NULL);
  free(s); free(phi);
  free(primes); free(mu);
  free(lpf); 
  return(0);
}
Пример #21
0
/*------------------------------------------------------------------------*/
static void
search_coeffs(msieve_obj *obj, poly_search_t *poly, 
		bounds_t *bounds, uint32 deadline)
{
	mpz_t curr_high_coeff;
	double dn = mpz_get_d(poly->N);
	uint32 digits = mpz_sizeinbase(poly->N, 10);
	double start_time = get_cpu_time();
	uint32 deadline_per_coeff = 800;
	uint32 batch_size = (poly->degree == 5) ? POLY_BATCH_SIZE : 1;

	if (digits <= 100)
		deadline_per_coeff = 5;
	else if (digits <= 105)
		deadline_per_coeff = 20;
	else if (digits <= 110)
		deadline_per_coeff = 30;
	else if (digits <= 120)
		deadline_per_coeff = 50;
	else if (digits <= 130)
		deadline_per_coeff = 100;
	else if (digits <= 140)
		deadline_per_coeff = 200;
	else if (digits <= 150)
		deadline_per_coeff = 400;
	printf("deadline: %u seconds per coefficient\n", deadline_per_coeff);

	mpz_init(curr_high_coeff);
	mpz_fdiv_q_ui(curr_high_coeff, 
			bounds->gmp_high_coeff_begin, 
			(mp_limb_t)MULTIPLIER);
	mpz_mul_ui(curr_high_coeff, curr_high_coeff, 
			(mp_limb_t)MULTIPLIER);
	if (mpz_cmp(curr_high_coeff, 
			bounds->gmp_high_coeff_begin) < 0) {
		mpz_add_ui(curr_high_coeff, curr_high_coeff, 
				(mp_limb_t)MULTIPLIER);
	}

	poly->num_poly = 0;

	while (1) {
		curr_poly_t *c = poly->batch + poly->num_poly;

		if (mpz_cmp(curr_high_coeff, 
					bounds->gmp_high_coeff_end) > 0) {

			if (poly->num_poly > 0) {
				search_coeffs_core(obj, poly, 
					   deadline_per_coeff);
			}
			break;
		}

		stage1_bounds_update(bounds, dn, 
					mpz_get_d(curr_high_coeff),
					poly->degree);

		mpz_set(c->high_coeff, curr_high_coeff);
		c->p_size_max = bounds->p_size_max;
		c->coeff_max = bounds->coeff_max;

		if (++poly->num_poly == batch_size) {
			search_coeffs_core(obj, poly, 
					deadline_per_coeff);

			if (obj->flags & MSIEVE_FLAG_STOP_SIEVING)
				break;

			if (deadline) {
				double curr_time = get_cpu_time();
				double elapsed = curr_time - start_time;

				if (elapsed > deadline)
					break;
			}
			poly->num_poly = 0;
		}

		mpz_add_ui(curr_high_coeff, curr_high_coeff, 
				(mp_limb_t)MULTIPLIER);
	}

	mpz_clear(curr_high_coeff);
}
Пример #22
0
/*------------------------------------------------------------------------*/
static void
search_coeffs(msieve_obj *obj, poly_search_t *poly, uint32 deadline)
{
	uint32 digits = mpz_sizeinbase(poly->N, 10);
	double deadline_per_coeff;
	double cumulative_time = 0;
	sieve_t ad_sieve;
	poly_coeff_t *c = poly_coeff_init();
#ifdef HAVE_CUDA
	void *gpu_data = gpu_data_init(obj, poly);
#endif
	/* determine the CPU time limit; I have no idea if
	   the following is appropriate */

	if (digits <= 100)
		deadline_per_coeff = 5;
	else if (digits <= 105)
		deadline_per_coeff = 20;
	else if (digits <= 110)
		deadline_per_coeff = 30;
	else if (digits <= 120)
		deadline_per_coeff = 50;
	else if (digits <= 130)
		deadline_per_coeff = 100;
	else if (digits <= 140)
		deadline_per_coeff = 200;
	else if (digits <= 150)
		deadline_per_coeff = 400;
	else if (digits <= 175)
		deadline_per_coeff = 800;
	else if (digits <= 200)
		deadline_per_coeff = 1600;
	else
		deadline_per_coeff = 3200;

	printf("deadline: %.0lf CPU-seconds per coefficient\n",
					deadline_per_coeff);

	/* set up lower limit on a_d */

	mpz_sub_ui(poly->tmp1, poly->gmp_high_coeff_begin, 1);
	mpz_fdiv_q_ui(poly->tmp1, poly->tmp1, 
			HIGH_COEFF_MULTIPLIER);
	mpz_add_ui(poly->tmp1, poly->tmp1, 1);
	mpz_mul_ui(poly->gmp_high_coeff_begin, poly->tmp1, 
			HIGH_COEFF_MULTIPLIER);

	init_ad_sieve(&ad_sieve, poly);

	while (1) {
		double elapsed;

		/* we only use a_d which are composed of
		   many small prime factors, in order to
		   have lots of projective roots going
		   into stage 2 */

		if (find_next_ad(&ad_sieve, poly, c->high_coeff))
			break;

		/* recalculate internal parameters used
		   for search */

		stage1_bounds_update(poly, c);

		/* finally, sieve for polynomials using
		   Kleinjung's improved algorithm */

#ifdef HAVE_CUDA
		cumulative_time = sieve_lattice_gpu(obj, poly, c,
					gpu_data, deadline_per_coeff);
#else
		elapsed = sieve_lattice_cpu(obj, poly, c, deadline_per_coeff);
		cumulative_time += elapsed;
#endif

		if (obj->flags & MSIEVE_FLAG_STOP_SIEVING)
			break;

		if (deadline && cumulative_time > deadline)
			break;
	}

	free_ad_sieve(&ad_sieve);
#ifdef HAVE_CUDA
	gpu_data_free(gpu_data);
#endif
	poly_coeff_free(c);
}
Пример #23
0
static int generator_rule_TYPE(Generator *gen) {
        GeneratorState *next, *state = gen->tip;
        unsigned long val;
        int res;

        /*
         * TYPE ::= basic
         *          | 'v'
         *          | '(' ')'
         *          | 'm' TYPE
         *          | 'a' TYPE
         *          | '(' TUPLE ')'
         *          | '{' PAIR '}'
         */

        res = mpz_cmp_ui(state->seed, _GENERATOR_BASIC_N + 2);
        if (res < 0) {
                /*
                 * TYPE ::= basic | 'v' | '(' ')'
                 */
                val = mpz_get_ui(state->seed);
                switch (val) {
                case _GENERATOR_BASIC_N + 0:
                        /*
                         * TYPE ::= 'v'
                         */
                        generator_pop(gen);
                        return 'v';
                case _GENERATOR_BASIC_N + 1:
                        /*
                         * TYPE ::= '(' ')'
                         */
                        state->rule = GENERATOR_RULE_TUPLE_CLOSE;
                        return '(';
                default:
                        /*
                         * TYPE ::= basic
                         */
                        generator_pop(gen);
                        return generator_map_basic(val);
                }
        } else {
                /*
                 * TYPE ::= 'm' TYPE | 'a' TYPE | '(' TUPLE ')' | '{' PAIR '}'
                 */
                mpz_sub_ui(state->seed, state->seed, _GENERATOR_BASIC_N + 2);
                val = mpz_fdiv_q_ui(state->seed, state->seed, _GENERATOR_COMPOUND_N);
                switch (val) {
                case GENERATOR_COMPOUND_m:
                        /*
                         * TYPE ::= 'm' TYPE
                         */
                        state->rule = GENERATOR_RULE_TYPE;
                        return 'm';
                case GENERATOR_COMPOUND_a:
                        /*
                         * TYPE ::= 'a' TYPE
                         */
                        state->rule = GENERATOR_RULE_TYPE;
                        return 'a';
                case GENERATOR_COMPOUND_r:
                        /*
                         * TYPE ::= '(' TUPLE ')'
                         */
                        state->rule = GENERATOR_RULE_TUPLE_CLOSE;
                        next = generator_push(gen);
                        next->rule = GENERATOR_RULE_TUPLE;
                        mpz_set(next->seed, state->seed);
                        return '(';
                case GENERATOR_COMPOUND_e:
                        /*
                         * TYPE ::= '{' PAIR '}'
                         */
                        state->rule = GENERATOR_RULE_PAIR_CLOSE;
                        next = generator_push(gen);
                        next->rule = GENERATOR_RULE_PAIR;
                        mpz_set(next->seed, state->seed);
                        return '{';
                default:
                        assert(0);
                        return 0;
                }
        }
}
Пример #24
0
static PyObject *
GMPy_Integer_FloorDiv(PyObject *x, PyObject *y, CTXT_Object *context)
{
    MPZ_Object *result;

    if (!(result = GMPy_MPZ_New(context)))
        return NULL;

    if (CHECK_MPZANY(x)) {
        if (PyIntOrLong_Check(y)) {
            int error;
            native_si temp = GMPy_Integer_AsNative_siAndError(y, &error);

            if (!error) {
                if (temp > 0) {
                    mpz_fdiv_q_ui(result->z, MPZ(x), temp);
                }
                else if (temp == 0) {
                    ZERO_ERROR("division or modulo by zero");
                    Py_DECREF((PyObject*)result);
                    return NULL;
                }
                else {
                    mpz_cdiv_q_ui(result->z, MPZ(x), -temp);
                    mpz_neg(result->z, result->z);
                }
            }
            else {
                mpz_set_PyIntOrLong(global.tempz, y);
                mpz_fdiv_q(result->z, MPZ(x), global.tempz);
            }
            return (PyObject*)result;
        }

        if (CHECK_MPZANY(y)) {
            if (mpz_sgn(MPZ(y)) == 0) {
                ZERO_ERROR("division or modulo by zero");
                Py_DECREF((PyObject*)result);
                return NULL;
            }
            mpz_fdiv_q(result->z, MPZ(x), MPZ(y));
            return (PyObject*)result;
        }
    }

    if (CHECK_MPZANY(y)) {
        if (mpz_sgn(MPZ(y)) == 0) {
            ZERO_ERROR("division or modulo by zero");
            Py_DECREF((PyObject*)result);
            return NULL;
        }

        if (PyIntOrLong_Check(x)) {
            mpz_set_PyIntOrLong(global.tempz, x);
            mpz_fdiv_q(result->z, global.tempz, MPZ(y));
            return (PyObject*)result;
        }
    }

    if (IS_INTEGER(x) && IS_INTEGER(y)) {
        MPZ_Object *tempx, *tempy;

        tempx = GMPy_MPZ_From_Integer(x, context);
        tempy = GMPy_MPZ_From_Integer(y, context);
        if (!tempx || !tempy) {
            Py_XDECREF((PyObject*)tempx);
            Py_XDECREF((PyObject*)tempy);
            Py_DECREF((PyObject*)result);
            return NULL;
        }
        if (mpz_sgn(tempy->z) == 0) {
            ZERO_ERROR("division or modulo by zero");
            Py_XDECREF((PyObject*)tempx);
            Py_XDECREF((PyObject*)tempy);
            Py_DECREF((PyObject*)result);
            return NULL;
        }

        mpz_fdiv_q(result->z, tempx->z, tempy->z);
        Py_DECREF((PyObject*)tempx);
        Py_DECREF((PyObject*)tempy);
        return (PyObject*)result;
    }

    Py_DECREF((PyObject*)result);
    Py_RETURN_NOTIMPLEMENTED;
}
Пример #25
0
int main(int cnt, char** v) {
    if (cnt > 1) {

        mpz_t max, pmax, qmax, p, q, max_tmp, ans, gcd, tmp, a, b, c, k;
        mpz_inits(max, pmax, qmax, '\0');
        mpz_inits(p, q, max_tmp, '\0');
        mpz_inits(ans, gcd, tmp, '\0');
        mpz_inits(a, b, c, k, '\0');

        mpz_set_str(max, v[1], 10);
        mpz_root(qmax, max, 4);
        mpz_fdiv_q_ui(max_tmp, max, 4);
        mpz_root(pmax, max_tmp, 4);

        mpz_set_str(p, "1", 10);
        while (mpz_cmp(p, pmax) <= 0)
        {
            mpz_set(q, p);
            while (mpz_cmp(q, qmax) <= 0) {
                mpz_gcd(gcd, p, q);
                if (mpz_cmp_ui(gcd, 1) == 0) {
                    // int g = mpz_get_ui(gcd);
                    // if(g==1){
                    // uint64_t k=max/q/q/(p+q)/(p+q);
                    // uint64_t a=p*p*(p+q)*(p+q);
                    // uint64_t b=q*q*(p+q)*(p+q);
                    // uint64_t c=p*p*q*q;
                    mpz_set_str(tmp, "0", 10);
                    mpz_set_str(max_tmp, "0", 10);
                    //mpz_set_str(k,"1",10);
                    mpz_set_str(a, "1", 10);
                    mpz_set_str(b, "1", 10);
                    mpz_set_str(c, "1", 10);
                    mpz_add(max_tmp, p, q);

                    mpz_fdiv_q(k, max, q);
                    mpz_fdiv_q(k, k, q);
                    mpz_fdiv_q(k, k, max_tmp);
                    mpz_fdiv_q(k, k, max_tmp);

                    mpz_mul(a, p, p);
                    mpz_mul(a, a, max_tmp);
                    mpz_mul(a, a, max_tmp);

                    mpz_mul(b, q, q);
                    mpz_mul(b, b, max_tmp);
                    mpz_mul(b, b, max_tmp);

                    mpz_mul(c, p, p);
                    mpz_mul(c, c, q);
                    mpz_mul(c, c, q);

                    mpz_add(tmp, tmp, a);
                    mpz_add(tmp, tmp, b);
                    mpz_add(tmp, tmp, c);
                    mpz_mul(tmp, tmp, k);
                    mpz_add_ui(k, k, 1);
                    mpz_mul(tmp, tmp, k);
                    mpz_fdiv_q_ui(tmp, tmp, 2);
                    mpz_add(ans, ans, tmp);
                    // }
                }
                mpz_add_ui(q, q, 1);
            }
            mpz_add_ui(p, p, 1);
        }
        gmp_printf("%Zd\n", ans);
        mpz_clears(max, pmax, qmax, '\0');
        mpz_clears(p, q, max_tmp,'\0');
        mpz_clears(ans, gcd, tmp, '\0');
        mpz_clears(a, b, c, k, '\0');
        
    }

}
Пример #26
0
/* f <- 1 - r/2! + r^2/4! + ... + (-1)^l r^l/(2l)! + ...
   Assumes |r| < 1/2, and f, r have the same precision.
   Returns e such that the error on f is bounded by 2^e ulps.
*/
static int
mpfr_cos2_aux (mpfr_ptr f, mpfr_srcptr r)
{
  mpz_t x, t, s;
  mpfr_exp_t ex, l, m;
  mpfr_prec_t p, q;
  unsigned long i, maxi, imax;

  MPFR_ASSERTD(mpfr_get_exp (r) <= -1);

  /* compute minimal i such that i*(i+1) does not fit in an unsigned long,
     assuming that there are no padding bits. */
  maxi = 1UL << (CHAR_BIT * sizeof(unsigned long) / 2);
  if (maxi * (maxi / 2) == 0) /* test checked at compile time */
    {
      /* can occur only when there are padding bits. */
      /* maxi * (maxi-1) is representable iff maxi * (maxi / 2) != 0 */
      do
        maxi /= 2;
      while (maxi * (maxi / 2) == 0);
    }

  mpz_init (x);
  mpz_init (s);
  mpz_init (t);
  ex = mpfr_get_z_2exp (x, r); /* r = x*2^ex */

  /* remove trailing zeroes */
  l = mpz_scan1 (x, 0);
  ex += l;
  mpz_fdiv_q_2exp (x, x, l);

  /* since |r| < 1, r = x*2^ex, and x is an integer, necessarily ex < 0 */

  p = mpfr_get_prec (f); /* same than r */
  /* bound for number of iterations */
  imax = p / (-mpfr_get_exp (r));
  imax += (imax == 0);
  q = 2 * MPFR_INT_CEIL_LOG2(imax) + 4; /* bound for (3l)^2 */

  mpz_set_ui (s, 1); /* initialize sum with 1 */
  mpz_mul_2exp (s, s, p + q); /* scale all values by 2^(p+q) */
  mpz_set (t, s); /* invariant: t is previous term */
  for (i = 1; (m = mpz_sizeinbase (t, 2)) >= q; i += 2)
    {
      /* adjust precision of x to that of t */
      l = mpz_sizeinbase (x, 2);
      if (l > m)
        {
          l -= m;
          mpz_fdiv_q_2exp (x, x, l);
          ex += l;
        }
      /* multiply t by r */
      mpz_mul (t, t, x);
      mpz_fdiv_q_2exp (t, t, -ex);
      /* divide t by i*(i+1) */
      if (i < maxi)
        mpz_fdiv_q_ui (t, t, i * (i + 1));
      else
        {
          mpz_fdiv_q_ui (t, t, i);
          mpz_fdiv_q_ui (t, t, i + 1);
        }
      /* if m is the (current) number of bits of t, we can consider that
         all operations on t so far had precision >= m, so we can prove
         by induction that the relative error on t is of the form
         (1+u)^(3l)-1, where |u| <= 2^(-m), and l=(i+1)/2 is the # of loops.
         Since |(1+x^2)^(1/x) - 1| <= 4x/3 for |x| <= 1/2,
         for |u| <= 1/(3l)^2, the absolute error is bounded by
         4/3*(3l)*2^(-m)*t <= 4*l since |t| < 2^m.
         Therefore the error on s is bounded by 2*l*(l+1). */
      /* add or subtract to s */
      if (i % 4 == 1)
        mpz_sub (s, s, t);
      else
        mpz_add (s, s, t);
    }

  mpfr_set_z (f, s, MPFR_RNDN);
  mpfr_div_2ui (f, f, p + q, MPFR_RNDN);

  mpz_clear (x);
  mpz_clear (s);
  mpz_clear (t);

  l = (i - 1) / 2; /* number of iterations */
  return 2 * MPFR_INT_CEIL_LOG2 (l + 1) + 1; /* bound is 2l(l+1) */
}
Пример #27
0
static PyObject *
GMPy_MPZ_is_aprcl_prime(PyObject *self, PyObject *other)
{
  mpz_t N;
  s64_t T, U;
  int i, j, H, I, J, K, P, Q, W, X;
  int IV, InvX, LEVELnow, NP, PK, PL, PM, SW, VK, TestedQs, TestingQs;
  int QQ, T1, T3, U1, U3, V1, V3;
  int break_this = 0;
  MPZ_Object *tempx;

  if (!(tempx = GMPy_MPZ_From_Integer(other, NULL))) {
    TYPE_ERROR("is_aprcl_prime() requires 'mpz' argument");
    return NULL;
  }

  mpz_init(N);
  mpz_set(N, tempx->z);
  Py_DECREF(tempx);

  /* make sure the input is >= 2 and odd */
  if (mpz_cmp_ui(N, 2) < 0)
    Py_RETURN_FALSE;

  if (mpz_divisible_ui_p(N, 2)) {
    if (mpz_cmp_ui(N, 2) == 0)
      Py_RETURN_TRUE;
    else
      Py_RETURN_FALSE;
  }

  /* only three small exceptions for this implementation */
  /* with this set of P and Q primes */
  if (mpz_cmp_ui(N, 3) == 0)
    Py_RETURN_TRUE;
  if (mpz_cmp_ui(N, 7) == 0)
    Py_RETURN_TRUE;
  if (mpz_cmp_ui(N, 11) == 0)
    Py_RETURN_TRUE;

  /* If the input number is larger than 7000 decimal digits
     we will just return whether it is a BPSW (probable) prime */
  NumberLength = mpz_sizeinbase(N, 10);
  if (NumberLength > 7000) {
      VALUE_ERROR("value too large to test");
      return NULL;
  }

  allocate_vars();

  mpz_set(TestNbr, N);
  mpz_set_si(biS, 0);

  j = PK = PL = PM = 0;
  for (J = 0; J < PWmax; J++) {
    /* aiJX[J] = 0; */
    mpz_set_ui(aiJX[J], 0);
  }
  break_this = 0;
/* GetPrimes2Test : */
  for (i = 0; i < LEVELmax; i++) {
    /* biS[0] = 2; */
    mpz_set_ui(biS, 2);

    for (j = 0; j < aiNQ[i]; j++) {
      Q = aiQ[j];
      if (aiT[i]%(Q-1) != 0)
        continue;
      U = aiT[i] * Q;
      do {
        U /= Q;
        /* MultBigNbrByLong(biS, Q, biS, NumberLength); */
        mpz_mul_ui(biS, biS, Q);
      } while (U % Q == 0);

      // Exit loop if S^2 > N.
      if (CompareSquare(biS, TestNbr) > 0) {
        /* break GetPrimes2Test; */
        break_this = 1;
        break;
      }
    } /* End for j */

    if (break_this) break;
  } /* End for i */

  if (i == LEVELmax)
  { /* too big */
    free_vars();
    VALUE_ERROR("value too large to test");
    return NULL;
  }
  LEVELnow = i;
  TestingQs = j;
  T = aiT[LEVELnow];
  NP = aiNP[LEVELnow];

MainStart:
  for (;;)
  {
    for (i = 0; i < NP; i++)
    {
      P = aiP[i];
      if (T%P != 0) continue;

      SW = TestedQs = 0;
      /* Q = W = (int) BigNbrModLong(TestNbr, P * P); */
      Q = W = mpz_fdiv_ui(TestNbr, P * P);
      for (J = P - 2; J > 0; J--)
      {
        W = (W * Q) % (P * P);
      }
      if (P > 2 && W != 1)
      {
        SW = 1;
      }
      for (;;)
      {
        for (j = TestedQs; j <= TestingQs; j++)
        {
          Q = aiQ[j] - 1;
          /* G = aiG[j]; */
          K = 0;
          while (Q % P == 0)
          {
            K++;
            Q /= P;
          }
          Q = aiQ[j];
          if (K == 0)
          {
            continue;
          }

          PM = 1;
          for (I = 1; I < K; I++)
          {
            PM = PM * P;
          }
          PL = (P - 1) * PM;
          PK = P * PM;
          for (I = 0; I < PK; I++)
          {
            /* aiJ0[I] = aiJ1[I] = 0; */
            mpz_set_ui(aiJ0[I], 0);
            mpz_set_ui(aiJ1[I], 0);
          }
          if (P > 2)
          {
            JacobiSum(0, P, PL, Q);
          }
          else
          {
            if (K != 1)
            {
              JacobiSum(0, P, PL, Q);
              for (I = 0; I < PK; I++)
              {
                /* aiJW[I] = 0; */
                mpz_set_ui(aiJW[I], 0);
              }
              if (K != 2)
              {
                for (I = 0; I < PM; I++)
                {
                  /* aiJW[I] = aiJ0[I]; */
                  mpz_set(aiJW[I], aiJ0[I]);
                }
                JacobiSum(1, P, PL, Q);
                for (I = 0; I < PM; I++)
                {
                  /* aiJS[I] = aiJ0[I]; */
                  mpz_set(aiJS[I], aiJ0[I]);
                }
                JS_JW(PK, PL, PM, P);
                for (I = 0; I < PM; I++)
                {
                  /* aiJ1[I] = aiJS[I]; */
                  mpz_set(aiJ1[I], aiJS[I]);
                }
                JacobiSum(2, P, PL, Q);
                for (I = 0; I < PK; I++)
                {
                  /* aiJW[I] = 0; */
                  mpz_set_ui(aiJW[I], 0);
                }
                for (I = 0; I < PM; I++)
                {
                  /* aiJS[I] = aiJ0[I]; */
                  mpz_set(aiJS[I], aiJ0[I]);
                }
                JS_2(PK, PL, PM, P);
                for (I = 0; I < PM; I++)
                {
                  /* aiJ2[I] = aiJS[I]; */
                  mpz_set(aiJ2[I], aiJS[I]);
                }
              }
            }
          }
          /* aiJ00[0] = aiJ01[0] = 1; */
          mpz_set_ui(aiJ00[0], 1);
          mpz_set_ui(aiJ01[0], 1);
          for (I = 1; I < PK; I++)
          {
            /* aiJ00[I] = aiJ01[I] = 0; */
            mpz_set_ui(aiJ00[I], 0);
            mpz_set_ui(aiJ01[I], 0);
          }
          /* VK = (int) BigNbrModLong(TestNbr, PK); */
          VK = mpz_fdiv_ui(TestNbr, PK);
          for (I = 1; I < PK; I++)
          {
            if (I % P != 0)
            {
              U1 = 1;
              U3 = I;
              V1 = 0;
              V3 = PK;
              while (V3 != 0)
              {
                QQ = U3 / V3;
                T1 = U1 - V1 * QQ;
                T3 = U3 - V3 * QQ;
                U1 = V1;
                U3 = V3;
                V1 = T1;
                V3 = T3;
              }
              aiInv[I] = (U1 + PK) % PK;
            }
            else
            {
              aiInv[I] = 0;
            }
          }
          if (P != 2)
          {
            for (IV = 0; IV <= 1; IV++)
            {
              for (X = 1; X < PK; X++)
              {
                for (I = 0; I < PK; I++)
                {
                  /* aiJS[I] = aiJ0[I]; */
                  mpz_set(aiJS[I], aiJ0[I]);
                }
                if (X % P == 0)
                {
                  continue;
                }
                if (IV == 0)
                {
                  /* LongToBigNbr(X, biExp, NumberLength); */
                  mpz_set_ui(biExp, X);
                }
                else
                {
                  /* LongToBigNbr(VK * X / PK, biExp, NumberLength); */
                  mpz_set_ui(biExp, (VK * X) / PK);
                  if ((VK * X) / PK == 0)
                  {
                    continue;
                  }
                }
                JS_E(PK, PL, PM, P);
                for (I = 0; I < PK; I++)
                {
                  /* aiJW[I] = 0; */
                  mpz_set_ui(aiJW[I], 0);
                }
                InvX = aiInv[X];
                for (I = 0; I < PK; I++)
                {
                  J = (I * InvX) % PK;
                  /* AddBigNbrModN(aiJW[J], aiJS[I], aiJW[J], TestNbr, NumberLength); */
                  mpz_add(aiJW[J], aiJW[J], aiJS[I]);
                }
                NormalizeJW(PK, PL, PM, P);
                if (IV == 0)
                {
                  for (I = 0; I < PK; I++)
                  {
                    /* aiJS[I] = aiJ00[I]; */
                    mpz_set(aiJS[I], aiJ00[I]);
                  }
                }
                else
                {
                  for (I = 0; I < PK; I++)
                  {
                    /* aiJS[I] = aiJ01[I]; */
                    mpz_set(aiJS[I], aiJ01[I]);
                  }
                }
                JS_JW(PK, PL, PM, P);
                if (IV == 0)
                {
                  for (I = 0; I < PK; I++)
                  {
                    /* aiJ00[I] = aiJS[I]; */
                    mpz_set(aiJ00[I], aiJS[I]);
                  }
                }
                else
                {
                  for (I = 0; I < PK; I++)
                  {
                    /* aiJ01[I] = aiJS[I]; */
                    mpz_set(aiJ01[I], aiJS[I]);
                  }
                }
              } /* end for X */
            } /* end for IV */
          }
          else
          {
            if (K == 1)
            {
              /* MultBigNbrByLongModN(1, Q, aiJ00[0], TestNbr, NumberLength); */
              mpz_set_ui(aiJ00[0], Q);
              /* aiJ01[0] = 1; */
              mpz_set_ui(aiJ01[0], 1);
            }
            else
            {
              if (K == 2)
              {
                if (VK == 1)
                {
                  /* aiJ01[0] = 1; */
                  mpz_set_ui(aiJ01[0], 1);
                }
                /* aiJS[0] = aiJ0[0]; */
                /* aiJS[1] = aiJ0[1]; */
                mpz_set(aiJS[0], aiJ0[0]);
                mpz_set(aiJS[1], aiJ0[1]);
                JS_2(PK, PL, PM, P);
                if (VK == 3)
                {
                  /* aiJ01[0] = aiJS[0]; */
                  /* aiJ01[1] = aiJS[1]; */
                  mpz_set(aiJ01[0], aiJS[0]);
                  mpz_set(aiJ01[1], aiJS[1]);
                }
                /* MultBigNbrByLongModN(aiJS[0], Q, aiJ00[0], TestNbr, NumberLength); */
                mpz_mul_ui(aiJ00[0], aiJS[0], Q);
                /* MultBigNbrByLongModN(aiJS[1], Q, aiJ00[1], TestNbr, NumberLength); */
                mpz_mul_ui(aiJ00[1], aiJS[1], Q);
              }
              else
              {
                for (IV = 0; IV <= 1; IV++)
                {
                  for (X = 1; X < PK; X += 2)
                  {
                    for (I = 0; I <= PM; I++)
                    {
                      /* aiJS[I] = aiJ1[I]; */
                      mpz_set(aiJS[I], aiJ1[I]);
                    }
                    if (X % 8 == 5 || X % 8 == 7)
                    {
                      continue;
                    }
                    if (IV == 0)
                    {
                      /* LongToBigNbr(X, biExp, NumberLength); */
                      mpz_set_ui(biExp, X);
                    }
                    else
                    {
                      /* LongToBigNbr(VK * X / PK, biExp, NumberLength); */
                      mpz_set_ui(biExp, VK * X / PK);
                      if (VK * X / PK == 0)
                      {
                        continue;
                      }
                    }
                    JS_E(PK, PL, PM, P);
                    for (I = 0; I < PK; I++)
                    {
                      /* aiJW[I] = 0; */
                      mpz_set_ui(aiJW[I], 0);
                    }
                    InvX = aiInv[X];
                    for (I = 0; I < PK; I++)
                    {
                      J = I * InvX % PK;
                      /* AddBigNbrModN(aiJW[J], aiJS[I], aiJW[J], TestNbr, NumberLength); */
                      mpz_add(aiJW[J], aiJW[J], aiJS[I]);
                    }
                    NormalizeJW(PK, PL, PM, P);
                    if (IV == 0)
                    {
                      for (I = 0; I < PK; I++)
                      {
                        /* aiJS[I] = aiJ00[I]; */
                        mpz_set(aiJS[I], aiJ00[I]);
                      }
                    }
                    else
                    {
                      for (I = 0; I < PK; I++)
                      {
                        /* aiJS[I] = aiJ01[I]; */
                        mpz_set(aiJS[I], aiJ01[I]);
                      }
                    }
                    NormalizeJS(PK, PL, PM, P);
                    JS_JW(PK, PL, PM, P);
                    if (IV == 0)
                    {
                      for (I = 0; I < PK; I++)
                      {
                        /* aiJ00[I] = aiJS[I]; */
                        mpz_set(aiJ00[I], aiJS[I]);
                      }
                    }
                    else
                    {
                      for (I = 0; I < PK; I++)
                      {
                        /* aiJ01[I] = aiJS[I]; */
                        mpz_set(aiJ01[I], aiJS[I]);
                      }
                    }
                  } /* end for X */
                  if (IV == 0 || VK % 8 == 1 || VK % 8 == 3)
                  {
                    continue;
                  }
                  for (I = 0; I < PM; I++)
                  {
                    /* aiJW[I] = aiJ2[I]; */
                    /* aiJS[I] = aiJ01[I]; */
                    mpz_set(aiJW[I], aiJ2[I]);
                    mpz_set(aiJS[I], aiJ01[I]);
                  }
                  for (; I < PK; I++)
                  {
                    /* aiJW[I] = aiJS[I] = 0; */
                    mpz_set_ui(aiJW[I], 0);
                    mpz_set_ui(aiJS[I], 0);
                  }
                  JS_JW(PK, PL, PM, P);
                  for (I = 0; I < PM; I++)
                  {
                    /* aiJ01[I] = aiJS[I]; */
                    mpz_set(aiJ01[I], aiJS[I]);
                  }
                } /* end for IV */
              }
            }
          }
          for (I = 0; I < PL; I++)
          {
            /* aiJS[I] = aiJ00[I]; */
            mpz_set(aiJS[I], aiJ00[I]);
          }
          for (; I < PK; I++)
          {
            /* aiJS[I] = 0; */
            mpz_set_ui(aiJS[I], 0);
          }
          /* DivBigNbrByLong(TestNbr, PK, biExp, NumberLength); */
          mpz_fdiv_q_ui(biExp, TestNbr, PK);
          JS_E(PK, PL, PM, P);
          for (I = 0; I < PK; I++)
          {
            /* aiJW[I] = 0; */
            mpz_set_ui(aiJW[I], 0);
          }
          for (I = 0; I < PL; I++)
          {
            for (J = 0; J < PL; J++)
            {
              /* MontgomeryMult(aiJS[I], aiJ01[J], biTmp); */
              /* AddBigNbrModN(biTmp, aiJW[(I + J) % PK], aiJW[(I + J) % PK], TestNbr, NumberLength); */
              mpz_mul(biTmp, aiJS[I], aiJ01[J]);
              mpz_add(aiJW[(I + J) % PK], biTmp, aiJW[(I + J) % PK]);
            }
          }
          NormalizeJW(PK, PL, PM, P);
/* MatchingRoot : */
          do
          {
            H = -1;
            W = 0;
            for (I = 0; I < PL; I++)
            {
              if (mpz_cmp_ui(aiJW[I], 0) != 0)/* (!BigNbrIsZero(aiJW[I])) */
              {
                /* if (H == -1 && BigNbrAreEqual(aiJW[I], 1)) */
                if (H == -1 && (mpz_cmp_ui(aiJW[I], 1) == 0))
                {
                  H = I;
                }
                else
                {
                  H = -2;
                  /* AddBigNbrModN(aiJW[I], MontgomeryMultR1, biTmp, TestNbr, NumberLength); */
                  mpz_add_ui(biTmp, aiJW[I], 1);
                  mpz_mod(biTmp, biTmp, TestNbr);
                  if (mpz_cmp_ui(biTmp, 0) == 0) /* (BigNbrIsZero(biTmp)) */
                  {
                    W++;
                  }
                }
              }
            }
            if (H >= 0)
            {
              /* break MatchingRoot; */
              break;
            }
            if (W != P - 1)
            {
              /* Not prime */
              free_vars();
              Py_RETURN_FALSE;
            }
            for (I = 0; I < PM; I++)
            {
              /* AddBigNbrModN(aiJW[I], 1, biTmp, TestNbr, NumberLength); */
              mpz_add_ui(biTmp, aiJW[I], 1);
              mpz_mod(biTmp, biTmp, TestNbr);
              if (mpz_cmp_ui(biTmp, 0) == 0) /* (BigNbrIsZero(biTmp)) */
              {
                break;
              }
            }
            if (I == PM)
            {
              /* Not prime */
              free_vars();
              Py_RETURN_FALSE;
            }
            for (J = 1; J <= P - 2; J++)
            {
              /* AddBigNbrModN(aiJW[I + J * PM], 1, biTmp, TestNbr, NumberLength); */
              mpz_add_ui(biTmp, aiJW[I + J * PM], 1);
              mpz_mod(biTmp, biTmp, TestNbr);
              if (mpz_cmp_ui(biTmp, 0) != 0)/* (!BigNbrIsZero(biTmp)) */
              {
                /* Not prime */
                free_vars();
                Py_RETURN_FALSE;
              }
            }
            H = I + PL;
          }
          while (0);

          if (SW == 1 || H % P == 0)
          {
            continue;
          }
          if (P != 2)
          {
            SW = 1;
            continue;
          }
          if (K == 1)
          {
            if ((mpz_get_ui(TestNbr) & 3) == 1)
            {
              SW = 1;
            }
            continue;
          }

          // if (Q^((N-1)/2) mod N != N-1), N is not prime.

          /* MultBigNbrByLongModN(1, Q, biTmp, TestNbr, NumberLength); */
          mpz_set_ui(biTmp, Q);
          mpz_mod(biTmp, biTmp, TestNbr);

          mpz_sub_ui(biT, TestNbr, 1); /* biT = n-1 */
          mpz_divexact_ui(biT, biT, 2); /* biT = (n-1)/2 */
          mpz_powm(biR, biTmp, biT, TestNbr); /* biR = Q^((n-1)/2) mod n */
          mpz_add_ui(biTmp, biR, 1);
          mpz_mod(biTmp, biTmp, TestNbr);

          if (mpz_cmp_ui(biTmp, 0) != 0)/* (!BigNbrIsZero(biTmp)) */
          {
            /* Not prime */
            free_vars();
            Py_RETURN_FALSE;
          }
          SW = 1;
        } /* end for j */
        if (SW == 0)
        {
          TestedQs = TestingQs + 1;
          if (TestingQs < aiNQ[LEVELnow] - 1)
          {
            TestingQs++;
            Q = aiQ[TestingQs];
            U = T * Q;
            do
            {
              /* MultBigNbrByLong(biS, Q, biS, NumberLength); */
              mpz_mul_ui(biS, biS, Q);
              U /= Q;
            }
            while (U % Q == 0);

            continue; /* Retry */
          }
          LEVELnow++;
          if (LEVELnow == LEVELmax)
          {
            free_vars();
            // return mpz_bpsw_prp(N); /* Cannot tell */
            VALUE_ERROR("maximum levels reached");
            return NULL;
          }
          T = aiT[LEVELnow];
          NP = aiNP[LEVELnow];
          /* biS = 2; */
          mpz_set_ui(biS, 2);
          for (J = 0; J <= aiNQ[LEVELnow]; J++)
          {
            Q = aiQ[J];
            if (T%(Q-1) != 0) continue;
            U = T * Q;
            do
            {
              /* MultBigNbrByLong(biS, Q, biS, NumberLength); */
              mpz_mul_ui(biS, biS, Q);
              U /= Q;
            }
            while (U % Q == 0);
            if (CompareSquare(biS, TestNbr) > 0)
            {
              TestingQs = J;
              /* continue MainStart; */ /* Retry from the beginning */
              goto MainStart;
            }
          } /* end for J */
          free_vars();
          VALUE_ERROR("internal failure");
          return NULL;
        } /* end if */
        break;
      } /* end for (;;) */
    } /* end for i */

    // Final Test

    /* biR = 1 */
    mpz_set_ui(biR, 1);
    /* biN <- TestNbr mod biS */ /* Compute N mod S */
    mpz_fdiv_r(biN, TestNbr, biS);

    for (U = 1; U <= T; U++)
    {
      /* biR <- (biN * biR) mod biS */
      mpz_mul(biR, biN, biR);
      mpz_mod(biR, biR, biS);
      if (mpz_cmp_ui(biR, 1) == 0) /* biR == 1 */
      {
        /* Number is prime */
        free_vars();
        Py_RETURN_TRUE;
      }
      if (mpz_divisible_p(TestNbr, biR) && mpz_cmp(biR, TestNbr) < 0) /* biR < N and biR | TestNbr */
      {
        /* Number is composite */
        free_vars();
        Py_RETURN_FALSE;
      }
    } /* End for U */
    /* This should never be reached. */
    free_vars();
    SYSTEM_ERROR("Internal error: APR-CL error with final test.");
    return NULL;
  }
}
Пример #28
0
void C_BigInt::divideBy (const uint32_t inDivisor,
                         C_BigInt & outQuotient,
                         uint32_t & outRemainder) const {
  outRemainder = (uint32_t) mpz_fdiv_q_ui (outQuotient.mGMPint, mGMPint, inDivisor) ;
}