예제 #1
0
int sg_big_float_floor(sg_big_float_t* dst, const sg_big_float_t* src)
{
    if (!dst || !src)
        return -1;
    mpf_floor(dst->mpf, src->mpf);
    return 0;
}
예제 #2
0
/**
 * rasqal_xsd_decimal_round:
 * @result: result variable
 * @a: argment decimal
 * 
 * Return the number with no fractional part closes to argument for an XSD Decimal
 *
 * Return value: non-0 on failure
 **/
int
rasqal_xsd_decimal_round(rasqal_xsd_decimal* result, rasqal_xsd_decimal* a)
{
  int rc = 0;
#ifdef RASQAL_DECIMAL_GMP
  mpf_t b;
  mpf_t c;
#endif
  
  rasqal_xsd_decimal_clear_string(result);
  
#if defined(RASQAL_DECIMAL_C99) || defined(RASQAL_DECIMAL_NONE)
  result->raw = round(a->raw);
#endif
#ifdef RASQAL_DECIMAL_MPFR
  mpfr_round(result->raw, a->raw);
#endif
#ifdef RASQAL_DECIMAL_GMP
  /* GMP has no mpf_round so use result := floor(a + 0.5) */
  mpf_init2(b, a->precision_bits);
  mpf_init2(c, a->precision_bits);

  mpf_set_d(b, 0.5);
  mpf_add(c, a->raw, b);
  mpf_floor(result->raw, c);

  mpf_clear(b);
  mpf_clear(c);
#endif

  return rc;
}
예제 #3
0
/* ceil function: floor(a) + 1 */
int mpf_ceil(mp_float * a, mp_float * b)
{
    int err;
    if ((err = mpf_floor(a, b)) != MP_OKAY) {
	return err;
    }
    if ((err = mpf_add_d(b, 1, b)) != MP_OKAY) {
	return err;
    }
    return MP_OKAY;
}
예제 #4
0
파일: my.c 프로젝트: macroxue/const-pi
void my_out_str_raw(FILE *fp, unsigned long digits, mpf_t f, unsigned long offset)
{
    unsigned long d;

    if (digits <= LINE_SIZE*NUM_BLOCKS) {
        unsigned long cursor = offset % LINE_SIZE;
        for (d = 0; d < digits; ) {
            mpf_set_prec_raw(f, (int)((digits-d)*BITS_PER_DIGIT+1));
            mpf_mul_ui(f, f, UNIT_MOD);
            unsigned long i = mpf_get_ui(f);
            mpf_sub_ui(f, f, i);

            utoa(i, UNIT_SIZE);
            *out_ptr++ = ' ';
            d += UNIT_SIZE;
            cursor += UNIT_SIZE;
            if (cursor == LINE_SIZE) {
                cursor = 0;
                *out_ptr++ = ':';
                *out_ptr++ = ' ';
                utoa(offset + d, 0);
                *out_ptr++ = '\n';
                if ((offset + d) % (LINE_SIZE*10) == 0)
                    flush_out(fp);
            }
        }
    } else {
        mpf_t block, mod;
        unsigned long num_units = (digits + UNIT_SIZE-1)/UNIT_SIZE;
        unsigned long block_size =  (num_units + NUM_BLOCKS-1)/NUM_BLOCKS*UNIT_SIZE;
        mpf_set_default_prec((int)(block_size*BITS_PER_DIGIT+1));
        mpf_init(block);
        mpf_init_set_ui(mod, 10);
        mpf_pow_ui(mod, mod, block_size);

        for (d = 0; d < digits; d += block_size) {
            unsigned long size = block_size < digits - d ? block_size : digits - d;
            mpf_set_prec_raw(block, (int)(size*BITS_PER_DIGIT+1));
            mpf_set(block, f);
            my_out_str_raw(fp, size, block, offset+d);
            if (block_size < digits - d) {
                mpf_set_prec_raw(f, (int)((digits-d)*BITS_PER_DIGIT+1));
                mpf_mul(f, f, mod);
                mpf_floor(trunk, f);
                mpf_sub(f, f, trunk);
            }
        }
        mpf_clear(block);
        mpf_clear(mod);
    }
}
예제 #5
0
/**
 * rasqal_xsd_decimal_floor:
 * @result: result variable
 * @a: argment decimal
 * 
 * Return the number with no fractional part closes to argument for an XSD Decimal
 *
 * Return value: non-0 on failure
 **/
