Example #1
0
File: eu066.c Project: pbevin/euler
/*
 * http://en.wikipedia.org/wiki/Pell's_equation
 *
 * We find the continued fraction expansion of sqrt(d), and
 * expand out the convergents as h/k.  At some point, the
 * solution x=h, y=k will satisfy the equation and this is
 * guaranteed to be minimal in x.
 *
 * To find the continued fraction expansion of sqrt(d):
 *   http://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Continued_fraction_expansion
 *
 * To find the convergents:
 *   http://www.proofwiki.org/wiki/Definition:Continued_Fraction/Numerators_and_Denominators
 * (our h, k are their p, q)
 */
static void minx(int d, mpz_t x) {
  int a0 = sqrt(d);
  int mn = 0, dn = 1, an = a0;
  int m1, d1, a1;

  mpz_t h, k;    // h_n, k_n
  mpz_t h1, k1;  // h_{n-1}, k_{n-1}
  mpz_t h2, k2;  // h_{n-2}, k_{n-2}
  mpz_t hsq, ksq; // h^2, k^2

  mpz_init(h); mpz_init(k);
  mpz_init(h1); mpz_init(k1);
  mpz_init(h2); mpz_init(k2);
  mpz_init(hsq); mpz_init(ksq);

  mpz_set_ui(h1, 1);
  mpz_set_ui(k1, 0);
  mpz_set_ui(h, a0);
  mpz_set_ui(k, 1);

  do {
    // Get the next a_n in the continued fraction
    m1 = dn * an - mn;
    d1 = (d - m1*m1) / dn;
    a1 = (a0 + m1) / d1;

    mn = m1;
    dn = d1;
    an = a1;

    // Get the next convergent
    mpz_set(h2, h1);
    mpz_set(k2, k1);
    mpz_set(h1, h);
    mpz_set(k1, k);
    mpz_mul_ui(h, h1, an); mpz_add(h, h, h2); // h_n = a_n*h_{n-1} + h_{n-2}
    mpz_mul_ui(k, k1, an); mpz_add(k, k, k2); // k_n = a_n*k_{n-1} + k_{n-2}

    // Check if h, k is a solution
    mpz_mul(hsq, h, h);
    mpz_mul(ksq, k, k);
    mpz_submul_ui(hsq, ksq, d);
  } while (mpz_cmp_ui(hsq, 1) != 0);

  mpz_set(x, h);

  mpz_clear(h); mpz_clear(k);
  mpz_clear(h1); mpz_clear(k1);
  mpz_clear(h2); mpz_clear(k2);
  mpz_clear(hsq); mpz_clear(ksq);
}
Example #2
0
void
testmain (int argc, char **argv)
{
  unsigned i;
  mpz_t a, b, res, ref;

  mpz_init (a);
  mpz_init (b);
  mpz_init_set_ui (res, 5);
  mpz_init (ref);

  for (i = 0; i < COUNT; i++)
    {
      mini_random_op3 (OP_MUL, MAXBITS, a, b, ref);
      if (i & 1) {
	mpz_add (ref, ref, res);
	if (mpz_fits_ulong_p (b))
	  mpz_addmul_ui (res, a, mpz_get_ui (b));
	else
	  mpz_addmul (res, a, b);
      } else {
	mpz_sub (ref, res, ref);
	if (mpz_fits_ulong_p (b))
	  mpz_submul_ui (res, a, mpz_get_ui (b));
	else
	  mpz_submul (res, a, b);
      }
      if (mpz_cmp (res, ref))
	{
	  if (i & 1)
	    fprintf (stderr, "mpz_addmul failed:\n");
	  else
	    fprintf (stderr, "mpz_submul failed:\n");
	  dump ("a", a);
	  dump ("b", b);
	  dump ("r", res);
	  dump ("ref", ref);
	  abort ();
	}
    }
  mpz_clear (a);
  mpz_clear (b);
  mpz_clear (res);
  mpz_clear (ref);
}
Example #3
0
void
check_one_ui (mpz_ptr w, mpz_ptr x, unsigned long y)
{
  mpz_t  want, got;

  mpz_init (want);
  mpz_init (got);

  mpz_mul_ui (want, x, (unsigned long) y);
  mpz_add (want, w, want);
  mpz_set (got, w);
  mpz_addmul_ui (got, x, (unsigned long) y);
  MPZ_CHECK_FORMAT (got);
  if (mpz_cmp (want, got) != 0)
    {
      printf ("mpz_addmul_ui fail\n");
    fail:
      mpz_trace ("w", w);
      mpz_trace ("x", x);
      printf    ("y=0x%lX   %lu\n", y, y);
      mpz_trace ("want", want);
      mpz_trace ("got ", got);
      abort ();
    }

  mpz_mul_ui (want, x, y);
  mpz_sub (want, w, want);
  mpz_set (got, w);
  mpz_submul_ui (got, x, y);
  MPZ_CHECK_FORMAT (got);
  if (mpz_cmp (want, got) != 0)
    {
      printf ("mpz_submul_ui fail\n");
      goto fail;
    }

  mpz_clear (want);
  mpz_clear (got);
}
Example #4
0
static void eliminate_digit(unsigned int d)
{
  mpz_submul_ui(accum, denom, d);
  mpz_mul_ui(accum, accum, 10);
  mpz_mul_ui(numer, numer, 10);
}
Example #5
0
void eliminate_digit(ui d) {
   mpz_submul_ui(acc, den, d);
   mpz_mul_ui(acc, acc, 10);
   mpz_mul_ui(num, num, 10);
}
Example #6
0
Integer& Integer::maxpyin(Integer& res, const Integer& a, const uint64_t x)
{
    if (isZero(a) || isZero(x)) return res;
    mpz_submul_ui( (mpz_ptr)&res.gmp_rep, (mpz_srcptr)&a.gmp_rep, x);
    return res;
}