Ejemplo n.º 1
0
int
main (int argc, char **argv)
{
  mpz_t x2;
  mpz_t root1;
  mp_size_t x2_size;
  int i;
  int reps = 500;
  unsigned long nth;
  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 (x2);
  mpz_init (root1);

  /* This triggers a gcc 4.3.2 bug */
  mpz_set_str (x2, "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80000000000000000000000000000000000000000000000000000000000000002", 16);
  mpz_root (root1, x2, 2);
  check_one (root1, x2, 2, -1);

  for (i = 0; i < reps; i++)
    {
      mpz_urandomb (bs, rands, 32);
      size_range = mpz_get_ui (bs) % 17 + 2;

      mpz_urandomb (bs, rands, size_range);
      x2_size = mpz_get_ui (bs) + 10;
      mpz_rrandomb (x2, rands, x2_size);

      mpz_urandomb (bs, rands, 15);
      nth = mpz_getlimbn (bs, 0) % mpz_sizeinbase (x2, 2) + 2;

      mpz_root (root1, x2, nth);

      mpz_urandomb (bs, rands, 4);
      bsi = mpz_get_ui (bs);
      if ((bsi & 1) != 0)
	{
	  /* With 50% probability, set x2 near a perfect power.  */
	  mpz_pow_ui (x2, root1, nth);
	  if ((bsi & 2) != 0)
	    {
	      mpz_sub_ui (x2, x2, bsi >> 2);
	      mpz_abs (x2, x2);
	    }
	  else
Ejemplo n.º 2
0
int
main (int argc, char **argv)
{
  mpz_t dividend, divisor;
  mpz_t quotient, remainder;
  mpz_t quotient2, remainder2;
  mpz_t temp;
  mp_size_t dividend_size, divisor_size;
  int i;
  int reps = 1000;
  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 (dividend);
  mpz_init (divisor);
  mpz_init (quotient);
  mpz_init (remainder);
  mpz_init (quotient2);
  mpz_init (remainder2);
  mpz_init (temp);

  for (i = 0; i < reps; i++)
    {
      mpz_urandomb (bs, rands, 32);
      size_range = mpz_get_ui (bs) % 18 + 2; /* 0..524288 bit operands */

      do
	{
	  mpz_urandomb (bs, rands, size_range);
	  divisor_size = mpz_get_ui (bs);
	  mpz_rrandomb (divisor, rands, divisor_size);
	}
      while (mpz_sgn (divisor) == 0);

      mpz_urandomb (bs, rands, size_range);
      dividend_size = mpz_get_ui (bs) + divisor_size;
      mpz_rrandomb (dividend, rands, dividend_size);

      mpz_urandomb (bs, rands, 2);
      bsi = mpz_get_ui (bs);
      if ((bsi & 1) != 0)
	mpz_neg (dividend, dividend);
      if ((bsi & 2) != 0)
	mpz_neg (divisor, divisor);

      /* printf ("%ld %ld\n", SIZ (dividend), SIZ (divisor)); */

      mpz_tdiv_qr (quotient, remainder, dividend, divisor);
      mpz_tdiv_q (quotient2, dividend, divisor);
      mpz_tdiv_r (remainder2, dividend, divisor);

      /* First determine that the quotients and remainders computed
	 with different functions are equal.  */
      if (mpz_cmp (quotient, quotient2) != 0)
	dump_abort (dividend, divisor);
      if (mpz_cmp (remainder, remainder2) != 0)
	dump_abort (dividend, divisor);

      /* Check if the sign of the quotient is correct.  */
      if (mpz_cmp_ui (quotient, 0) != 0)
	if ((mpz_cmp_ui (quotient, 0) < 0)
	    != ((mpz_cmp_ui (dividend, 0) ^ mpz_cmp_ui (divisor, 0)) < 0))
	dump_abort (dividend, divisor);

      /* Check if the remainder has the same sign as the dividend
	 (quotient rounded towards 0).  */
      if (mpz_cmp_ui (remainder, 0) != 0)
	if ((mpz_cmp_ui (remainder, 0) < 0) != (mpz_cmp_ui (dividend, 0) < 0))
	  dump_abort (dividend, divisor);

      mpz_mul (temp, quotient, divisor);
      mpz_add (temp, temp, remainder);
      if (mpz_cmp (temp, dividend) != 0)
	dump_abort (dividend, divisor);

      mpz_abs (temp, divisor);
      mpz_abs (remainder, remainder);
      if (mpz_cmp (remainder, temp) >= 0)
	dump_abort (dividend, divisor);
    }

  mpz_clear (bs);
  mpz_clear (dividend);
  mpz_clear (divisor);
  mpz_clear (quotient);
  mpz_clear (remainder);
  mpz_clear (quotient2);
  mpz_clear (remainder2);
  mpz_clear (temp);

  tests_end ();
  exit (0);
}
Ejemplo n.º 3
0
int
main (int argc, char **argv)
{
  mpz_t op1, op2, ref;
  int i, chain_len;
  gmp_randstate_ptr rands;
  mpz_t bs;
  unsigned long bsi, size_range;
  long int reps = 200;

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

  rands = RANDS;

  mpz_inits (bs, op1, op2, ref, gcd1, gcd2, temp1, temp2, temp3, s, NULL);

  check_data ();
  check_kolmo1 ();
  check_kolmo2 ();

  /* Testcase to exercise the u0 == u1 case in mpn_gcdext_lehmer_n. */
  mpz_set_ui (op2, GMP_NUMB_MAX); /* FIXME: Huge limb doesn't always fit */
  mpz_mul_2exp (op1, op2, 100);
  mpz_add (op1, op1, op2);
  mpz_mul_ui (op2, op2, 2);
  one_test (op1, op2, NULL, -1);

  for (i = 0; i < reps; i++)
    {
      /* Generate plain operands with unknown gcd.  These types of operands
	 have proven to trigger certain bugs in development versions of the
	 gcd code.  The "hgcd->row[3].rsize > M" ASSERT is not triggered by
	 the division chain code below, but that is most likely just a result
	 of that other ASSERTs are triggered before it.  */

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

      mpz_urandomb (bs, rands, size_range);
      mpz_rrandomb (op1, rands, mpz_get_ui (bs) + MIN_OPERAND_BITSIZE);
      mpz_urandomb (bs, rands, size_range);
      mpz_rrandomb (op2, rands, mpz_get_ui (bs) + MIN_OPERAND_BITSIZE);

      mpz_urandomb (bs, rands, 8);
      bsi = mpz_get_ui (bs);

      if ((bsi & 0x3c) == 4)
	mpz_mul (op1, op1, op2);	/* make op1 a multiple of op2 */
      else if ((bsi & 0x3c) == 8)
	mpz_mul (op2, op1, op2);	/* make op2 a multiple of op1 */

      if ((bsi & 1) != 0)
	mpz_neg (op1, op1);
      if ((bsi & 2) != 0)
	mpz_neg (op2, op2);

      one_test (op1, op2, NULL, i);

      /* Generate a division chain backwards, allowing otherwise unlikely huge
	 quotients.  */

      mpz_urandomb (bs, rands, 32);
      chain_len = mpz_get_ui (bs) % LOG2C (GMP_NUMB_BITS * MAX_SCHOENHAGE_THRESHOLD);
      mpz_urandomb (bs, rands, 32);
      chain_len = mpz_get_ui (bs) % (1 << chain_len) / 32;

      make_chain_operands (ref, op1, op2, rands, 16, 12, chain_len);

      one_test (op1, op2, ref, i);
    }

  mpz_clears (bs, op1, op2, ref, gcd1, gcd2, temp1, temp2, temp3, s, NULL);

  tests_end ();
  exit (0);
}
Ejemplo n.º 4
0
int
main (int argc, char **argv)
{
  mpz_t x2;
  mpz_t x, rem;
  mpz_t temp, temp2;
  mp_size_t x2_size;
  int i;
  int reps = 1000;
  gmp_randstate_ptr rands;
  mpz_t bs;
  unsigned long size_range;

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

  rands = RANDS;

  mpz_init (bs);

  mpz_init (x2);
  mpz_init (x);
  mpz_init (rem);
  mpz_init (temp);
  mpz_init (temp2);

  for (i = 0; i < reps; i++)
    {
      mpz_urandomb (bs, rands, 32);
      size_range = mpz_get_ui (bs) % 17 + 2; /* 0..262144 bit operands */

      mpz_urandomb (bs, rands, size_range);
      x2_size = mpz_get_ui (bs);
      mpz_rrandomb (x2, rands, x2_size);

      /* printf ("%ld\n", SIZ (x2)); */

      mpz_sqrtrem (x, rem, x2);
      MPZ_CHECK_FORMAT (x);
      MPZ_CHECK_FORMAT (rem);

      mpz_mul (temp, x, x);

      /* Is square of result > argument?  */
      if (mpz_cmp (temp, x2) > 0)
	dump_abort (x2, x, rem);

      mpz_add_ui (temp2, x, 1);
      mpz_mul (temp2, temp2, temp2);

      /* Is square of (result + 1) <= argument?  */
      if (mpz_cmp (temp2, x2) <= 0)
	dump_abort (x2, x, rem);

      mpz_add (temp2, temp, rem);

      /* Is the remainder wrong?  */
      if (mpz_cmp (x2, temp2) != 0)
	dump_abort (x2, x, rem);
    }

  mpz_clear (bs);
  mpz_clear (x2);
  mpz_clear (x);
  mpz_clear (rem);
  mpz_clear (temp);
  mpz_clear (temp2);

  tests_end ();
  exit (0);
}
Ejemplo n.º 5
0
int
main (int argc, char **argv)
{
  mpz_t op1, op2, ref;
  int i, j, chain_len;
  gmp_randstate_ptr rands;
  mpz_t bs;
  unsigned long bsi, size_range;
  int reps = 200;

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

  rands = RANDS;

  check_data ();

  mpz_init (bs);
  mpz_init (op1);
  mpz_init (op2);
  mpz_init (ref);
  mpz_init (gcd1);
  mpz_init (gcd2);
  mpz_init (temp1);
  mpz_init (temp2);
  mpz_init (temp3);
  mpz_init (s);
  mpz_init (t);

  /* Testcase to exercise the u0 == u1 case in mpn_gcdext_lehmer_n. */
  mpz_set_ui (op2, GMP_NUMB_MAX);
  mpz_mul_2exp (op1, op2, 100);
  mpz_add (op1, op1, op2);
  mpz_mul_ui (op2, op2, 2);
  one_test (op1, op2, NULL, -1);

#if 0
  mpz_set_str (op1, "4da8e405e0d2f70d6d679d3de08a5100a81ec2cff40f97b313ae75e1183f1df2b244e194ebb02a4ece50d943640a301f0f6cc7f539117b783c3f3a3f91649f8a00d2e1444d52722810562bce02fccdbbc8fe3276646e306e723dd3b", 16);
  mpz_set_str (op2, "76429e12e4fdd8929d89c21657097fbac09d1dc08cf7f1323a34e78ca34226e1a7a29b86fee0fa7fe2cc2a183d46d50df1fe7029590974ad7da77605f35f902cb8b9b8d22dd881eaae5919675d49a337145a029c3b33fc2b0", 16);
  one_test (op1, op2, NULL, -1);
#endif

  for (i = 0; i < reps; i++)
    {
      /* Generate plain operands with unknown gcd.  These types of operands
	 have proven to trigger certain bugs in development versions of the
	 gcd code.  The "hgcd->row[3].rsize > M" ASSERT is not triggered by
	 the division chain code below, but that is most likely just a result
	 of that other ASSERTs are triggered before it.  */

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

      mpz_urandomb (bs, rands, size_range);
      mpz_rrandomb (op1, rands, mpz_get_ui (bs) + MIN_OPERAND_BITSIZE);
      mpz_urandomb (bs, rands, size_range);
      mpz_rrandomb (op2, rands, mpz_get_ui (bs) + MIN_OPERAND_BITSIZE);

      mpz_urandomb (bs, rands, 8);
      bsi = mpz_get_ui (bs);

      if ((bsi & 0x3c) == 4)
	mpz_mul (op1, op1, op2);	/* make op1 a multiple of op2 */
      else if ((bsi & 0x3c) == 8)
	mpz_mul (op2, op1, op2);	/* make op2 a multiple of op1 */

      if ((bsi & 1) != 0)
	mpz_neg (op1, op1);
      if ((bsi & 2) != 0)
	mpz_neg (op2, op2);

      one_test (op1, op2, NULL, i);

      /* Generate a division chain backwards, allowing otherwise unlikely huge
	 quotients.  */

      mpz_set_ui (op1, 0);
      mpz_urandomb (bs, rands, 32);
      mpz_urandomb (bs, rands, mpz_get_ui (bs) % 16 + 1);
      mpz_rrandomb (op2, rands, mpz_get_ui (bs));
      mpz_add_ui (op2, op2, 1);
      mpz_set (ref, op2);

#if WHACK_SCHOENHAGE
      chain_len = 1000000;
#else
      mpz_urandomb (bs, rands, 32);
      chain_len = mpz_get_ui (bs) % (GMP_NUMB_BITS * MAX_SCHOENHAGE_THRESHOLD / 256);
#endif

      for (j = 0; j < chain_len; j++)
	{
	  mpz_urandomb (bs, rands, 32);
	  mpz_urandomb (bs, rands, mpz_get_ui (bs) % 12 + 1);
	  mpz_rrandomb (temp2, rands, mpz_get_ui (bs) + 1);
	  mpz_add_ui (temp2, temp2, 1);
	  mpz_mul (temp1, op2, temp2);
	  mpz_add (op1, op1, temp1);

	  /* Don't generate overly huge operands.  */
	  if (SIZ (op1) > 3 * MAX_SCHOENHAGE_THRESHOLD)
	    break;

	  mpz_urandomb (bs, rands, 32);
	  mpz_urandomb (bs, rands, mpz_get_ui (bs) % 12 + 1);
	  mpz_rrandomb (temp2, rands, mpz_get_ui (bs) + 1);
	  mpz_add_ui (temp2, temp2, 1);
	  mpz_mul (temp1, op1, temp2);
	  mpz_add (op2, op2, temp1);

	  /* Don't generate overly huge operands.  */
	  if (SIZ (op2) > 3 * MAX_SCHOENHAGE_THRESHOLD)
	    break;
	}
      one_test (op1, op2, ref, i);
    }

  mpz_clear (bs);
  mpz_clear (op1);
  mpz_clear (op2);
  mpz_clear (ref);
  mpz_clear (gcd1);
  mpz_clear (gcd2);
  mpz_clear (temp1);
  mpz_clear (temp2);
  mpz_clear (temp3);
  mpz_clear (s);
  mpz_clear (t);

  tests_end ();
  exit (0);
}
Ejemplo n.º 6
0
int
main (int argc, char **argv)
{
    mpz_t op1, op2;
    mpz_t prod, quot;
    mp_size_t size;
    int i;
    int reps = 5000;
    gmp_randstate_ptr rands;
    mpz_t bs;
    unsigned long bsi, size_range;

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

    rands = RANDS;

    mp_trace_base = -16;

    mpz_init (bs);

    mpz_init (op1);
    mpz_init (op2);
    mpz_init (prod);
    mpz_init (quot);

    for (i = 0; i < reps; i++)
    {
        mpz_urandomb (bs, rands, 32);
        size_range = mpz_get_ui (bs) % 17 + 2; /* 0..2047 bit operands */

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

        do
        {
            mpz_urandomb (bs, rands, size_range);
            size = mpz_get_ui (bs);
            mpz_rrandomb (op2, rands, size);
        }
        while (mpz_sgn (op2) == 0);

        mpz_urandomb (bs, rands, 2);
        bsi = mpz_get_ui (bs);
        if ((bsi & 1) != 0)
            mpz_neg (op1, op1);
        if ((bsi & 2) != 0)
            mpz_neg (op2, op2);

        mpz_mul (prod, op1, op2);

        mpz_divexact (quot, prod, op2);
        MPZ_CHECK_FORMAT (quot);

        if (mpz_cmp (quot, op1) != 0)
        {
            printf ("Wrong results:\n");
            mpz_trace ("  got     ", quot);
            mpz_trace ("  want    ", op1);
            mpz_trace ("  dividend", prod);
            mpz_trace ("  divisor ", op2);
            abort ();
        }
    }

    mpz_clear (bs);
    mpz_clear (op1);
    mpz_clear (op2);
    mpz_clear (prod);
    mpz_clear (quot);

    tests_end ();
    exit (0);
}
Ejemplo n.º 7
0
int
main (int argc, char **argv)
{
  mp_ptr ap, bp, rp, refp;
  mp_size_t max_n, n;
  gmp_randstate_ptr rands;
  long test, reps = 1000;
  TMP_SDECL;
  TMP_SMARK;

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

  rands = RANDS;

  max_n = 32;

  ap = TMP_SALLOC_LIMBS (max_n);
  bp = TMP_SALLOC_LIMBS (max_n);
  rp = TMP_SALLOC_LIMBS (max_n);
  refp = TMP_SALLOC_LIMBS (max_n);

  for (test = 0; test < reps; test++)
    {
      for (n = 1; n <= max_n; n++)
	{
	  mpn_random2 (ap, n);
	  mpn_random2 (bp, n);

	  refmpn_and_n (refp, ap, bp, n);
	  mpn_and_n (rp, ap, bp, n);
	  check_one (refp, rp, ap, bp, n, "and_n");

	  refmpn_ior_n (refp, ap, bp, n);
	  mpn_ior_n (rp, ap, bp, n);
	  check_one (refp, rp, ap, bp, n, "ior_n");

	  refmpn_xor_n (refp, ap, bp, n);
	  mpn_xor_n (rp, ap, bp, n);
	  check_one (refp, rp, ap, bp, n, "xor_n");

	  refmpn_andn_n (refp, ap, bp, n);
	  mpn_andn_n (rp, ap, bp, n);
	  check_one (refp, rp, ap, bp, n, "andn_n");

	  refmpn_iorn_n (refp, ap, bp, n);
	  mpn_iorn_n (rp, ap, bp, n);
	  check_one (refp, rp, ap, bp, n, "iorn_n");

	  refmpn_nand_n (refp, ap, bp, n);
	  mpn_nand_n (rp, ap, bp, n);
	  check_one (refp, rp, ap, bp, n, "nand_n");

	  refmpn_nior_n (refp, ap, bp, n);
	  mpn_nior_n (rp, ap, bp, n);
	  check_one (refp, rp, ap, bp, n, "nior_n");

	  refmpn_xnor_n (refp, ap, bp, n);
	  mpn_xnor_n (rp, ap, bp, n);
	  check_one (refp, rp, ap, bp, n, "xnor_n");

	  refmpn_com (refp, ap, n);
	  mpn_com (rp, ap, n);
	  check_one (refp, rp, ap, bp, n, "com");
	}
    }

  TMP_SFREE;
  tests_end ();
  return 0;
}
Ejemplo n.º 8
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);
}