int
rasqal_xsd_decimal_floor(rasqal_xsd_decimal* result, rasqal_xsd_decimal* a)
{
  int rc = 0;
  
  rasqal_xsd_decimal_clear_string(result);
  
#if defined(RASQAL_DECIMAL_C99) || defined(RASQAL_DECIMAL_NONE)
  result->raw = floor(a->raw);
#endif
#ifdef RASQAL_DECIMAL_MPFR
  mpfr_floor(result->raw, a->raw);
#endif
#ifdef RASQAL_DECIMAL_GMP
  mpf_floor(result->raw, a->raw);
#endif

  return rc;
}
예제 #6
0
void
mpc_mod (mpc_t *rop, mpc_t op1, mpc_t op2)
{
  /* I am 90% sure that this doesn't work. However, it works for
   * integers, so I'll put off fixing it for a little while.
   */
  mpf_t hold_op1;
  mpf_t hold_op2;
  mpf_t hold_res;
  unsigned int prec;

  mpf_init (hold_op1);
  mpf_init (hold_op2);
  mpf_init (hold_res);
  mpf_set_z (hold_op1, op1.object);
  mpf_set_z (hold_op2, op2.object);

  // Get the largest precision.
  prec = (op1.precision > op2.precision) ? op1.precision : op2.precision;

  // Set the scalar values
  while (op1.precision-- > 0)
    mpf_div_ui (hold_op1, hold_op1, 10);
  while (op2.precision-- > 0)
    mpf_div_ui (hold_op2, hold_op2, 10);

  // Get the value
  mpf_div (hold_res, hold_op1, hold_op2);
  mpf_floor (hold_res, hold_res);
  mpf_mul (hold_res, hold_res, hold_op2);
  mpf_sub (hold_res, hold_op1, hold_res);

  for (rop->precision = prec; prec > 0; prec--)
    mpf_mul_ui (hold_res, hold_res, 10);
  
  mpz_set_f (rop->object, hold_res);
}
예제 #7
0
//Le but de la fonction est de calculer le développement en fractions continue jusqu'à un certain rang de racine carrée de kN et de stocker les couples (A_n-1,Q_n) comme décrit dans la section (à venir)
cfrac expand(const mpz_t N, const long long unsigned int rang, const mpz_t k)
{
	cfrac res;	//Contient l'ensemble des A_n-1 et l'ensemble Q_n
	mpz_inits(res.N, res.k, res.g, NULL);

	//Initialisation des variables
	mpz_t* A = (mpz_t*)malloc((rang+1)*sizeof(mpz_t));		//Le tableau contenant les A_n-1
	mpz_t* Q = (mpz_t*)malloc((rang+2)*sizeof(mpz_t));		//Le tableau contenant les Q_n
	mpz_t* P = (mpz_t*)malloc((rang+1)*sizeof(mpz_t));		//Éléments reliés au Q_n
	mpz_t* r = (mpz_t*)malloc((rang+1)*sizeof(mpz_t));		//Interviennent dans le calcul des A_n-1 & Q_n
	mpz_t* q = (mpz_t*)malloc(rang*sizeof(mpz_t));			//Idem
	mpz_t g, tempz;											//Idem, tempz = variable à tout faire	
	mpf_t sqrtkN, tempf, tempf2;									//sqrtkN = sqrt(k*N), tempf = variable à tout faire

	

	//Valeurs d'initialisation de la boucle
	mpz_inits(g, A[0], Q[0], r[0], tempz, NULL);
	mpf_inits(tempf, sqrtkN, tempf2, NULL);

	//Initialisation des différentes valeurs "indépendantes"

	mpz_set(tempz, N);
	mpz_mul(tempz, tempz, k);
	mpf_set_z(sqrtkN, tempz);
	mpf_sqrt(sqrtkN, sqrtkN);
	mpf_floor(tempf, sqrtkN);
	mpz_set_f(g, tempf);				//g = [sqrt(kN)]

	mpz_set(Q[0], k);
	mpz_mul(Q[0], Q[0], N);				//Q_-1 = kN = Q[0]
	mpz_set(r[0], g);					//r_-1 = r[0]
	mpz_set_ui(A[0], 1);				//A_-1 = A[0]

	
	//Calcul de P_0 & Q_0
	mpz_init_set_ui(Q[1], 1);			//Q_0 = Q[1]
	mpz_init_set_ui(P[0], 0);			//P_0 = P[0]	

	for(long long int i = 0; i < rang; i++)
	{
		switch(i)
		{
			case 0:

				//Calcul de q_0
				mpz_init_set(q[0], g);				//q_0 = [(sqrt(kN) + P_0)/Q_0] avec P_0 = 0 et Q_0 = 1

				//Calcul de A_0
				mpz_init_set(A[1],A[0]);
				mpz_mul(A[1], A[1], q[0]);			//A_0 = q_0*A_-1
				mpz_mod(A[1], A[1], N);				//On réduit mod N

				//Calcul de r_0
				mpz_init_set_ui(r[1], 0);			//r_0 = P_0 + g - q_0.Q_0 = 0 + g - g.1 = 0

				//Calcul de P_1
				mpz_init_set(P[1], g);				//P_1 = g - r_0 = g - 0 = g

				//Calcul de Q_1 = Q[2]
				mpz_init_set(Q[2], r[1]);		
				mpz_sub(Q[2], Q[2], r[0]);
				mpz_mul(Q[2], Q[2], q[0]);
				mpz_add(Q[2], Q[2], Q[0]);
				
				break;
			default:
				//Calcul q_i
				mpz_init(q[i]);	
				mpf_set_z(tempf, P[i]);
				mpf_set_z(tempf2, Q[i+1]);
				mpf_add(tempf, tempf, sqrtkN);				//sqrt(kN) + P_i
				mpf_div(tempf, tempf, tempf2);		
				mpf_floor(tempf, tempf);					//floor((sqrt(kN) + P_i)/Q_i)
				mpz_set_f(q[i], tempf);

				//Calcul de r_n = r[n+1]	
				mpz_init(r[i+1]);
				mpz_submul(r[i+1], q[i], Q[i+1]);
				mpz_add(r[i+1], r[i+1], P[i]);
				mpz_add(r[i+1], r[i+1], g);

				//Calcul de A_n = A[n+1] 		
				mpz_init_set(A[i+1],A[i]);
				mpz_mul(A[i+1], A[i+1], q[i]);		//A_i-1*q_i
				mpz_add(A[i+1], A[i+1], A[i-1]);	//A_i-1*q_i + A_i-2
				mpz_mod(A[i+1], A[i+1], N);			//réduction modulo N

				//Calcul P_n+1 
				mpz_init_set(P[i+1], g);
				mpz_sub(P[i+1], P[i+1], r[i+1]);		//P[n+1] = g - r_n = g - r[n+1]

				//Calcul Q_n+1 = Q[n+2]
				mpz_init_set(Q[i+2], r[i+1]); 
				mpz_sub(Q[i+2],	Q[i+2], r[i]);		//(r_n - r_n-1)
				mpz_mul(Q[i+2], Q[i+2], q[i]);		//q_n(r_n - r_n-1)
				mpz_add(Q[i+2], Q[i+2], Q[i]);		//Q_n-1 + q_n(r_n - r_n-1)
				
				break;
		}

	}

	//Test de routine pour voir si le développement de la fraction continue s'est bien passé
	mpz_t tempsqrt;
	mpz_init(tempsqrt);
	mpz_set(tempsqrt, k);
	mpz_mul(tempsqrt, tempsqrt, N);
	mpz_sqrt(tempsqrt, tempsqrt);
	mpz_mul_ui(tempsqrt, tempsqrt, 2);

	for(int i = 1; i < rang; i++)				//Éviter de commencer à i = 0 puisque cela représente Q_-1 qui n'intervient uniquement dans l'algo et non dans le développement en fraction continue
	{
		if(mpz_cmp(Q[i], tempsqrt) >= 0)	//Si Q_n >= 2sqrt(kN)
		{
			res.rang = 0;

			mpz_clears(g, tempz, NULL);
			mpf_clears(sqrtkN, tempf, tempf2, NULL);
			return res;
		}
	}

	//Assignation des tableaux dans le résultat
	res.A = A;
	res.Q = Q;
	res.r = r;
	res.q = q;
	res.P = P;
	mpz_set(res.N, N);
	mpz_set(res.k, k);
	res.rang = rang;
	mpz_set(res.g, g);

	//Libération de mémoire
	mpz_clears(g, tempz, NULL);
	mpf_clears(sqrtkN, tempf, tempf2, NULL);

	return res;
}
예제 #8
0
void series(bool const & abortTask, mpf_t & rop, unsigned long m,
            mpz_t * const & tmpI, mpf_t * const & tmpF,
            mpz_t const & sixteen, mpz_t const & digit, mpf_t const & epsilon)
{
    // temporary local variables
    mpf_t & tmp1 = tmpF[0];
    mpf_t & t = tmpF[1];
    mpz_t & tmp2 = tmpI[0];
    mpz_t & k = tmpI[1];
    mpz_t & p = tmpI[2];
    mpz_t & ak = tmpI[3];

    mpf_set_ui(rop, 0);
    mpz_set_ui(k, 0);

    while (mpz_cmp(k, digit) < 0) // k < digit
    {
        // p = id - k;
        mpz_sub(p, digit, k);

        // ak = 8 * k + m;
        mpz_set(ak, k);
        mpz_mul_ui(ak, ak, 8);
        mpz_add_ui(ak, ak, m);

        // t = expm (p, ak);
        mpz_powm(tmp2, sixteen, p, ak);
        mpf_set_z(t, tmp2);

        // s = s + t / ak;
        mpf_set_z(tmp1, ak);
        mpf_div(tmp1, t, tmp1);
        mpf_add(rop, rop, tmp1);

        // s = s - (int) s;
        mpf_floor(tmp1, rop);
        mpf_sub(rop, rop, tmp1);

        // k++
        mpz_add_ui(k, k, 1);

        if (abortTask)
            return;
    }

    // ak = 8 * k + m;
    mpz_set(ak, k);
    mpz_mul_ui(ak, ak, 8);
    mpz_add_ui(ak, ak, m);

    // t = pow (16., (double) (id - k)) / ak;
    mpf_set_z(tmp1, ak);
    mpf_ui_div(t, 1, tmp1);

    while (mpf_cmp(t, epsilon) >= 0) // t >= epsilon
    {
        // s = s + t;
        mpf_add(rop, rop, t);

        // s = s - (int) s;
        mpf_floor(tmp1, rop);
        mpf_sub(rop, rop, tmp1);

        // k++
        mpz_add_ui(k, k, 1);

        // p = id - k;
        mpz_sub(p, digit, k);

        // ak = 8 * k + m;
        mpz_set(ak, k);
        mpz_mul_ui(ak, ak, 8);
        mpz_add_ui(ak, ak, m);

        // t = pow (16., (double) (id - k)) / ak;
        mpz_pow_ui(tmp2, sixteen, mpz_get_ui(p));
        mpz_mul(tmp2, tmp2, ak);
        mpf_set_z(t, tmp2);
        mpf_ui_div(t, 1, t);

        if (abortTask)
            return;
    }
}
예제 #9
0
bool bbp_pi(bool const & abortTask,
            std::string const & digitIndex,
            uint32_t const digitStep,
            std::string & piSequence)
{
    unsigned long const mantissa_bits = 132;
    unsigned long const count_offset = 7;
    // settings above gives 32 hexadecimal digits
    unsigned long count = static_cast<unsigned long>(
        floor(log10(pow(2.0, static_cast<double>(mantissa_bits)))));
    count -= count_offset;

    // starting digit
    mpz_t digit;
    mpz_init(digit);
    if (mpz_set_str(digit, digitIndex.c_str(), 10) < 0)
        return false;
    mpz_sub_ui(digit, digit, 1); // subtract the 3 digit
    mpz_add_ui(digit, digit, digitStep);
    
    mpz_t tmpI[TEMPORARY_INTEGERS];
    for (size_t i = 0; i < (sizeof(tmpI) / sizeof(mpz_t)); ++i)
        mpz_init(tmpI[i]);
    mpf_t tmpF[TEMPORARY_FLOATS];
    for (size_t i = 0; i < (sizeof(tmpF) / sizeof(mpf_t)); ++i)
        mpf_init2(tmpF[i], mantissa_bits);
    
    // determine epsilon based on the number of digits required
    mpf_t epsilon;
    mpf_init2(epsilon, mantissa_bits);
    mpf_set_ui(epsilon, 10);
    mpf_pow_ui(epsilon, epsilon, count + count_offset);
    mpf_ui_div(epsilon, 1, epsilon);

    // integer constant
    mpz_t sixteen;
    mpz_init(sixteen);
    mpz_set_ui(sixteen, 16);

    // determine the series
    mpf_t s1, s2, s3, s4;
    mpf_init2(s1, mantissa_bits);
    mpf_init2(s2, mantissa_bits);
    mpf_init2(s3, mantissa_bits);
    mpf_init2(s4, mantissa_bits);
    series(abortTask, s1, 1, tmpI, tmpF, sixteen, digit, epsilon);
    if (abortTask)
        return false;
    series(abortTask, s2, 4, tmpI, tmpF, sixteen, digit, epsilon);
    if (abortTask)
        return false;
    series(abortTask, s3, 5, tmpI, tmpF, sixteen, digit, epsilon);
    if (abortTask)
        return false;
    series(abortTask, s4, 6, tmpI, tmpF, sixteen, digit, epsilon);
    if (abortTask)
        return false;

    // pid = 4. * s1 - 2. * s2 - s3 - s4;
    mpf_mul_ui(s1, s1, 4);
    mpf_mul_ui(s2, s2, 2);
    mpf_t result;
    mpf_init2(result, mantissa_bits);
    mpf_sub(result, s1, s2);
    mpf_sub(result, result, s3);
    mpf_sub(result, result, s4);

    // pid = pid - (int) pid + 1.;
    mpf_t & tmp1 = tmpF[0];
    mpf_floor(tmp1, result);
    mpf_sub(result, result, tmp1);
    mpf_add_ui(result, result, 1);
    mpf_abs(result, result);

    // output the result
    char resultStr[256];
    mp_exp_t exponent;
    mpf_get_str(resultStr, &exponent, 16, 254, result);
    resultStr[count + 1] = '\0'; // cut off any erroneous bits
    piSequence.assign(&resultStr[1]);

    // cleanup
    for (size_t i = 0; i < (sizeof(tmpI) / sizeof(mpz_t)); ++i)
        mpz_clear(tmpI[i]);
    for (size_t i = 0; i < (sizeof(tmpF) / sizeof(mpf_t)); ++i)
        mpf_clear(tmpF[i]);
    mpz_clear(digit);
    mpf_clear(epsilon);
    mpz_clear(sixteen);
    mpf_clear(s1);
    mpf_clear(s2);
    mpf_clear(s3);
    mpf_clear(s4);
    mpf_clear(result);
    return true;
}
int
aks (mpz_t n)
{
  mpz_t r;
  mpz_t a;
  mpz_t max_a;
  mpz_t gcd_rslt;
  mpz_t totient_r;
  mpf_t ftotient_r;
  mpf_t sqrt_rslt;
  mpf_t sqrt_rslt2;
  mpf_t temp;
  mpf_t temp2;
  sli_t logn;
/* For the sake of maple kernel */
  int argc = 0;
  char **argv;
  char err[2048];
  mpz_init (r);
  mpz_init (a);
  mpz_init (max_a);
  mpz_init (gcd_rslt);
  mpz_init (totient_r);
  mpf_init (ftotient_r);
  mpf_init (sqrt_rslt);
  mpf_init (sqrt_rslt2);
  mpf_init (temp);
  mpf_init (temp2);
/* 1. If (n = a^k for a in N and b > 1) output COMPOSITE */
  if (mpz_perfect_power_p (n) != 0)
    {
      printf ("Step 1 detected composite\n");
      return FALSE;
    }
/* 2. Find the smallest r such that or(n) > 4(log n)^2 */
  find_smallest_r (r, n);
  gmp_printf ("good r seems to be %Zd\n", r);
/* 3. If 1 < gcd(a, n) < n for some a <= r, output COMPOSITE */
/* for (a = 1; a <= r; a++) {
* gcd_rslt = gcd(a, n);
* if (gcd_rslt > 1 && gcd_rslt < n) {
* return FALSE;
* }
* }
*/
  for (mpz_set_ui (a, 1);
       mpz_cmp (a, r) < 0 || mpz_cmp (a, r) == 0; mpz_add_ui (a, a, 1))
    {
      mpz_gcd (gcd_rslt, a, n);
      if (mpz_cmp_ui (gcd_rslt, 1) > 0 && mpz_cmp (gcd_rslt, n) < 0)
	{
	  printf ("Step 3 detected composite\n");
	  return FALSE;
	}
    }
/* 4. If n <= r, output PRIME */
  if (mpz_cmp (n, r) < 0 || mpz_cmp (n, r) == 0)
    {
      printf ("Step 4 detected prime\n");
      return TRUE;
    }
/* 5. For a = 1 to floor(2*sqrt(totient(r))*(log n)
* if ( (X+a)^n != X^n + a (mod X^r-1, n) ), output COMPOSITE
*
* Choices of implementation to evaluate the polynomial equality:
* (1) Implement powermodreduce on polynomial ourselves (tough manly way)
* (2) Use MAPLE (not so manly, but less painful)
*/
/* Compute totient(r), since r is prime, this is simply r-1 */
  mpz_sub_ui (totient_r, r, 1);
/* Compute log n (ceilinged) */
  mpz_logbase2cl (&logn, n);
/* Compute sqrt(totient(r)) */
  mpf_set_z (ftotient_r, totient_r);
  mpf_sqrt (sqrt_rslt, ftotient_r);
/* Compute 2*sqrt(totient(r)) */
  mpf_mul_ui (sqrt_rslt2, sqrt_rslt, 2);
/* Compute 2*sqrt(totient(r))*(log n) */
  mpf_set (temp, sqrt_rslt2);
  mpf_set_si (temp2, logn);
  mpf_mul (temp, temp, temp2);
/* Finally, compute max_a, after lots of singing and dancing */
  mpf_floor (temp, temp);
  mpz_set_f (max_a, temp);
  gmp_printf ("max_a = %Zd\n", max_a);
/* Now evaluate the polynomial equality with the help of maple kernel */
/* Set up maple kernel incantations */
  MKernelVector kv;
  MCallBackVectorDesc cb = { textCallBack,
    0,				/* errorCallBack not used */
    0,				/* statusCallBack not used */
    0,				/* readLineCallBack not used */
    0,				/* redirectCallBack not used */
    0,				/* streamCallBack not used */
    0,				/* queryInterrupt not used */
    0				/* callBackCallBack not used */
  };
/* Initialize Maple */
  if ((kv = StartMaple (argc, argv, &cb, NULL, NULL, err)) == NULL)
    {
      printf ("Could not start Maple, %s\n", err);
      exit (666);
    }
/* Here comes the complexity and bottleneck */
/* for (a = 1; a <= max_a; a++) {
* if (!poly_eq_holds(kv, a, n, r)) {
* return FALSE;
* }
* }
*/
/* Make max_a only up to 5 */
  mpz_set_ui (max_a, 5);
  for (mpz_set_ui (a, 1);
       mpz_cmp (a, max_a) < 0 || mpz_cmp (a, max_a) == 0;
       mpz_add_ui (a, a, 1))
    {
      if (!poly_eq_holds (kv, a, n, r))
	{
	  printf ("Step 5 detected composite\n");
	  return FALSE;
	}
    }
/* 6. Output PRIME */
  printf ("Step 6 detected prime\n");
  return TRUE;
}