Blame tests/mpz/t-jac.c

Packit 5c3484
/* Exercise mpz_*_kronecker_*() and mpz_jacobi() functions.
Packit 5c3484
Packit 5c3484
Copyright 1999-2004, 2013 Free Software Foundation, Inc.
Packit 5c3484
Packit 5c3484
This file is part of the GNU MP Library test suite.
Packit 5c3484
Packit 5c3484
The GNU MP Library test suite is free software; you can redistribute it
Packit 5c3484
and/or modify it under the terms of the GNU General Public License as
Packit 5c3484
published by the Free Software Foundation; either version 3 of the License,
Packit 5c3484
or (at your option) any later version.
Packit 5c3484
Packit 5c3484
The GNU MP Library test suite is distributed in the hope that it will be
Packit 5c3484
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 5c3484
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
Packit 5c3484
Public License for more details.
Packit 5c3484
Packit 5c3484
You should have received a copy of the GNU General Public License along with
Packit 5c3484
the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
Packit 5c3484
Packit 5c3484
Packit 5c3484
/* With no arguments the various Kronecker/Jacobi symbol routines are
Packit 5c3484
   checked against some test data and a lot of derived data.
Packit 5c3484
Packit 5c3484
   To check the test data against PARI-GP, run
Packit 5c3484
Packit 5c3484
	   t-jac -p | gp -q
Packit 5c3484
Packit 5c3484
   It takes a while because the output from "t-jac -p" is big.
Packit 5c3484
Packit 5c3484
Packit 5c3484
   Enhancements:
Packit 5c3484
Packit 5c3484
   More big test cases than those given by check_squares_zi would be good.  */
