示例#1
0
/* Compute e^x.  */
static void
exp_mpn (mp1 ex, mp1 x)
{
   unsigned int n;
   mp1 xp;
   mp2 tmp;
   mp_limb_t chk;
   mp1 tol;

   memset (xp, 0, sizeof (mp1));
   memset (ex, 0, sizeof (mp1));
   xp[FRAC / mpbpl] = (mp_limb_t)1 << FRAC % mpbpl;
   memset (tol, 0, sizeof (mp1));
   tol[(FRAC - TOL) / mpbpl] = (mp_limb_t)1 << (FRAC - TOL) % mpbpl;

   n = 0;

   do
     {
       /* Calculate sum(x^n/n!) until the next term is sufficiently small.  */

       mpn_mul_n (tmp, xp, x, SZ);
       assert(tmp[SZ * 2 - 1] == 0);
       if (n > 0)
	 mpn_divmod_1 (xp, tmp + FRAC / mpbpl, SZ, n);
       chk = mpn_add_n (ex, ex, xp, SZ);
       assert (chk == 0);
       ++n;
       assert (n < 80); /* Catch too-high TOL.  */
     }
   while (n < 10 || mpn_cmp (xp, tol, SZ) >= 0);
}
示例#2
0
文件: fmpz.c 项目: hperl/flint
void fmpz_tdiv_ui(fmpz_t output, const fmpz_t input, const unsigned long x)
{
   output[0] = input[0];
   unsigned long size = FLINT_ABS(input[0]);
     
   mpn_divmod_1(output+1, input+1, size, x);
   
   NORM(output);
}
示例#3
0
void
sdiv (const MINT *dividend, signed short int divisor_short, MINT *quot, short *rem_ptr)
{
    mp_size_t sign_dividend;
    signed long int sign_divisor;
    mp_size_t dividend_size, quot_size;
    mp_ptr dividend_ptr, quot_ptr;
    mp_limb_t divisor_limb;
    mp_limb_t remainder_limb;

    sign_dividend = dividend->_mp_size;
    dividend_size = ABS (dividend->_mp_size);

    if (dividend_size == 0)
    {
        quot->_mp_size = 0;
        *rem_ptr = 0;
        return;
    }

    sign_divisor = divisor_short;
    divisor_limb = (unsigned short) ABS (divisor_short);

    /* No need for temporary allocation and copying even if QUOT == DIVIDEND
       as the divisor is just one limb, and thus no intermediate remainders
       need to be stored.  */

    if (quot->_mp_alloc < dividend_size)
        _mp_realloc (quot, dividend_size);

    quot_ptr = quot->_mp_d;
    dividend_ptr = dividend->_mp_d;

    remainder_limb = mpn_divmod_1 (quot_ptr,
                                   dividend_ptr, dividend_size, divisor_limb);

    *rem_ptr = sign_dividend >= 0 ? remainder_limb : -remainder_limb;
    /* The quotient is DIVIDEND_SIZE limbs, but the most significant
       might be zero.  Set QUOT_SIZE properly. */
    quot_size = dividend_size - (quot_ptr[dividend_size - 1] == 0);
    quot->_mp_size = (sign_divisor ^ sign_dividend) >= 0 ? quot_size : -quot_size;
}
示例#4
0
/* 
   Divide (arrayg, limbsg) by the positive value gc inplace and
   return the number of limbs written
*/
mp_size_t mpn_tdiv_q_fmpz_inplace(mp_ptr arrayg, mp_size_t limbsg, fmpz_t gc)
{
   if (fmpz_size(gc) == 1) 
   {
      mpn_divmod_1(arrayg, arrayg, limbsg, fmpz_get_ui(gc));
      return limbsg - (arrayg[limbsg - 1] == 0);
   }
	else 
   {
      mp_size_t tlimbs;
      __mpz_struct * mpz_ptr = COEFF_TO_PTR(*gc);
      
      mp_ptr temp = flint_malloc(limbsg*sizeof(mp_limb_t));
      mpn_copyi(temp, arrayg, limbsg);
      
      mpn_tdiv_q(arrayg, temp, limbsg, mpz_ptr->_mp_d, mpz_ptr->_mp_size);
      tlimbs = limbsg - mpz_ptr->_mp_size + 1;
      tlimbs -= (arrayg[tlimbs - 1] == 0);
      
      flint_free(temp);
      return tlimbs;
   } 
}
示例#5
0
文件: mp_poly.c 项目: hperl/flint
void compute_B_terms(QS_t * qs_inf, poly_t * poly_inf)
{
   unsigned long s = poly_inf->s;
   unsigned long * A_ind = poly_inf->A_ind;
   unsigned long * A_modp = poly_inf->A_modp;
   unsigned long * B_terms = poly_inf->B_terms;
   prime_t * factor_base = qs_inf->factor_base;
   unsigned long limbs = qs_inf->prec+1;
   unsigned long limbs2;
   unsigned long * A = poly_inf->A;
   unsigned long * B = poly_inf->B;
   unsigned long p, i; 
   unsigned long * temp1 = (unsigned long *) flint_stack_alloc(limbs);
   unsigned long temp;
   mp_limb_t msl;
   double pinv;
   
   for (i = 0; i < s; i++)
   {
      p = factor_base[A_ind[i]].p;
      pinv = z_precompute_inverse(p);
      mpn_divmod_1(temp1 + 1, A + 1, A[0], p);
      temp1[0] = A[0] - (temp1[A[0]] == 0); 
      A_modp[i] = (temp = mpn_mod_1(temp1 + 1, temp1[0], p));
      temp = z_invert(temp, p);
      temp = z_mulmod_precomp(temp, qs_inf->sqrts[A_ind[i]], p, pinv);
      if (temp > p/2) temp = p - temp;
      msl = mpn_mul_1(B_terms + i*limbs + 1, temp1 + 1, temp1[0], temp);
      if (msl) 
      {
         B_terms[i*limbs + temp1[0] + 1] = msl;
         B_terms[i*limbs] = temp1[0] + 1;
      }
      else B_terms[i*limbs] = temp1[0];
#if B_TERMS
      mpz_t temp;
      mpz_init(temp);
      fmpz_to_mpz(temp, B_terms + i*limbs);
      gmp_printf("B_%ld = %Zd\n", i, temp);
      mpz_clear(temp);
#endif
   }
   
   F_mpn_copy(B, B_terms, B_terms[0]+1);  // Set B to the sum of the B terms
   if (limbs > B_terms[0] + 1) F_mpn_clear(B + B_terms[0] + 1, limbs - B_terms[0] - 1);
   for (i = 1; i < s; i++)
   {
      limbs2 = B_terms[i*limbs];
      msl = mpn_add_n(B+1, B+1, B_terms + i*limbs + 1, limbs2);
      if (msl) mpn_add_1(B + limbs2 + 1, B + limbs2 + 1, limbs - limbs2 - 1, msl);
   }
   B[0] = limbs - 1;
   while (!B[B[0]] && B[0]) B[0]--;
#if B_TERMS
   mpz_t temp2;
   mpz_init(temp2);
   fmpz_to_mpz(temp2, B);
   gmp_printf("B = %Zd\n", temp2);
   mpz_clear(temp2);
#endif
   
   flint_stack_release(); // release temp1
}
示例#6
0
/* mpn_divmod_1 was a function in gmp 3.0.1 and earlier, but marked obsolete
   in both gmp 2 and 3.  As of gmp 3.1 it's a macro calling mpn_divrem_1. */
mp_limb_t
__MPN (divmod_1) (mp_ptr dst, mp_srcptr src, mp_size_t size, mp_limb_t divisor)
{
  return mpn_divmod_1 (dst, src, size, divisor);
}