Exemple #1
0
void
testmain (int argc, char **argv)
{
  unsigned i;
  unsigned long e;
  mpz_t u, s, r, bs;

  mpz_init (u);
  mpz_init (s);
  mpz_init (r);
  mpz_init (bs);

  for (i = 0; i < COUNT; i++)
    {
      mini_rrandomb (u, MAXBITS);
      mini_rrandomb (bs, 12);
      e = mpz_getlimbn (bs, 0) % mpz_sizeinbase (u, 2) + 2;
      if ((e & 1) && (mpz_getlimbn (bs, 0) & (1L<<10)))
	mpz_neg (u, u);
      mpz_rootrem (s, r, u, e);

      if (!rootrem_valid_p (u, s, r, e))
	{
	  fprintf (stderr, "mpz_rootrem(%lu-th) failed:\n", e);
	  dump ("u", u);
	  dump ("root", s);
	  dump ("rem", r);
	  abort ();
	}
    }
  mpz_clear (bs);
  mpz_clear (u);
  mpz_clear (s);
  mpz_clear (r);
}
Exemple #2
0
static PyObject *
GMPy_MPZ_Function_IrootRem(PyObject *self, PyObject *args)
{
    unsigned long n;
    MPZ_Object *root = NULL, *rem = 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_rem() 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_rem() of negative number");
        Py_DECREF((PyObject*)tempx);
        return NULL;
    }

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

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

    mpz_rootrem(root->z, rem->z, tempx->z, n);
    Py_DECREF((PyObject*)tempx);

    PyTuple_SET_ITEM(result, 0, (PyObject*)root);
    PyTuple_SET_ITEM(result, 1, (PyObject*)rem);
    return result;
}
Exemple #3
0
// Factorization
int factor(const Ptr<RCP<const Integer>> &f, const Integer &n, double B1)
{
    int ret_val = 0;
    mpz_class _n, _f;

    _n = n.as_mpz();

#ifdef HAVE_CSYMPY_ECM
    if (mpz_perfect_power_p(_n.get_mpz_t())) {

        unsigned long int i = 1;
        mpz_class m, rem;
        rem = 1; // Any non zero number
        m = 2; // set `m` to 2**i, i = 1 at the begining

        // calculate log2n, this can be improved
        for (; m < _n; i++)
            m = m * 2;

        // eventually `rem` = 0 zero as `n` is a perfect power. `f_t` will
        // be set to a factor of `n` when that happens
        while (i > 1 && rem != 0) {
            mpz_rootrem(_f.get_mpz_t(), rem.get_mpz_t(), _n.get_mpz_t(), i);
            i--;
        }

        ret_val = 1;
    }
    else {

        if (mpz_probab_prime_p(_n.get_mpz_t(), 25) > 0) { // most probably, n is a prime
            ret_val = 0;
            _f = _n;
        }
        else {

            for (int i = 0; i < 10 && !ret_val; i++)
                ret_val = ecm_factor(_f.get_mpz_t(), _n.get_mpz_t(), B1, NULL);
            if (!ret_val)
                throw std::runtime_error("ECM failed to factor the given number");
        }
    }
#else
    // B1 is discarded if gmp-ecm is not installed
    ret_val = _factor_trial_division_sieve(_f, _n);
#endif // HAVE_CSYMPY_ECM
    *f = integer(_f);

    return ret_val;
}
Exemple #4
0
void
check_one (mpz_t root1, mpz_t x2, unsigned long nth, int i)
{
  mpz_t temp, temp2;
  mpz_t root2, rem2;

  mpz_init (root2);
  mpz_init (rem2);
  mpz_init (temp);
  mpz_init (temp2);

  MPZ_CHECK_FORMAT (root1);

  mpz_rootrem (root2, rem2, x2, nth);
  MPZ_CHECK_FORMAT (root2);
  MPZ_CHECK_FORMAT (rem2);

  mpz_pow_ui (temp, root1, nth);
  MPZ_CHECK_FORMAT (temp);

  mpz_add (temp2, temp, rem2);

  /* Is power of result > argument?  */
  if (mpz_cmp (root1, root2) != 0 || mpz_cmp (x2, temp2) != 0 || mpz_cmpabs (temp, x2) > 0)
    {
      fprintf (stderr, "ERROR after test %d\n", i);
      debug_mp (x2, 10);
      debug_mp (root1, 10);
      debug_mp (root2, 10);
      fprintf (stderr, "nth: %lu\n", nth);
      abort ();
    }

  if (nth > 1 && mpz_cmp_ui (temp, 1L) > 0 && ! mpz_perfect_power_p (temp))
    {
      fprintf (stderr, "ERROR in mpz_perfect_power_p after test %d\n", i);
      debug_mp (temp, 10);
      debug_mp (root1, 10);
      fprintf (stderr, "nth: %lu\n", nth);
      abort ();
    }

  if (nth <= 10000 && mpz_sgn(x2) > 0)		/* skip too expensive test */
    {
      mpz_add_ui (temp2, root1, 1L);
      mpz_pow_ui (temp2, temp2, nth);
      MPZ_CHECK_FORMAT (temp2);

      /* Is square of (result + 1) <= argument?  */
      if (mpz_cmp (temp2, x2) <= 0)
	{
	  fprintf (stderr, "ERROR after test %d\n", i);
	  debug_mp (x2, 10);
	  debug_mp (root1, 10);
	  fprintf (stderr, "nth: %lu\n", nth);
	  abort ();
	}
    }

  mpz_clear (root2);
  mpz_clear (rem2);
  mpz_clear (temp);
  mpz_clear (temp2);
}
Exemple #5
0
bool root(mpz & root, mpz const & a, unsigned k) {
    static LEAN_THREAD_LOCAL mpz rem;
    mpz_rootrem(root.m_val, rem.m_val, a.m_val, k);
    return rem.is_zero();
}
Exemple #6
0
bool root(mpz & root, mpz const & a, unsigned k) {
    mpz rem;
    mpz_rootrem(root.m_val, rem.m_val, a.m_val, k);
    return rem.is_zero();
}
mpz_class squareRoot(const mpz_class& i) {
    mpz_class root, remainder;
    mpz_rootrem(root.get_mpz_t(), remainder.get_mpz_t(), i.get_mpz_t(), 2);
    assert(remainder == 0);
    return root;
}
bool isSquare(const mpz_class& i) {
    mpz_class dummy, remainder;
    mpz_rootrem(dummy.get_mpz_t(), remainder.get_mpz_t(), i.get_mpz_t(), 2);
    return remainder == 0;
}
int main() {
	srand(1337);

	// The primes we will perform trial division with on small integers.
	std::vector<uint32_t> primes;

	// Generate the trial division primes using a simple sieve.
	{
		uint32_t max = (uint32_t)ceil(sqrt(TRIAL_BOUND)) + 1;
		char *sieve = new char[max];
		memset(sieve, 1, max);
		for(uint32_t p = 2; p < max; ++p) {
			if(!sieve[p])
				continue;
			primes.push_back(p);
			for(uint32_t i = p; i < max; i += p)
				sieve[i] = 0;
		}
		delete[] sieve;
	}

	mpz_class N;

	// Read numbers to factor from stdin until EOF.
	while(std::cin >> N) {
		// This quadratic sieve implementation is designed to factor numbers no larger than 100 bits.
		if(mpz_sizeinbase(N.get_mpz_t(), 2) > 100) {
			std::cerr << N << " is too large\n" << std::endl;
			continue;
		}

		std::stack<mpz_class> factors;

		factors.push(N);

		while(!factors.empty()) {
			mpz_class factor = factors.top();
			factors.pop();

			// If the factor is prime, print it.
			if(mpz_probab_prime_p(factor.get_mpz_t(), 10)) {
				std::cout << factor << std::endl;
				continue;

			// Run trial division if factor is small.
			} else if(factor < TRIAL_BOUND) {
				uint32_t f = factor.get_ui();
				for(uint32_t p = 0; p < primes.size(); ++p) {
					if(f % primes[p] == 0) {
						factors.push(primes[p]);
						factors.push(factor / primes[p]);
						break;
					}
				}

			} else {
				// Before we run quadratic sieve, check for small factors.
				bool found_factor = false;
				for(uint32_t p = 0; p < primes.size(); ++p) {
					if(mpz_divisible_ui_p(factor.get_mpz_t(), primes[p])) {
						factors.push(primes[p]);
						factors.push(factor / primes[p]);
						found_factor = true;
						break;
					}
				}
				if(found_factor)
					continue;

				// Quadratic sieve doesn't handle perferct powers very well, handle those separately.
				if(mpz_perfect_power_p(factor.get_mpz_t())) {
					mpz_class root, rem;

					// Check root remainders up half of the amount of bits in factor.
					uint32_t max = mpz_sizeinbase(factor.get_mpz_t(), 2) / 2;
					for(uint32_t n = 2; n < max; ++n) {
						mpz_rootrem(root.get_mpz_t(), rem.get_mpz_t(), factor.get_mpz_t(), n);
						if(rem == 0) {
							// Push the n root factors.
							for(uint32_t i = 0; i < n; ++i)
								factors.push(root);
							break;
						}
					}

				} else {
					mpz_class f = quadratic_sieve(factor);

					factors.push(f);
					factors.push(factor / f);
				}
			}
		}

		std::cout << std::endl;
	}

	return 0;
}
Exemple #10
0
int
main (int argc, char **argv)
{
  int i;
  int pass, reps = 400;
  mpz_t in1, in2, in3;
  unsigned long int in2i;
  mp_size_t size;
  mpz_t res1, res2, res3;
  mpz_t ref1, ref2, ref3;
  mpz_t t;
  unsigned long int r1, r2;
  gmp_randstate_ptr rands;
  mpz_t bs;
  unsigned long bsi, size_range;

  tests_start ();
  TESTS_REPS (reps, argv, argc);

  rands = RANDS;

  mpz_init (bs);

  mpz_init (in1);
  mpz_init (in2);
  mpz_init (in3);
  mpz_init (ref1);
  mpz_init (ref2);
  mpz_init (ref3);
  mpz_init (res1);
  mpz_init (res2);
  mpz_init (res3);
  mpz_init (t);

  for (pass = 1; pass <= reps; pass++)
    {
      if (isatty (fileno (stdout)))
	{
	  printf ("\r%d/%d passes", pass, reps);
	  fflush (stdout);
	}

      mpz_urandomb (bs, rands, 32);
      size_range = mpz_get_ui (bs) % 21 + 2;

      if ((pass & 1) == 0)
	{
	  /* Make all input operands have quite different sizes */
	  mpz_urandomb (bs, rands, 32);
	  size = mpz_get_ui (bs) % size_range;
	  mpz_rrandomb (in1, rands, size);

	  mpz_urandomb (bs, rands, 32);
	  size = mpz_get_ui (bs) % size_range;
	  mpz_rrandomb (in2, rands, size);

	  mpz_urandomb (bs, rands, 32);
	  size = mpz_get_ui (bs) % size_range;
	  mpz_rrandomb (in3, rands, size);
	}
      else
	{
	  /* Make all input operands have about the same size */
	  mpz_urandomb (bs, rands, size_range);
	  size = mpz_get_ui (bs);
	  mpz_rrandomb (in1, rands, size);

	  mpz_urandomb (bs, rands, size_range);
	  size = mpz_get_ui (bs);
	  mpz_rrandomb (in2, rands, size);

	  mpz_urandomb (bs, rands, size_range);
	  size = mpz_get_ui (bs);
	  mpz_rrandomb (in3, rands, size);
	}

      mpz_urandomb (bs, rands, 3);
      bsi = mpz_get_ui (bs);
      if ((bsi & 1) != 0)
	mpz_neg (in1, in1);
      if ((bsi & 2) != 0)
	mpz_neg (in2, in2);
      if ((bsi & 4) != 0)
	mpz_neg (in3, in3);

      for (i = 0; i < numberof (dss); i++)
	{
	  if (dss[i].isdivision && mpz_sgn (in2) == 0)
	    continue;
	  if (dss[i].isslow && size_range > 19)
	    continue;

	  (dss[i].fptr) (ref1, in1, in2);
	  MPZ_CHECK_FORMAT (ref1);

	  mpz_set (res1, in1);
	  INVOKE_RSS (dss[i], res1, res1, in2);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0)
	    FAIL (dss, i, in1, in2, NULL);

	  mpz_set (res1, in2);
	  INVOKE_RSS (dss[i], res1, in1, res1);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0)
	    FAIL (dss, i, in1, in2, NULL);
	}

      for (i = 0; i < numberof (ddss_div); i++)
	{
	  if (mpz_sgn (in2) == 0)
	    continue;

	  (ddss_div[i].fptr) (ref1, ref2, in1, in2);
	  MPZ_CHECK_FORMAT (ref1);
	  MPZ_CHECK_FORMAT (ref2);

	  mpz_set (res1, in1);
	  INVOKE_RRSS (ddss_div[i], res1, res2, res1, in2);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
	    FAIL (ddss_div, i, in1, in2, NULL);

	  mpz_set (res2, in1);
	  INVOKE_RRSS (ddss_div[i], res1, res2, res2, in2);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
	    FAIL (ddss_div, i, in1, in2, NULL);

	  mpz_set (res1, in2);
	  INVOKE_RRSS (ddss_div[i], res1, res2, in1, res1);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
	    FAIL (ddss_div, i, in1, in2, NULL);

	  mpz_set (res2, in2);
	  INVOKE_RRSS (ddss_div[i], res1, res2, in1, res2);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
	    FAIL (ddss_div, i, in1, in2, NULL);
	}

      for (i = 0; i < numberof (ds); i++)
	{
	  if (ds[i].nonneg && mpz_sgn (in1) < 0)
	    continue;

	  (ds[i].fptr) (ref1, in1);
	  MPZ_CHECK_FORMAT (ref1);

	  mpz_set (res1, in1);
	  INVOKE_RS (ds[i], res1, res1);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0)
	    FAIL (ds, i, in1, in2, NULL);
	}

      in2i = mpz_get_ui (in2);

      for (i = 0; i < numberof (dsi); i++)
	{
	  if (dsi[i].mod != 0)
	    in2i = mpz_get_ui (in2) % dsi[i].mod;

	  (dsi[i].fptr) (ref1, in1, in2i);
	  MPZ_CHECK_FORMAT (ref1);

	  mpz_set (res1, in1);
	  INVOKE_RRS (dsi[i], res1, res1, in2i);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0)
	    FAIL (dsi, i, in1, in2, NULL);
	}

      if (in2i != 0)	  /* Don't divide by 0.  */
	{
	  for (i = 0; i < numberof (dsi_div); i++)
	    {
	      r1 = (dsi_div[i].fptr) (ref1, in1, in2i);
	      MPZ_CHECK_FORMAT (ref1);

	      mpz_set (res1, in1);
	      r2 = (dsi_div[i].fptr) (res1, res1, in2i);
	      MPZ_CHECK_FORMAT (res1);
	      if (mpz_cmp (ref1, res1) != 0 || r1 != r2)
		FAIL (dsi_div, i, in1, in2, NULL);
	    }

	  for (i = 0; i < numberof (ddsi_div); i++)
	    {
	      r1 = (ddsi_div[i].fptr) (ref1, ref2, in1, in2i);
	      MPZ_CHECK_FORMAT (ref1);

	      mpz_set (res1, in1);
	      r2 = (ddsi_div[i].fptr) (res1, res2, res1, in2i);
	      MPZ_CHECK_FORMAT (res1);
	      if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0 || r1 != r2)
		FAIL (ddsi_div, i, in1, in2, NULL);

	      mpz_set (res2, in1);
	      (ddsi_div[i].fptr) (res1, res2, res2, in2i);
	      MPZ_CHECK_FORMAT (res1);
	      if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0 || r1 != r2)
		FAIL (ddsi_div, i, in1, in2, NULL);
	    }
	}

      if (mpz_sgn (in1) >= 0)
	{
	  mpz_sqrtrem (ref1, ref2, in1);
	  MPZ_CHECK_FORMAT (ref1);
	  MPZ_CHECK_FORMAT (ref2);

	  mpz_set (res1, in1);
	  mpz_sqrtrem (res1, res2, res1);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
	    FAIL2 (mpz_sqrtrem, in1, NULL, NULL);

	  mpz_set (res2, in1);
	  mpz_sqrtrem (res1, res2, res2);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
	    FAIL2 (mpz_sqrtrem, in1, NULL, NULL);

	  mpz_set (res1, in1);
	  mpz_sqrtrem (res1, res1, res1);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref2, res1) != 0)
	    FAIL2 (mpz_sqrtrem, in1, NULL, NULL);
	}

      if (mpz_sgn (in1) >= 0)
	{
	  mpz_root (ref1, in1, in2i % 0x100 + 1);
	  MPZ_CHECK_FORMAT (ref1);

	  mpz_set (res1, in1);
	  mpz_root (res1, res1, in2i % 0x100 + 1);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0)
	    FAIL2 (mpz_root, in1, in2, NULL);
	}

      if (mpz_sgn (in1) >= 0)
	{
	  mpz_rootrem (ref1, ref2, in1, in2i % 0x100 + 1);
	  MPZ_CHECK_FORMAT (ref1);
	  MPZ_CHECK_FORMAT (ref2);

	  mpz_set (res1, in1);
	  mpz_rootrem (res1, res2, res1, in2i % 0x100 + 1);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
	    FAIL2 (mpz_rootrem, in1, in2, NULL);

	  mpz_set (res2, in1);
	  mpz_rootrem (res1, res2, res2, in2i % 0x100 + 1);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
	    FAIL2 (mpz_rootrem, in1, in2, NULL);
	}

      if (size_range < 18)	/* run fewer tests since gcdext lots of time */
	{
	  mpz_gcdext (ref1, ref2, ref3, in1, in2);
	  MPZ_CHECK_FORMAT (ref1);
	  MPZ_CHECK_FORMAT (ref2);
	  MPZ_CHECK_FORMAT (ref3);

	  mpz_set (res1, in1);
	  mpz_gcdext (res1, res2, res3, res1, in2);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  MPZ_CHECK_FORMAT (res3);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
	      || mpz_cmp (ref3, res3) != 0)
	    FAIL2 (mpz_gcdext, in1, in2, NULL);

	  mpz_set (res2, in1);
	  mpz_gcdext (res1, res2, res3, res2, in2);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  MPZ_CHECK_FORMAT (res3);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
	      || mpz_cmp (ref3, res3) != 0)
	    FAIL2 (mpz_gcdext, in1, in2, NULL);

	  mpz_set (res3, in1);
	  mpz_gcdext (res1, res2, res3, res3, in2);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  MPZ_CHECK_FORMAT (res3);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
	      || mpz_cmp (ref3, res3) != 0)
	    FAIL2 (mpz_gcdext, in1, in2, NULL);

	  mpz_set (res1, in2);
	  mpz_gcdext (res1, res2, res3, in1, res1);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  MPZ_CHECK_FORMAT (res3);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
	      || mpz_cmp (ref3, res3) != 0)
	    FAIL2 (mpz_gcdext, in1, in2, NULL);

	  mpz_set (res2, in2);
	  mpz_gcdext (res1, res2, res3, in1, res2);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  MPZ_CHECK_FORMAT (res3);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
	      || mpz_cmp (ref3, res3) != 0)
	    FAIL2 (mpz_gcdext, in1, in2, NULL);

	  mpz_set (res3, in2);
	  mpz_gcdext (res1, res2, res3, in1, res3);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  MPZ_CHECK_FORMAT (res3);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
	      || mpz_cmp (ref3, res3) != 0)
	    FAIL2 (mpz_gcdext, in1, in2, NULL);

	  mpz_set (res1, in1);
	  mpz_gcdext (res1, res2, NULL, res1, in2);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
	      || mpz_cmp (ref3, res3) != 0)
	    FAIL2 (mpz_gcdext, in1, in2, NULL);

	  mpz_set (res2, in1);
	  mpz_gcdext (res1, res2, NULL, res2, in2);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
	      || mpz_cmp (ref3, res3) != 0)
	    FAIL2 (mpz_gcdext, in1, in2, NULL);

	  mpz_set (res1, in2);
	  mpz_gcdext (res1, res2, NULL, in1, res1);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
	      || mpz_cmp (ref3, res3) != 0)
	    FAIL2 (mpz_gcdext, in1, in2, NULL);

	  mpz_set (res2, in2);
	  mpz_gcdext (res1, res2, NULL, in1, res2);
	  MPZ_CHECK_FORMAT (res1);
	  MPZ_CHECK_FORMAT (res2);
	  if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
	      || mpz_cmp (ref3, res3) != 0)
	    FAIL2 (mpz_gcdext, in1, in2, NULL);
	}

      /* Don't run mpz_powm for huge exponents or when undefined.  */
      if (size_range < 17 && mpz_sizeinbase (in2, 2) < 250 && mpz_sgn (in3) != 0
	  && (mpz_sgn (in2) >= 0 || mpz_invert (t, in1, in3)))
	{
	  mpz_powm (ref1, in1, in2, in3);
	  MPZ_CHECK_FORMAT (ref1);

	  mpz_set (res1, in1);
	  mpz_powm (res1, res1, in2, in3);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0)
	    FAIL2 (mpz_powm, in1, in2, in3);

	  mpz_set (res1, in2);
	  mpz_powm (res1, in1, res1, in3);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0)
	    FAIL2 (mpz_powm, in1, in2, in3);

	  mpz_set (res1, in3);
	  mpz_powm (res1, in1, in2, res1);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0)
	    FAIL2 (mpz_powm, in1, in2, in3);
	}

      /* Don't run mpz_powm_ui when undefined.  */
      if (size_range < 17 && mpz_sgn (in3) != 0)
	{
	  mpz_powm_ui (ref1, in1, in2i, in3);
	  MPZ_CHECK_FORMAT (ref1);

	  mpz_set (res1, in1);
	  mpz_powm_ui (res1, res1, in2i, in3);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0)
	    FAIL2 (mpz_powm_ui, in1, in2, in3);

	  mpz_set (res1, in3);
	  mpz_powm_ui (res1, in1, in2i, res1);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0)
	    FAIL2 (mpz_powm_ui, in1, in2, in3);
	}

      {
	r1 = mpz_gcd_ui (ref1, in1, in2i);
	MPZ_CHECK_FORMAT (ref1);

	mpz_set (res1, in1);
	r2 = mpz_gcd_ui (res1, res1, in2i);
	MPZ_CHECK_FORMAT (res1);
	if (mpz_cmp (ref1, res1) != 0)
	  FAIL2 (mpz_gcd_ui, in1, in2, NULL);
      }

      if (mpz_sgn (in2) != 0)
	{
	  /* Test mpz_remove */
	  mp_bitcnt_t refretval, retval;
	  refretval = mpz_remove (ref1, in1, in2);
	  MPZ_CHECK_FORMAT (ref1);

	  mpz_set (res1, in1);
	  retval = mpz_remove (res1, res1, in2);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0 || refretval != retval)
	    FAIL2 (mpz_remove, in1, in2, NULL);

	  mpz_set (res1, in2);
	  retval = mpz_remove (res1, in1, res1);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0 || refretval != retval)
	    FAIL2 (mpz_remove, in1, in2, NULL);
	}

      if (mpz_sgn (in2) != 0)
	{
	  /* Test mpz_divexact */
	  mpz_mul (t, in1, in2);
	  mpz_divexact (ref1, t, in2);
	  MPZ_CHECK_FORMAT (ref1);

	  mpz_set (res1, t);
	  mpz_divexact (res1, res1, in2);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0)
	    FAIL2 (mpz_divexact, t, in2, NULL);

	  mpz_set (res1, in2);
	  mpz_divexact (res1, t, res1);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0)
	    FAIL2 (mpz_divexact, t, in2, NULL);
	}

      if (mpz_sgn (in2) > 0)
	{
	  /* Test mpz_divexact_gcd, same as mpz_divexact */
	  mpz_mul (t, in1, in2);
	  mpz_divexact_gcd (ref1, t, in2);
	  MPZ_CHECK_FORMAT (ref1);

	  mpz_set (res1, t);
	  mpz_divexact_gcd (res1, res1, in2);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0)
	    FAIL2 (mpz_divexact_gcd, t, in2, NULL);

	  mpz_set (res1, in2);
	  mpz_divexact_gcd (res1, t, res1);
	  MPZ_CHECK_FORMAT (res1);
	  if (mpz_cmp (ref1, res1) != 0)
	    FAIL2 (mpz_divexact_gcd, t, in2, NULL);
	}
    }

  if (isatty (fileno (stdout)))
    printf ("\r%20s", "");

  mpz_clear (bs);
  mpz_clear (in1);
  mpz_clear (in2);
  mpz_clear (in3);
  mpz_clear (ref1);
  mpz_clear (ref2);
  mpz_clear (ref3);
  mpz_clear (res1);
  mpz_clear (res2);
  mpz_clear (res3);
  mpz_clear (t);

  if (isatty (fileno (stdout)))
    printf ("\r");

  tests_end ();
  exit (0);
}