Packit 5c3484
Packit 5c3484
Packit 5c3484
#include <stdio.h>
Packit 5c3484
#include <stdlib.h>
Packit 5c3484
#include <string.h>
Packit 5c3484
Packit 5c3484
#include "gmp.h"
Packit 5c3484
#include "gmp-impl.h"
Packit 5c3484
#include "tests.h"
Packit 5c3484
Packit 5c3484
#ifdef _LONG_LONG_LIMB
Packit 5c3484
#define LL(l,ll)  ll
Packit 5c3484
#else
Packit 5c3484
#define LL(l,ll)  l
Packit 5c3484
#endif
Packit 5c3484
Packit 5c3484
Packit 5c3484
int option_pari = 0;
Packit 5c3484
Packit 5c3484
Packit 5c3484
unsigned long
Packit 5c3484
mpz_mod4 (mpz_srcptr z)
Packit 5c3484
{
Packit 5c3484
  mpz_t          m;
Packit 5c3484
  unsigned long  ret;
Packit 5c3484
Packit 5c3484
  mpz_init (m);
Packit 5c3484
  mpz_fdiv_r_2exp (m, z, 2);
Packit 5c3484
  ret = mpz_get_ui (m);
Packit 5c3484
  mpz_clear (m);
Packit 5c3484
  return ret;
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
int
Packit 5c3484
mpz_fits_ulimb_p (mpz_srcptr z)
Packit 5c3484
{
Packit 5c3484
  return (SIZ(z) == 1 || SIZ(z) == 0);
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
mp_limb_t
Packit 5c3484
mpz_get_ulimb (mpz_srcptr z)
Packit 5c3484
{
Packit 5c3484
  if (SIZ(z) == 0)
Packit 5c3484
    return 0;
Packit 5c3484
  else
Packit 5c3484
    return PTR(z)[0];
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
Packit 5c3484
void
Packit 5c3484
try_base (mp_limb_t a, mp_limb_t b, int answer)
Packit 5c3484
{
Packit 5c3484
  int  got;
Packit 5c3484
Packit 5c3484
  if ((b & 1) == 0 || b == 1 || a > b)
Packit 5c3484
    return;
Packit 5c3484
Packit 5c3484
  got = mpn_jacobi_base (a, b, 0);
Packit 5c3484
  if (got != answer)
Packit 5c3484
    {
Packit 5c3484
      printf (LL("mpn_jacobi_base (%lu, %lu) is %d should be %d\n",
Packit 5c3484
		 "mpn_jacobi_base (%llu, %llu) is %d should be %d\n"),
Packit 5c3484
	      a, b, got, answer);
Packit 5c3484
      abort ();
Packit 5c3484
    }
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
Packit 5c3484
void
Packit 5c3484
try_zi_ui (mpz_srcptr a, unsigned long b, int answer)
Packit 5c3484
{
Packit 5c3484
  int  got;
Packit 5c3484
Packit 5c3484
  got = mpz_kronecker_ui (a, b);
Packit 5c3484
  if (got != answer)
Packit 5c3484
    {
Packit 5c3484
      printf ("mpz_kronecker_ui (");
Packit 5c3484
      mpz_out_str (stdout, 10, a);
Packit 5c3484
      printf (", %lu) is %d should be %d\n", b, got, answer);
Packit 5c3484
      abort ();
Packit 5c3484
    }
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
Packit 5c3484
void
Packit 5c3484
try_zi_si (mpz_srcptr a, long b, int answer)
Packit 5c3484
{
Packit 5c3484
  int  got;
Packit 5c3484
Packit 5c3484
  got = mpz_kronecker_si (a, b);
Packit 5c3484
  if (got != answer)
Packit 5c3484
    {
Packit 5c3484
      printf ("mpz_kronecker_si (");
Packit 5c3484
      mpz_out_str (stdout, 10, a);
Packit 5c3484
      printf (", %ld) is %d should be %d\n", b, got, answer);
Packit 5c3484
      abort ();
Packit 5c3484
    }
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
Packit 5c3484
void
Packit 5c3484
try_ui_zi (unsigned long a, mpz_srcptr b, int answer)
Packit 5c3484
{
Packit 5c3484
  int  got;
Packit 5c3484
Packit 5c3484
  got = mpz_ui_kronecker (a, b);
Packit 5c3484
  if (got != answer)
Packit 5c3484
    {
Packit 5c3484
      printf ("mpz_ui_kronecker (%lu, ", a);
Packit 5c3484
      mpz_out_str (stdout, 10, b);
Packit 5c3484
      printf (") is %d should be %d\n", got, answer);
Packit 5c3484
      abort ();
Packit 5c3484
    }
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
Packit 5c3484
void
Packit 5c3484
try_si_zi (long a, mpz_srcptr b, int answer)
Packit 5c3484
{
Packit 5c3484
  int  got;
Packit 5c3484
Packit 5c3484
  got = mpz_si_kronecker (a, b);
Packit 5c3484
  if (got != answer)
Packit 5c3484
    {
Packit 5c3484
      printf ("mpz_si_kronecker (%ld, ", a);
Packit 5c3484
      mpz_out_str (stdout, 10, b);
Packit 5c3484
      printf (") is %d should be %d\n", got, answer);
Packit 5c3484
      abort ();
Packit 5c3484
    }
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
Packit 5c3484
/* Don't bother checking mpz_jacobi, since it only differs for b even, and
Packit 5c3484
   we don't have an actual expected answer for it.  tests/devel/try.c does
Packit 5c3484
   some checks though.  */
Packit 5c3484
void
Packit 5c3484
try_zi_zi (mpz_srcptr a, mpz_srcptr b, int answer)
Packit 5c3484
{
Packit 5c3484
  int  got;
Packit 5c3484
Packit 5c3484
  got = mpz_kronecker (a, b);
Packit 5c3484
  if (got != answer)
Packit 5c3484
    {
Packit 5c3484
      printf ("mpz_kronecker (");
Packit 5c3484
      mpz_out_str (stdout, 10, a);
Packit 5c3484
      printf (", ");
Packit 5c3484
      mpz_out_str (stdout, 10, b);
Packit 5c3484
      printf (") is %d should be %d\n", got, answer);
Packit 5c3484
      abort ();
Packit 5c3484
    }
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
Packit 5c3484
void
Packit 5c3484
try_pari (mpz_srcptr a, mpz_srcptr b, int answer)
Packit 5c3484
{
Packit 5c3484
  printf ("try(");
Packit 5c3484
  mpz_out_str (stdout, 10, a);
Packit 5c3484
  printf (",");
Packit 5c3484
  mpz_out_str (stdout, 10, b);
Packit 5c3484
  printf (",%d)\n", answer);
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
Packit 5c3484
void
Packit 5c3484
try_each (mpz_srcptr a, mpz_srcptr b, int answer)
Packit 5c3484
{
Packit 5c3484
#if 0
Packit 5c3484
  fprintf(stderr, "asize = %d, bsize = %d\n",
Packit 5c3484
	  mpz_sizeinbase (a, 2), mpz_sizeinbase (b, 2));
Packit 5c3484
#endif
Packit 5c3484
  if (option_pari)
Packit 5c3484
    {
Packit 5c3484
      try_pari (a, b, answer);
Packit 5c3484
      return;
Packit 5c3484
    }
Packit 5c3484
Packit 5c3484
  if (mpz_fits_ulimb_p (a) && mpz_fits_ulimb_p (b))
Packit 5c3484
    try_base (mpz_get_ulimb (a), mpz_get_ulimb (b), answer);
Packit 5c3484
Packit 5c3484
  if (mpz_fits_ulong_p (b))
Packit 5c3484
    try_zi_ui (a, mpz_get_ui (b), answer);
Packit 5c3484
Packit 5c3484
  if (mpz_fits_slong_p (b))
Packit 5c3484
    try_zi_si (a, mpz_get_si (b), answer);
Packit 5c3484
Packit 5c3484
  if (mpz_fits_ulong_p (a))
Packit 5c3484
    try_ui_zi (mpz_get_ui (a), b, answer);
Packit 5c3484
Packit 5c3484
  if (mpz_fits_sint_p (a))
Packit 5c3484
    try_si_zi (mpz_get_si (a), b, answer);
Packit 5c3484
Packit 5c3484
  try_zi_zi (a, b, answer);
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
Packit 5c3484
/* Try (a/b) and (a/-b). */
Packit 5c3484
void
Packit 5c3484
try_pn (mpz_srcptr a, mpz_srcptr b_orig, int answer)
Packit 5c3484
{
Packit 5c3484
  mpz_t  b;
Packit 5c3484
Packit 5c3484
  mpz_init_set (b, b_orig);
Packit 5c3484
  try_each (a, b, answer);
Packit 5c3484
Packit 5c3484
  mpz_neg (b, b);
Packit 5c3484
  if (mpz_sgn (a) < 0)
Packit 5c3484
    answer = -answer;
Packit 5c3484
Packit 5c3484
  try_each (a, b, answer);
Packit 5c3484
Packit 5c3484
  mpz_clear (b);
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
Packit 5c3484
/* Try (a+k*p/b) for various k, using the fact (a/b) is periodic in a with
Packit 5c3484
   period p.  For b>0, p=b if b!=2mod4 or p=4*b if b==2mod4. */
Packit 5c3484
Packit 5c3484
void
Packit 5c3484
try_periodic_num (mpz_srcptr a_orig, mpz_srcptr b, int answer)
Packit 5c3484
{
Packit 5c3484
  mpz_t  a, a_period;
Packit 5c3484
  int    i;
Packit 5c3484
Packit 5c3484
  if (mpz_sgn (b) <= 0)
Packit 5c3484
    return;
Packit 5c3484
Packit 5c3484
  mpz_init_set (a, a_orig);
Packit 5c3484
  mpz_init_set (a_period, b);
Packit 5c3484
  if (mpz_mod4 (b) == 2)
Packit 5c3484
    mpz_mul_ui (a_period, a_period, 4);
Packit 5c3484
Packit 5c3484
  /* don't bother with these tests if they're only going to produce
Packit 5c3484
     even/even */
Packit 5c3484
  if (mpz_even_p (a) && mpz_even_p (b) && mpz_even_p (a_period))
Packit 5c3484
    goto done;
Packit 5c3484
Packit 5c3484
  for (i = 0; i < 6; i++)
Packit 5c3484
    {
Packit 5c3484
      mpz_add (a, a, a_period);
Packit 5c3484
      try_pn (a, b, answer);
Packit 5c3484
    }
Packit 5c3484
Packit 5c3484
  mpz_set (a, a_orig);
Packit 5c3484
  for (i = 0; i < 6; i++)
Packit 5c3484
    {
Packit 5c3484
      mpz_sub (a, a, a_period);
Packit 5c3484
      try_pn (a, b, answer);
Packit 5c3484
    }
Packit 5c3484
Packit 5c3484
 done:
Packit 5c3484
  mpz_clear (a);
Packit 5c3484
  mpz_clear (a_period);
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
Packit 5c3484
/* Try (a/b+k*p) for various k, using the fact (a/b) is periodic in b of
Packit 5c3484
   period p.
Packit 5c3484
Packit 5c3484
			       period p
Packit 5c3484
	   a==0,1mod4             a
Packit 5c3484
	   a==2mod4              4*a
Packit 5c3484
	   a==3mod4 and b odd    4*a
Packit 5c3484
	   a==3mod4 and b even   8*a
Packit 5c3484
Packit 5c3484
   In Henri Cohen's book the period is given as 4*a for all a==2,3mod4, but
Packit 5c3484
   a counterexample would seem to be (3/2)=-1 which with (3/14)=+1 doesn't
Packit 5c3484
   have period 4*a (but rather 8*a with (3/26)=-1).  Maybe the plain 4*a is
Packit 5c3484
   to be read as applying to a plain Jacobi symbol with b odd, rather than
Packit 5c3484
   the Kronecker extension to b even. */
Packit 5c3484
Packit 5c3484
void
Packit 5c3484
try_periodic_den (mpz_srcptr a, mpz_srcptr b_orig, int answer)
Packit 5c3484
{
Packit 5c3484
  mpz_t  b, b_period;
Packit 5c3484
  int    i;
Packit 5c3484
Packit 5c3484
  if (mpz_sgn (a) == 0 || mpz_sgn (b_orig) == 0)
Packit 5c3484
    return;
Packit 5c3484
Packit 5c3484
  mpz_init_set (b, b_orig);
Packit 5c3484
Packit 5c3484
  mpz_init_set (b_period, a);
Packit 5c3484
  if (mpz_mod4 (a) == 3 && mpz_even_p (b))
Packit 5c3484
    mpz_mul_ui (b_period, b_period, 8L);
Packit 5c3484
  else if (mpz_mod4 (a) >= 2)
Packit 5c3484
    mpz_mul_ui (b_period, b_period, 4L);
Packit 5c3484
Packit 5c3484
  /* don't bother with these tests if they're only going to produce
Packit 5c3484
     even/even */
Packit 5c3484
  if (mpz_even_p (a) && mpz_even_p (b) && mpz_even_p (b_period))
Packit 5c3484
    goto done;
Packit 5c3484
Packit 5c3484
  for (i = 0; i < 6; i++)
Packit 5c3484
    {
Packit 5c3484
      mpz_add (b, b, b_period);
Packit 5c3484
      try_pn (a, b, answer);
Packit 5c3484
    }
Packit 5c3484
Packit 5c3484
  mpz_set (b, b_orig);
Packit 5c3484
  for (i = 0; i < 6; i++)
Packit 5c3484
    {
Packit 5c3484
      mpz_sub (b, b, b_period);
Packit 5c3484
      try_pn (a, b, answer);
Packit 5c3484
    }
Packit 5c3484
Packit 5c3484
 done:
Packit 5c3484
  mpz_clear (b);
Packit 5c3484
  mpz_clear (b_period);
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
Packit 5c3484
static const unsigned long  ktable[] = {
Packit 5c3484
  0, 1, 2, 3, 4, 5, 6, 7,
Packit 5c3484
  GMP_NUMB_BITS-1, GMP_NUMB_BITS, GMP_NUMB_BITS+1,
Packit 5c3484
  2*GMP_NUMB_BITS-1, 2*GMP_NUMB_BITS, 2*GMP_NUMB_BITS+1,
Packit 5c3484
  3*GMP_NUMB_BITS-1, 3*GMP_NUMB_BITS, 3*GMP_NUMB_BITS+1
Packit 5c3484
};
Packit 5c3484
Packit 5c3484
Packit 5c3484
/* Try (a/b*2^k) for various k. */
Packit 5c3484
void
Packit 5c3484
try_2den (mpz_srcptr a, mpz_srcptr b_orig, int answer)
Packit 5c3484
{
Packit 5c3484
  mpz_t  b;
Packit 5c3484
  int    kindex;
Packit 5c3484
  int    answer_a2, answer_k;
Packit 5c3484
  unsigned long k;
Packit 5c3484
Packit 5c3484
  /* don't bother when b==0 */
Packit 5c3484
  if (mpz_sgn (b_orig) == 0)
Packit 5c3484
    return;
Packit 5c3484
Packit 5c3484
  mpz_init_set (b, b_orig);
Packit 5c3484
Packit 5c3484
  /* (a/2) is 0 if a even, 1 if a==1 or 7 mod 8, -1 if a==3 or 5 mod 8 */
Packit 5c3484
  answer_a2 = (mpz_even_p (a) ? 0
Packit 5c3484
	       : (((SIZ(a) >= 0 ? PTR(a)[0] : -PTR(a)[0]) + 2) & 7) < 4 ? 1
Packit 5c3484
	       : -1);
Packit 5c3484
Packit 5c3484
  for (kindex = 0; kindex < numberof (ktable); kindex++)
Packit 5c3484
    {
Packit 5c3484
      k = ktable[kindex];
Packit 5c3484
Packit 5c3484
      /* answer_k = answer*(answer_a2^k) */
Packit 5c3484
      answer_k = (answer_a2 == 0 && k != 0 ? 0
Packit 5c3484
		  : (k & 1) == 1 && answer_a2 == -1 ? -answer
Packit 5c3484
		  : answer);
Packit 5c3484
Packit 5c3484
      mpz_mul_2exp (b, b_orig, k);
Packit 5c3484
      try_pn (a, b, answer_k);
Packit 5c3484
    }
Packit 5c3484
Packit 5c3484
  mpz_clear (b);
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
Packit 5c3484
/* Try (a*2^k/b) for various k.  If it happens mpz_ui_kronecker() gets (2/b)
Packit 5c3484
   wrong it will show up as wrong answers demanded. */
Packit 5c3484
void
Packit 5c3484
try_2num (mpz_srcptr a_orig, mpz_srcptr b, int answer)
Packit 5c3484
{
Packit 5c3484
  mpz_t  a;
Packit 5c3484
  int    kindex;
Packit 5c3484
  int    answer_2b, answer_k;
Packit 5c3484
  unsigned long  k;
Packit 5c3484
Packit 5c3484
  /* don't bother when a==0 */
Packit 5c3484
  if (mpz_sgn (a_orig) == 0)
Packit 5c3484
    return;
Packit 5c3484
Packit 5c3484
  mpz_init (a);
Packit 5c3484
Packit 5c3484
  /* (2/b) is 0 if b even, 1 if b==1 or 7 mod 8, -1 if b==3 or 5 mod 8 */
Packit 5c3484
  answer_2b = (mpz_even_p (b) ? 0
Packit 5c3484
	       : (((SIZ(b) >= 0 ? PTR(b)[0] : -PTR(b)[0]) + 2) & 7) < 4 ? 1
Packit 5c3484
	       : -1);
Packit 5c3484
Packit 5c3484
  for (kindex = 0; kindex < numberof (ktable); kindex++)
Packit 5c3484
    {
Packit 5c3484
      k = ktable[kindex];
Packit 5c3484
Packit 5c3484
      /* answer_k = answer*(answer_2b^k) */
Packit 5c3484
      answer_k = (answer_2b == 0 && k != 0 ? 0
Packit 5c3484
		  : (k & 1) == 1 && answer_2b == -1 ? -answer
Packit 5c3484
		  : answer);
Packit 5c3484
Packit 5c3484
	mpz_mul_2exp (a, a_orig, k);
Packit 5c3484
      try_pn (a, b, answer_k);
Packit 5c3484
    }
Packit 5c3484
Packit 5c3484
  mpz_clear (a);
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
Packit 5c3484
/* The try_2num() and try_2den() routines don't in turn call
Packit 5c3484
   try_periodic_num() and try_periodic_den() because it hugely increases the
Packit 5c3484
   number of tests performed, without obviously increasing coverage.
Packit 5c3484
Packit 5c3484
   Useful extra derived cases can be added here. */
Packit 5c3484
Packit 5c3484
void
Packit 5c3484
try_all (mpz_t a, mpz_t b, int answer)
Packit 5c3484
{
Packit 5c3484
  try_pn (a, b, answer);
Packit 5c3484
  try_periodic_num (a, b, answer);
Packit 5c3484
  try_periodic_den (a, b, answer);
Packit 5c3484
  try_2num (a, b, answer);
Packit 5c3484
  try_2den (a, b, answer);
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
Packit 5c3484
void
Packit 5c3484
check_data (void)
Packit 5c3484
{
Packit 5c3484
  static const struct {
Packit 5c3484
    const char  *a;
Packit 5c3484
    const char  *b;
Packit 5c3484
    int         answer;
Packit 5c3484
Packit 5c3484
  } data[] = {
Packit 5c3484
Packit 5c3484
    /* Note that the various derived checks in try_all() reduce the cases
Packit 5c3484
       that need to be given here.  */
Packit 5c3484
Packit 5c3484
    /* some zeros */
Packit 5c3484
    {  "0",  "0", 0 },
Packit 5c3484
    {  "0",  "2", 0 },
Packit 5c3484
    {  "0",  "6", 0 },
Packit 5c3484
    {  "5",  "0", 0 },
Packit 5c3484
    { "24", "60", 0 },
Packit 5c3484
Packit 5c3484
    /* (a/1) = 1, any a
Packit 5c3484
       In particular note (0/1)=1 so that (a/b)=(a mod b/b). */
Packit 5c3484
    { "0", "1", 1 },
Packit 5c3484
    { "1", "1", 1 },
Packit 5c3484
    { "2", "1", 1 },
Packit 5c3484
    { "3", "1", 1 },
Packit 5c3484
    { "4", "1", 1 },
Packit 5c3484
    { "5", "1", 1 },
Packit 5c3484
Packit 5c3484
    /* (0/b) = 0, b != 1 */
Packit 5c3484
    { "0",  "3", 0 },
Packit 5c3484
    { "0",  "5", 0 },
Packit 5c3484
    { "0",  "7", 0 },
Packit 5c3484
    { "0",  "9", 0 },
Packit 5c3484
    { "0", "11", 0 },
Packit 5c3484
    { "0", "13", 0 },
Packit 5c3484
    { "0", "15", 0 },
Packit 5c3484
Packit 5c3484
    /* (1/b) = 1 */
Packit 5c3484
    { "1",  "1", 1 },
Packit 5c3484
    { "1",  "3", 1 },
Packit 5c3484
    { "1",  "5", 1 },
Packit 5c3484
    { "1",  "7", 1 },
Packit 5c3484
    { "1",  "9", 1 },
Packit 5c3484
    { "1", "11", 1 },
Packit 5c3484
Packit 5c3484
    /* (-1/b) = (-1)^((b-1)/2) which is -1 for b==3 mod 4 */
Packit 5c3484
    { "-1",  "1",  1 },
Packit 5c3484
    { "-1",  "3", -1 },
Packit 5c3484
    { "-1",  "5",  1 },
Packit 5c3484
    { "-1",  "7", -1 },
Packit 5c3484
    { "-1",  "9",  1 },
Packit 5c3484
    { "-1", "11", -1 },
Packit 5c3484
    { "-1", "13",  1 },
Packit 5c3484
    { "-1", "15", -1 },
Packit 5c3484
    { "-1", "17",  1 },
Packit 5c3484
    { "-1", "19", -1 },
Packit 5c3484
Packit 5c3484
    /* (2/b) = (-1)^((b^2-1)/8) which is -1 for b==3,5 mod 8.
Packit 5c3484
       try_2num() will exercise multiple powers of 2 in the numerator.  */
Packit 5c3484
    { "2",  "1",  1 },
Packit 5c3484
    { "2",  "3", -1 },
Packit 5c3484
    { "2",  "5", -1 },
Packit 5c3484
    { "2",  "7",  1 },
Packit 5c3484
    { "2",  "9",  1 },
Packit 5c3484
    { "2", "11", -1 },
Packit 5c3484
    { "2", "13", -1 },
Packit 5c3484
    { "2", "15",  1 },
Packit 5c3484
    { "2", "17",  1 },
Packit 5c3484
Packit 5c3484
    /* (-2/b) = (-1)^((b^2-1)/8)*(-1)^((b-1)/2) which is -1 for b==5,7mod8.
Packit 5c3484
       try_2num() will exercise multiple powers of 2 in the numerator, which
Packit 5c3484
       will test that the shift in mpz_si_kronecker() uses unsigned not
Packit 5c3484
       signed.  */
Packit 5c3484
    { "-2",  "1",  1 },
Packit 5c3484
    { "-2",  "3",  1 },
Packit 5c3484
    { "-2",  "5", -1 },
Packit 5c3484
    { "-2",  "7", -1 },
Packit 5c3484
    { "-2",  "9",  1 },
Packit 5c3484
    { "-2", "11",  1 },
Packit 5c3484
    { "-2", "13", -1 },
Packit 5c3484
    { "-2", "15", -1 },
Packit 5c3484
    { "-2", "17",  1 },
Packit 5c3484
Packit 5c3484
    /* (a/2)=(2/a).
Packit 5c3484
       try_2den() will exercise multiple powers of 2 in the denominator. */
Packit 5c3484
    {  "3",  "2", -1 },
Packit 5c3484
    {  "5",  "2", -1 },
Packit 5c3484
    {  "7",  "2",  1 },
Packit 5c3484
    {  "9",  "2",  1 },
Packit 5c3484
    {  "11", "2", -1 },
Packit 5c3484
Packit 5c3484
    /* Harriet Griffin, "Elementary Theory of Numbers", page 155, various
Packit 5c3484
       examples.  */
Packit 5c3484
    {   "2", "135",  1 },
Packit 5c3484
    { "135",  "19", -1 },
Packit 5c3484
    {   "2",  "19", -1 },
Packit 5c3484
    {  "19", "135",  1 },
Packit 5c3484
    { "173", "135",  1 },
Packit 5c3484
    {  "38", "135",  1 },
Packit 5c3484
    { "135", "173",  1 },
Packit 5c3484
    { "173",   "5", -1 },
Packit 5c3484
    {   "3",   "5", -1 },
Packit 5c3484
    {   "5", "173", -1 },
Packit 5c3484
    { "173",   "3", -1 },
Packit 5c3484
    {   "2",   "3", -1 },
Packit 5c3484
    {   "3", "173", -1 },
Packit 5c3484
    { "253",  "21",  1 },
Packit 5c3484
    {   "1",  "21",  1 },
Packit 5c3484
    {  "21", "253",  1 },
Packit 5c3484
    {  "21",  "11", -1 },
Packit 5c3484
    {  "-1",  "11", -1 },
Packit 5c3484
Packit 5c3484
    /* Griffin page 147 */
Packit 5c3484
    {  "-1",  "17",  1 },
Packit 5c3484
    {   "2",  "17",  1 },
Packit 5c3484
    {  "-2",  "17",  1 },
Packit 5c3484
    {  "-1",  "89",  1 },
Packit 5c3484
    {   "2",  "89",  1 },
Packit 5c3484
Packit 5c3484
    /* Griffin page 148 */
Packit 5c3484
    {  "89",  "11",  1 },
Packit 5c3484
    {   "1",  "11",  1 },
Packit 5c3484
    {  "89",   "3", -1 },
Packit 5c3484
    {   "2",   "3", -1 },
Packit 5c3484
    {   "3",  "89", -1 },
Packit 5c3484
    {  "11",  "89",  1 },
Packit 5c3484
    {  "33",  "89", -1 },
Packit 5c3484
Packit 5c3484
    /* H. Davenport, "The Higher Arithmetic", page 65, the quadratic
Packit 5c3484
       residues and non-residues mod 19.  */
Packit 5c3484
    {  "1", "19",  1 },
Packit 5c3484
    {  "4", "19",  1 },
Packit 5c3484
    {  "5", "19",  1 },
Packit 5c3484
    {  "6", "19",  1 },
Packit 5c3484
    {  "7", "19",  1 },
Packit 5c3484
    {  "9", "19",  1 },
Packit 5c3484
    { "11", "19",  1 },
Packit 5c3484
    { "16", "19",  1 },
Packit 5c3484
    { "17", "19",  1 },
Packit 5c3484
    {  "2", "19", -1 },
Packit 5c3484
    {  "3", "19", -1 },
Packit 5c3484
    {  "8", "19", -1 },
Packit 5c3484
    { "10", "19", -1 },
Packit 5c3484
    { "12", "19", -1 },
Packit 5c3484
    { "13", "19", -1 },
Packit 5c3484
    { "14", "19", -1 },
Packit 5c3484
    { "15", "19", -1 },
Packit 5c3484
    { "18", "19", -1 },
Packit 5c3484
Packit 5c3484
    /* Residues and non-residues mod 13 */
Packit 5c3484
    {  "0",  "13",  0 },
Packit 5c3484
    {  "1",  "13",  1 },
Packit 5c3484
    {  "2",  "13", -1 },
Packit 5c3484
    {  "3",  "13",  1 },
Packit 5c3484
    {  "4",  "13",  1 },
Packit 5c3484
    {  "5",  "13", -1 },
Packit 5c3484
    {  "6",  "13", -1 },
Packit 5c3484
    {  "7",  "13", -1 },
Packit 5c3484
    {  "8",  "13", -1 },
Packit 5c3484
    {  "9",  "13",  1 },
Packit 5c3484
    { "10",  "13",  1 },
Packit 5c3484
    { "11",  "13", -1 },
Packit 5c3484
    { "12",  "13",  1 },
Packit 5c3484
Packit 5c3484
    /* various */
Packit 5c3484
    {  "5",   "7", -1 },
Packit 5c3484
    { "15",  "17",  1 },
Packit 5c3484
    { "67",  "89",  1 },
Packit 5c3484
Packit 5c3484
    /* special values inducing a==b==1 at the end of jac_or_kron() */
Packit 5c3484
    { "0x10000000000000000000000000000000000000000000000001",
Packit 5c3484
      "0x10000000000000000000000000000000000000000000000003", 1 },
Packit 5c3484
Packit 5c3484
    /* Test for previous bugs in jacobi_2. */
Packit 5c3484
    { "0x43900000000", "0x42400000439", -1 }, /* 32-bit limbs */
Packit 5c3484
    { "0x4390000000000000000", "0x4240000000000000439", -1 }, /* 64-bit limbs */
Packit 5c3484
Packit 5c3484
    { "198158408161039063", "198158360916398807", -1 },
Packit 5c3484
Packit 5c3484
    /* Some tests involving large quotients in the continued fraction
Packit 5c3484
       expansion. */
Packit 5c3484
    { "37200210845139167613356125645445281805",
Packit 5c3484
      "451716845976689892447895811408978421929", -1 },
Packit 5c3484
    { "67674091930576781943923596701346271058970643542491743605048620644676477275152701774960868941561652032482173612421015",
Packit 5c3484
      "4902678867794567120224500687210807069172039735", 0 },
Packit 5c3484
    { "2666617146103764067061017961903284334497474492754652499788571378062969111250584288683585223600172138551198546085281683283672592", "2666617146103764067061017961903284334497474492754652499788571378062969111250584288683585223600172138551198546085281683290481773", 1 },
Packit 5c3484
Packit 5c3484
    /* Exercises the case asize == 1, btwos > 0 in mpz_jacobi. */
Packit 5c3484
    { "804609", "421248363205206617296534688032638102314410556521742428832362659824", 1 } ,
Packit 5c3484
    { "4190209", "2239744742177804210557442048984321017460028974602978995388383905961079286530650825925074203175536427000", 1 },
Packit 5c3484
Packit 5c3484
    /* Exercises the case asize == 1, btwos = 63 in mpz_jacobi
Packit 5c3484
       (relevant when GMP_LIMB_BITS == 64). */
Packit 5c3484
    { "17311973299000934401", "1675975991242824637446753124775689449936871337036614677577044717424700351103148799107651171694863695242089956242888229458836426332300124417011114380886016", 1 },
Packit 5c3484
    { "3220569220116583677", "41859917623035396746", -1 },
Packit 5c3484
Packit 5c3484
    /* Other test cases that triggered bugs during development. */
Packit 5c3484
    { "37200210845139167613356125645445281805", "340116213441272389607827434472642576514", -1 },
Packit 5c3484
    { "74400421690278335226712251290890563610", "451716845976689892447895811408978421929", -1 },
Packit 5c3484
  };
Packit 5c3484
Packit 5c3484
  int    i;
Packit 5c3484
  mpz_t  a, b;
Packit 5c3484
Packit 5c3484
  mpz_init (a);
Packit 5c3484
  mpz_init (b);
Packit 5c3484
Packit 5c3484
  for (i = 0; i < numberof (data); i++)
Packit 5c3484
    {
Packit 5c3484
      mpz_set_str_or_abort (a, data[i].a, 0);
Packit 5c3484
      mpz_set_str_or_abort (b, data[i].b, 0);
Packit 5c3484
      try_all (a, b, data[i].answer);
Packit 5c3484
    }
Packit 5c3484
Packit 5c3484
  mpz_clear (a);
Packit 5c3484
  mpz_clear (b);
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
Packit 5c3484
/* (a^2/b)=1 if gcd(a,b)=1, or (a^2/b)=0 if gcd(a,b)!=1.
Packit 5c3484
   This includes when a=0 or b=0. */
Packit 5c3484
void
Packit 5c3484
check_squares_zi (void)
Packit 5c3484
{
Packit 5c3484
  gmp_randstate_ptr rands = RANDS;
Packit 5c3484
  mpz_t  a, b, g;
Packit 5c3484
  int    i, answer;
Packit 5c3484
  mp_size_t size_range, an, bn;
Packit 5c3484
  mpz_t bs;
Packit 5c3484
Packit 5c3484
  mpz_init (bs);
Packit 5c3484
  mpz_init (a);
Packit 5c3484
  mpz_init (b);
Packit 5c3484
  mpz_init (g);
Packit 5c3484
Packit 5c3484
  for (i = 0; i < 50; i++)
Packit 5c3484
    {
Packit 5c3484
      mpz_urandomb (bs, rands, 32);
Packit 5c3484
      size_range = mpz_get_ui (bs) % 10 + i/8 + 2;
Packit 5c3484
Packit 5c3484
      mpz_urandomb (bs, rands, size_range);
Packit 5c3484
      an = mpz_get_ui (bs);
Packit 5c3484
      mpz_rrandomb (a, rands, an);
Packit 5c3484
Packit 5c3484
      mpz_urandomb (bs, rands, size_range);
Packit 5c3484
      bn = mpz_get_ui (bs);
Packit 5c3484
      mpz_rrandomb (b, rands, bn);
Packit 5c3484
Packit 5c3484
      mpz_gcd (g, a, b);
Packit 5c3484
      if (mpz_cmp_ui (g, 1L) == 0)
Packit 5c3484
	answer = 1;
Packit 5c3484
      else
Packit 5c3484
	answer = 0;
Packit 5c3484
Packit 5c3484
      mpz_mul (a, a, a);
Packit 5c3484
Packit 5c3484
      try_all (a, b, answer);
Packit 5c3484
    }
Packit 5c3484
Packit 5c3484
  mpz_clear (bs);
Packit 5c3484
  mpz_clear (a);
Packit 5c3484
  mpz_clear (b);
Packit 5c3484
  mpz_clear (g);
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
Packit 5c3484
/* Check the handling of asize==0, make sure it isn't affected by the low
Packit 5c3484
   limb. */
Packit 5c3484
void
Packit 5c3484
check_a_zero (void)
Packit 5c3484
{
Packit 5c3484
  mpz_t  a, b;
Packit 5c3484
Packit 5c3484
  mpz_init_set_ui (a, 0);
Packit 5c3484
  mpz_init (b);
Packit 5c3484
Packit 5c3484
  mpz_set_ui (b, 1L);
Packit 5c3484
  PTR(a)[0] = 0;
Packit 5c3484
  try_all (a, b, 1);   /* (0/1)=1 */
Packit 5c3484
  PTR(a)[0] = 1;
Packit 5c3484
  try_all (a, b, 1);   /* (0/1)=1 */
Packit 5c3484
Packit 5c3484
  mpz_set_si (b, -1L);
Packit 5c3484
  PTR(a)[0] = 0;
Packit 5c3484
  try_all (a, b, 1);   /* (0/-1)=1 */
Packit 5c3484
  PTR(a)[0] = 1;
Packit 5c3484
  try_all (a, b, 1);   /* (0/-1)=1 */
Packit 5c3484
Packit 5c3484
  mpz_set_ui (b, 0);
Packit 5c3484
  PTR(a)[0] = 0;
Packit 5c3484
  try_all (a, b, 0);   /* (0/0)=0 */
Packit 5c3484
  PTR(a)[0] = 1;
Packit 5c3484
  try_all (a, b, 0);   /* (0/0)=0 */
Packit 5c3484
Packit 5c3484
  mpz_set_ui (b, 2);
Packit 5c3484
  PTR(a)[0] = 0;
Packit 5c3484
  try_all (a, b, 0);   /* (0/2)=0 */
Packit 5c3484
  PTR(a)[0] = 1;
Packit 5c3484
  try_all (a, b, 0);   /* (0/2)=0 */
Packit 5c3484
Packit 5c3484
  mpz_clear (a);
Packit 5c3484
  mpz_clear (b);
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
Packit 5c3484
/* Assumes that b = prod p_k^e_k */
Packit 5c3484
int
Packit 5c3484
ref_jacobi (mpz_srcptr a, mpz_srcptr b, unsigned nprime,
Packit 5c3484
	    mpz_t prime[], unsigned *exp)
Packit 5c3484
{
Packit 5c3484
  unsigned i;
Packit 5c3484
  int res;
Packit 5c3484
Packit 5c3484
  for (i = 0, res = 1; i < nprime; i++)
Packit 5c3484
    if (exp[i])
Packit 5c3484
      {
Packit 5c3484
	int legendre = refmpz_legendre (a, prime[i]);
Packit 5c3484
	if (!legendre)
Packit 5c3484
	  return 0;
Packit 5c3484
	if (exp[i] & 1)
Packit 5c3484
	  res *= legendre;
Packit 5c3484
      }
Packit 5c3484
  return res;
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
void
Packit 5c3484
check_jacobi_factored (void)
Packit 5c3484
{
Packit 5c3484
#define PRIME_N 10
Packit 5c3484
#define PRIME_MAX_SIZE 50
Packit 5c3484
#define PRIME_MAX_EXP 4
Packit 5c3484
#define PRIME_A_COUNT 10
Packit 5c3484
#define PRIME_B_COUNT 5
Packit 5c3484
#define PRIME_MAX_B_SIZE 2000
Packit 5c3484
Packit 5c3484
  gmp_randstate_ptr rands = RANDS;
Packit 5c3484
  mpz_t prime[PRIME_N];
Packit 5c3484
  unsigned exp[PRIME_N];
Packit 5c3484
  mpz_t a, b, t, bs;
Packit 5c3484
  unsigned i;
Packit 5c3484
Packit 5c3484
  mpz_init (a);
Packit 5c3484
  mpz_init (b);
Packit 5c3484
  mpz_init (t);
Packit 5c3484
  mpz_init (bs);
Packit 5c3484
Packit 5c3484
  /* Generate primes */
Packit 5c3484
  for (i = 0; i < PRIME_N; i++)
Packit 5c3484
    {
Packit 5c3484
      mp_size_t size;
Packit 5c3484
      mpz_init (prime[i]);
Packit 5c3484
      mpz_urandomb (bs, rands, 32);
Packit 5c3484
      size = mpz_get_ui (bs) % PRIME_MAX_SIZE + 2;
Packit 5c3484
      mpz_rrandomb (prime[i], rands, size);
Packit 5c3484
      if (mpz_cmp_ui (prime[i], 3) <= 0)
Packit 5c3484
	mpz_set_ui (prime[i], 3);
Packit 5c3484
      else
Packit 5c3484
	mpz_nextprime (prime[i], prime[i]);
Packit 5c3484
    }
Packit 5c3484
Packit 5c3484
  for (i = 0; i < PRIME_B_COUNT; i++)
Packit 5c3484
    {
Packit 5c3484
      unsigned j, k;
Packit 5c3484
      mp_bitcnt_t bsize;
Packit 5c3484
Packit 5c3484
      mpz_set_ui (b, 1);
Packit 5c3484
      bsize = 1;
Packit 5c3484
Packit 5c3484
      for (j = 0; j < PRIME_N && bsize < PRIME_MAX_B_SIZE; j++)
Packit 5c3484
	{
Packit 5c3484
	  mpz_urandomb (bs, rands, 32);
Packit 5c3484
	  exp[j] = mpz_get_ui (bs) % PRIME_MAX_EXP;
Packit 5c3484
	  mpz_pow_ui (t, prime[j], exp[j]);
Packit 5c3484
	  mpz_mul (b, b, t);
Packit 5c3484
	  bsize = mpz_sizeinbase (b, 2);
Packit 5c3484
	}
Packit 5c3484
      for (k = 0; k < PRIME_A_COUNT; k++)
Packit 5c3484
	{
Packit 5c3484
	  int answer;
Packit 5c3484
	  mpz_rrandomb (a, rands, bsize + 2);
Packit 5c3484
	  answer = ref_jacobi (a, b, j, prime, exp);
Packit 5c3484
	  try_all (a, b, answer);
Packit 5c3484
	}
Packit 5c3484
    }
Packit 5c3484
  for (i = 0; i < PRIME_N; i++)
Packit 5c3484
    mpz_clear (prime[i]);
Packit 5c3484
Packit 5c3484
  mpz_clear (a);
Packit 5c3484
  mpz_clear (b);
Packit 5c3484
  mpz_clear (t);
Packit 5c3484
  mpz_clear (bs);
Packit 5c3484
Packit 5c3484
#undef PRIME_N
Packit 5c3484
#undef PRIME_MAX_SIZE
Packit 5c3484
#undef PRIME_MAX_EXP
Packit 5c3484
#undef PRIME_A_COUNT
Packit 5c3484
#undef PRIME_B_COUNT
Packit 5c3484
#undef PRIME_MAX_B_SIZE
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
/* These tests compute (a|n), where the quotient sequence includes
Packit 5c3484
   large quotients, and n has a known factorization. Such inputs are
Packit 5c3484
   generated as follows. First, construct a large n, as a power of a
Packit 5c3484
   prime p of moderate size.
Packit 5c3484
Packit 5c3484
   Next, compute a matrix from factors (q,1;1,0), with q chosen with
Packit 5c3484
   uniformly distributed size. We must stop with matrix elements of
Packit 5c3484
   roughly half the size of n. Denote elements of M as M = (m00, m01;
Packit 5c3484
   m10, m11).
Packit 5c3484
Packit 5c3484
   We now look for solutions to
Packit 5c3484
Packit 5c3484
     n = m00 x + m01 y
Packit 5c3484
     a = m10 x + m11 y
Packit 5c3484
Packit 5c3484
   with x,y > 0. Since n >= m00 * m01, there exists a positive
Packit 5c3484
   solution to the first equation. Find those x, y, and substitute in
Packit 5c3484
   the second equation to get a. Then the quotient sequence for (a|n)
Packit 5c3484
   is precisely the quotients used when constructing M, followed by
Packit 5c3484
   the quotient sequence for (x|y).
Packit 5c3484
Packit 5c3484
   Numbers should also be large enough that we exercise hgcd_jacobi,
Packit 5c3484
   which means that they should be larger than
Packit 5c3484
Packit 5c3484
     max (GCD_DC_THRESHOLD, 3 * HGCD_THRESHOLD)
Packit 5c3484
Packit 5c3484
   With an n of roughly 40000 bits, this should hold on most machines.
Packit 5c3484
*/
Packit 5c3484
Packit 5c3484
void
Packit 5c3484
check_large_quotients (void)
Packit 5c3484
{
Packit 5c3484
#define COUNT 50
Packit 5c3484
#define PBITS 200
Packit 5c3484
#define PPOWER 201
Packit 5c3484
#define MAX_QBITS 500
Packit 5c3484
Packit 5c3484
  gmp_randstate_ptr rands = RANDS;
Packit 5c3484
Packit 5c3484
  mpz_t p, n, q, g, s, t, x, y, bs;
Packit 5c3484
  mpz_t M[2][2];
Packit 5c3484
  mp_bitcnt_t nsize;
Packit 5c3484
  unsigned i;
Packit 5c3484
Packit 5c3484
  mpz_init (p);
Packit 5c3484
  mpz_init (n);
Packit 5c3484
  mpz_init (q);
Packit 5c3484
  mpz_init (g);
Packit 5c3484
  mpz_init (s);
Packit 5c3484
  mpz_init (t);
Packit 5c3484
  mpz_init (x);
Packit 5c3484
  mpz_init (y);
Packit 5c3484
  mpz_init (bs);
Packit 5c3484
  mpz_init (M[0][0]);
Packit 5c3484
  mpz_init (M[0][1]);
Packit 5c3484
  mpz_init (M[1][0]);
Packit 5c3484
  mpz_init (M[1][1]);
Packit 5c3484
Packit 5c3484
  /* First generate a number with known factorization, as a random
Packit 5c3484
     smallish prime raised to an odd power. Then (a|n) = (a|p). */
Packit 5c3484
  mpz_rrandomb (p, rands, PBITS);
Packit 5c3484
  mpz_nextprime (p, p);
Packit 5c3484
  mpz_pow_ui (n, p, PPOWER);
Packit 5c3484
Packit 5c3484
  nsize = mpz_sizeinbase (n, 2);
Packit 5c3484
Packit 5c3484
  for (i = 0; i < COUNT; i++)
Packit 5c3484
    {
Packit 5c3484
      int answer;
Packit 5c3484
      mp_bitcnt_t msize;
Packit 5c3484
Packit 5c3484
      mpz_set_ui (M[0][0], 1);
Packit 5c3484
      mpz_set_ui (M[0][1], 0);
Packit 5c3484
      mpz_set_ui (M[1][0], 0);
Packit 5c3484
      mpz_set_ui (M[1][1], 1);
Packit 5c3484
Packit 5c3484
      for (msize = 1; 2*(msize + MAX_QBITS) + 1 < nsize ;)
Packit 5c3484
	{
Packit 5c3484
	  unsigned i;
Packit 5c3484
	  mpz_rrandomb (bs, rands, 32);
Packit 5c3484
	  mpz_rrandomb (q, rands, 1 + mpz_get_ui (bs) % MAX_QBITS);
Packit 5c3484
Packit 5c3484
	  /* Multiply by (q, 1; 1,0) from the right */
Packit 5c3484
	  for (i = 0; i < 2; i++)
Packit 5c3484
	    {
Packit 5c3484
	      mp_bitcnt_t size;
Packit 5c3484
	      mpz_swap (M[i][0], M[i][1]);
Packit 5c3484
	      mpz_addmul (M[i][0], M[i][1], q);
Packit 5c3484
	      size = mpz_sizeinbase (M[i][0], 2);
Packit 5c3484
	      if (size > msize)
Packit 5c3484
		msize = size;
Packit 5c3484
	    }
Packit 5c3484
	}
Packit 5c3484
      mpz_gcdext (g, s, t, M[0][0], M[0][1]);
Packit 5c3484
      ASSERT_ALWAYS (mpz_cmp_ui (g, 1) == 0);
Packit 5c3484
Packit 5c3484
      /* Solve n = M[0][0] * x + M[0][1] * y */
Packit 5c3484
      if (mpz_sgn (s) > 0)
Packit 5c3484
	{
Packit 5c3484
	  mpz_mul (x, n, s);
Packit 5c3484
	  mpz_fdiv_qr (q, x, x, M[0][1]);
Packit 5c3484
	  mpz_mul (y, q, M[0][0]);
Packit 5c3484
	  mpz_addmul (y, t, n);
Packit 5c3484
	  ASSERT_ALWAYS (mpz_sgn (y) > 0);
Packit 5c3484
	}
Packit 5c3484
      else
Packit 5c3484
	{
Packit 5c3484
	  mpz_mul (y, n, t);
Packit 5c3484
	  mpz_fdiv_qr (q, y, y, M[0][0]);
Packit 5c3484
	  mpz_mul (x, q, M[0][1]);
Packit 5c3484
	  mpz_addmul (x, s, n);
Packit 5c3484
	  ASSERT_ALWAYS (mpz_sgn (x) > 0);
Packit 5c3484
	}
Packit 5c3484
      mpz_mul (x, x, M[1][0]);
Packit 5c3484
      mpz_addmul (x, y, M[1][1]);
Packit 5c3484
Packit 5c3484
      /* Now (x|n) has the selected large quotients */
Packit 5c3484
      answer = refmpz_legendre (x, p);
Packit 5c3484
      try_zi_zi (x, n, answer);
Packit 5c3484
    }
Packit 5c3484
  mpz_clear (p);
Packit 5c3484
  mpz_clear (n);
Packit 5c3484
  mpz_clear (q);
Packit 5c3484
  mpz_clear (g);
Packit 5c3484
  mpz_clear (s);
Packit 5c3484
  mpz_clear (t);
Packit 5c3484
  mpz_clear (x);
Packit 5c3484
  mpz_clear (y);
Packit 5c3484
  mpz_clear (bs);
Packit 5c3484
  mpz_clear (M[0][0]);
Packit 5c3484
  mpz_clear (M[0][1]);
Packit 5c3484
  mpz_clear (M[1][0]);
Packit 5c3484
  mpz_clear (M[1][1]);
Packit 5c3484
#undef COUNT
Packit 5c3484
#undef PBITS
Packit 5c3484
#undef PPOWER
Packit 5c3484
#undef MAX_QBITS
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
int
Packit 5c3484
main (int argc, char *argv[])
Packit 5c3484
{
Packit 5c3484
  tests_start ();
Packit 5c3484
Packit 5c3484
  if (argc >= 2 && strcmp (argv[1], "-p") == 0)
Packit 5c3484
    {
Packit 5c3484
      option_pari = 1;
Packit 5c3484
Packit 5c3484
      printf ("\
Packit 5c3484
try(a,b,answer) =\n\
Packit 5c3484
{\n\
Packit 5c3484
  if (kronecker(a,b) != answer,\n\
Packit 5c3484
    print(\"wrong at \", a, \",\", b,\n\
Packit 5c3484
      \" expected \", answer,\n\
Packit 5c3484
      \" pari says \", kronecker(a,b)))\n\
Packit 5c3484
}\n");
Packit 5c3484
    }
Packit 5c3484
Packit 5c3484
  check_data ();
Packit 5c3484
  check_squares_zi ();
Packit 5c3484
  check_a_zero ();
Packit 5c3484
  check_jacobi_factored ();
Packit 5c3484
  check_large_quotients ();
Packit 5c3484
  tests_end ();
Packit 5c3484
  exit (0);
Packit 5c3484
}