t-jac.c
上传用户:qaz666999
上传日期:2022-08-06
资源大小:2570k
文件大小:16k
源码类别:

数学计算

开发平台:

Unix_Linux

  1. /* Exercise mpz_*_kronecker_*() and mpz_jacobi() functions.
  2. Copyright 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
  3. This file is part of the GNU MP Library.
  4. The GNU MP Library is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU Lesser General Public License as published by
  6. the Free Software Foundation; either version 3 of the License, or (at your
  7. option) any later version.
  8. The GNU MP Library is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  10. or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
  11. License for more details.
  12. You should have received a copy of the GNU Lesser General Public License
  13. along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.  */
  14. /* With no arguments the various Kronecker/Jacobi symbol routines are
  15.    checked against some test data and a lot of derived data.
  16.    To check the test data against PARI-GP, run
  17.    t-jac -p | gp -q
  18.    It takes a while because the output from "t-jac -p" is big.
  19.    Enhancements:
  20.    More big test cases than those given by check_squares_zi would be good.  */
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include "gmp.h"
  25. #include "gmp-impl.h"
  26. #include "tests.h"
  27. #ifdef _LONG_LONG_LIMB
  28. #define LL(l,ll)  ll
  29. #else
  30. #define LL(l,ll)  l
  31. #endif
  32. int option_pari = 0;
  33. unsigned long
  34. mpz_mod4 (mpz_srcptr z)
  35. {
  36.   mpz_t          m;
  37.   unsigned long  ret;
  38.   mpz_init (m);
  39.   mpz_fdiv_r_2exp (m, z, 2);
  40.   ret = mpz_get_ui (m);
  41.   mpz_clear (m);
  42.   return ret;
  43. }
  44. int
  45. mpz_fits_ulimb_p (mpz_srcptr z)
  46. {
  47.   return (SIZ(z) == 1 || SIZ(z) == 0);
  48. }
  49. mp_limb_t
  50. mpz_get_ulimb (mpz_srcptr z)
  51. {
  52.   if (SIZ(z) == 0)
  53.     return 0;
  54.   else
  55.     return PTR(z)[0];
  56. }
  57. void
  58. try_base (mp_limb_t a, mp_limb_t b, int answer)
  59. {
  60.   int  got;
  61.   if ((b & 1) == 0 || b == 1 || a > b)
  62.     return;
  63.   got = mpn_jacobi_base (a, b, 0);
  64.   if (got != answer)
  65.     {
  66.       printf (LL("mpn_jacobi_base (%lu, %lu) is %d should be %dn",
  67.  "mpn_jacobi_base (%llu, %llu) is %d should be %dn"),
  68.       a, b, got, answer);
  69.       abort ();
  70.     }
  71. }
  72. void
  73. try_zi_ui (mpz_srcptr a, unsigned long b, int answer)
  74. {
  75.   int  got;
  76.   got = mpz_kronecker_ui (a, b);
  77.   if (got != answer)
  78.     {
  79.       printf ("mpz_kronecker_ui (");
  80.       mpz_out_str (stdout, 10, a);
  81.       printf (", %lu) is %d should be %dn", b, got, answer);
  82.       abort ();
  83.     }
  84. }
  85. void
  86. try_zi_si (mpz_srcptr a, long b, int answer)
  87. {
  88.   int  got;
  89.   got = mpz_kronecker_si (a, b);
  90.   if (got != answer)
  91.     {
  92.       printf ("mpz_kronecker_si (");
  93.       mpz_out_str (stdout, 10, a);
  94.       printf (", %ld) is %d should be %dn", b, got, answer);
  95.       abort ();
  96.     }
  97. }
  98. void
  99. try_ui_zi (unsigned long a, mpz_srcptr b, int answer)
  100. {
  101.   int  got;
  102.   got = mpz_ui_kronecker (a, b);
  103.   if (got != answer)
  104.     {
  105.       printf ("mpz_ui_kronecker (%lu, ", a);
  106.       mpz_out_str (stdout, 10, b);
  107.       printf (") is %d should be %dn", got, answer);
  108.       abort ();
  109.     }
  110. }
  111. void
  112. try_si_zi (long a, mpz_srcptr b, int answer)
  113. {
  114.   int  got;
  115.   got = mpz_si_kronecker (a, b);
  116.   if (got != answer)
  117.     {
  118.       printf ("mpz_si_kronecker (%ld, ", a);
  119.       mpz_out_str (stdout, 10, b);
  120.       printf (") is %d should be %dn", got, answer);
  121.       abort ();
  122.     }
  123. }
  124. /* Don't bother checking mpz_jacobi, since it only differs for b even, and
  125.    we don't have an actual expected answer for it.  tests/devel/try.c does
  126.    some checks though.  */
  127. void
  128. try_zi_zi (mpz_srcptr a, mpz_srcptr b, int answer)
  129. {
  130.   int  got;
  131.   got = mpz_kronecker (a, b);
  132.   if (got != answer)
  133.     {
  134.       printf ("mpz_kronecker (");
  135.       mpz_out_str (stdout, 10, a);
  136.       printf (", ");
  137.       mpz_out_str (stdout, 10, b);
  138.       printf (") is %d should be %dn", got, answer);
  139.       abort ();
  140.     }
  141. }
  142. void
  143. try_pari (mpz_srcptr a, mpz_srcptr b, int answer)
  144. {
  145.   printf ("try(");
  146.   mpz_out_str (stdout, 10, a);
  147.   printf (",");
  148.   mpz_out_str (stdout, 10, b);
  149.   printf (",%d)n", answer);
  150. }
  151. void
  152. try_each (mpz_srcptr a, mpz_srcptr b, int answer)
  153. {
  154.   if (option_pari)
  155.     {
  156.       try_pari (a, b, answer);
  157.       return;
  158.     }
  159.   if (mpz_fits_ulimb_p (a) && mpz_fits_ulimb_p (b))
  160.     try_base (mpz_get_ulimb (a), mpz_get_ulimb (b), answer);
  161.   if (mpz_fits_ulong_p (b))
  162.     try_zi_ui (a, mpz_get_ui (b), answer);
  163.   if (mpz_fits_slong_p (b))
  164.     try_zi_si (a, mpz_get_si (b), answer);
  165.   if (mpz_fits_ulong_p (a))
  166.     try_ui_zi (mpz_get_ui (a), b, answer);
  167.   if (mpz_fits_sint_p (a))
  168.     try_si_zi (mpz_get_si (a), b, answer);
  169.   try_zi_zi (a, b, answer);
  170. }
  171. /* Try (a/b) and (a/-b). */
  172. void
  173. try_pn (mpz_srcptr a, mpz_srcptr b_orig, int answer)
  174. {
  175.   mpz_t  b;
  176.   mpz_init_set (b, b_orig);
  177.   try_each (a, b, answer);
  178.   mpz_neg (b, b);
  179.   if (mpz_sgn (a) < 0)
  180.     answer = -answer;
  181.   try_each (a, b, answer);
  182.   mpz_clear (b);
  183. }
  184. /* Try (a+k*p/b) for various k, using the fact (a/b) is periodic in a with
  185.    period p.  For b>0, p=b if b!=2mod4 or p=4*b if b==2mod4. */
  186. void
  187. try_periodic_num (mpz_srcptr a_orig, mpz_srcptr b, int answer)
  188. {
  189.   mpz_t  a, a_period;
  190.   int    i;
  191.   if (mpz_sgn (b) <= 0)
  192.     return;
  193.   mpz_init_set (a, a_orig);
  194.   mpz_init_set (a_period, b);
  195.   if (mpz_mod4 (b) == 2)
  196.     mpz_mul_ui (a_period, a_period, 4);
  197.   /* don't bother with these tests if they're only going to produce
  198.      even/even */
  199.   if (mpz_even_p (a) && mpz_even_p (b) && mpz_even_p (a_period))
  200.     goto done;
  201.   for (i = 0; i < 6; i++)
  202.     {
  203.       mpz_add (a, a, a_period);
  204.       try_pn (a, b, answer);
  205.     }
  206.   mpz_set (a, a_orig);
  207.   for (i = 0; i < 6; i++)
  208.     {
  209.       mpz_sub (a, a, a_period);
  210.       try_pn (a, b, answer);
  211.     }
  212.  done:
  213.   mpz_clear (a);
  214.   mpz_clear (a_period);
  215. }
  216. /* Try (a/b+k*p) for various k, using the fact (a/b) is periodic in b of
  217.    period p.
  218.        period p
  219.    a==0,1mod4             a
  220.    a==2mod4              4*a
  221.    a==3mod4 and b odd    4*a
  222.    a==3mod4 and b even   8*a
  223.    In Henri Cohen's book the period is given as 4*a for all a==2,3mod4, but
  224.    a counterexample would seem to be (3/2)=-1 which with (3/14)=+1 doesn't
  225.    have period 4*a (but rather 8*a with (3/26)=-1).  Maybe the plain 4*a is
  226.    to be read as applying to a plain Jacobi symbol with b odd, rather than
  227.    the Kronecker extension to b even. */
  228. void
  229. try_periodic_den (mpz_srcptr a, mpz_srcptr b_orig, int answer)
  230. {
  231.   mpz_t  b, b_period;
  232.   int    i;
  233.   if (mpz_sgn (a) == 0 || mpz_sgn (b_orig) == 0)
  234.     return;
  235.   mpz_init_set (b, b_orig);
  236.   mpz_init_set (b_period, a);
  237.   if (mpz_mod4 (a) == 3 && mpz_even_p (b))
  238.     mpz_mul_ui (b_period, b_period, 8L);
  239.   else if (mpz_mod4 (a) >= 2)
  240.     mpz_mul_ui (b_period, b_period, 4L);
  241.   /* don't bother with these tests if they're only going to produce
  242.      even/even */
  243.   if (mpz_even_p (a) && mpz_even_p (b) && mpz_even_p (b_period))
  244.     goto done;
  245.   for (i = 0; i < 6; i++)
  246.     {
  247.       mpz_add (b, b, b_period);
  248.       try_pn (a, b, answer);
  249.     }
  250.   mpz_set (b, b_orig);
  251.   for (i = 0; i < 6; i++)
  252.     {
  253.       mpz_sub (b, b, b_period);
  254.       try_pn (a, b, answer);
  255.     }
  256.  done:
  257.   mpz_clear (b);
  258.   mpz_clear (b_period);
  259. }
  260. static const unsigned long  ktable[] = {
  261.   0, 1, 2, 3, 4, 5, 6, 7,
  262.   GMP_NUMB_BITS-1, GMP_NUMB_BITS, GMP_NUMB_BITS+1,
  263.   2*GMP_NUMB_BITS-1, 2*GMP_NUMB_BITS, 2*GMP_NUMB_BITS+1,
  264.   3*GMP_NUMB_BITS-1, 3*GMP_NUMB_BITS, 3*GMP_NUMB_BITS+1
  265. };
  266. /* Try (a/b*2^k) for various k. */
  267. void
  268. try_2den (mpz_srcptr a, mpz_srcptr b_orig, int answer)
  269. {
  270.   mpz_t  b;
  271.   int    kindex;
  272.   int    answer_a2, answer_k;
  273.   unsigned long k;
  274.   /* don't bother when b==0 */
  275.   if (mpz_sgn (b_orig) == 0)
  276.     return;
  277.   mpz_init_set (b, b_orig);
  278.   /* (a/2) is 0 if a even, 1 if a==1 or 7 mod 8, -1 if a==3 or 5 mod 8 */
  279.   answer_a2 = (mpz_even_p (a) ? 0
  280.        : (((SIZ(a) >= 0 ? PTR(a)[0] : -PTR(a)[0]) + 2) & 7) < 4 ? 1
  281.        : -1);
  282.   for (kindex = 0; kindex < numberof (ktable); kindex++)
  283.     {
  284.       k = ktable[kindex];
  285.       /* answer_k = answer*(answer_a2^k) */
  286.       answer_k = (answer_a2 == 0 && k != 0 ? 0
  287.   : (k & 1) == 1 && answer_a2 == -1 ? -answer
  288.   : answer);
  289.       mpz_mul_2exp (b, b_orig, k);
  290.       try_pn (a, b, answer_k);
  291.     }
  292.   mpz_clear (b);
  293. }
  294. /* Try (a*2^k/b) for various k.  If it happens mpz_ui_kronecker() gets (2/b)
  295.    wrong it will show up as wrong answers demanded. */
  296. void
  297. try_2num (mpz_srcptr a_orig, mpz_srcptr b, int answer)
  298. {
  299.   mpz_t  a;
  300.   int    kindex;
  301.   int    answer_2b, answer_k;
  302.   unsigned long  k;
  303.   /* don't bother when a==0 */
  304.   if (mpz_sgn (a_orig) == 0)
  305.     return;
  306.   mpz_init (a);
  307.   /* (2/b) is 0 if b even, 1 if b==1 or 7 mod 8, -1 if b==3 or 5 mod 8 */
  308.   answer_2b = (mpz_even_p (b) ? 0
  309.        : (((SIZ(b) >= 0 ? PTR(b)[0] : -PTR(b)[0]) + 2) & 7) < 4 ? 1
  310.        : -1);
  311.   for (kindex = 0; kindex < numberof (ktable); kindex++)
  312.     {
  313.       k = ktable[kindex];
  314.       /* answer_k = answer*(answer_2b^k) */
  315.       answer_k = (answer_2b == 0 && k != 0 ? 0
  316.   : (k & 1) == 1 && answer_2b == -1 ? -answer
  317.   : answer);
  318. mpz_mul_2exp (a, a_orig, k);
  319.       try_pn (a, b, answer_k);
  320.     }
  321.   mpz_clear (a);
  322. }
  323. /* The try_2num() and try_2den() routines don't in turn call
  324.    try_periodic_num() and try_periodic_den() because it hugely increases the
  325.    number of tests performed, without obviously increasing coverage.
  326.    Useful extra derived cases can be added here. */
  327. void
  328. try_all (mpz_t a, mpz_t b, int answer)
  329. {
  330.   try_pn (a, b, answer);
  331.   try_periodic_num (a, b, answer);
  332.   try_periodic_den (a, b, answer);
  333.   try_2num (a, b, answer);
  334.   try_2den (a, b, answer);
  335. }
  336. void
  337. check_data (void)
  338. {
  339.   static const struct {
  340.     const char  *a;
  341.     const char  *b;
  342.     int         answer;
  343.   } data[] = {
  344.     /* Note that the various derived checks in try_all() reduce the cases
  345.        that need to be given here.  */
  346.     /* some zeros */
  347.     {  "0",  "0", 0 },
  348.     {  "0",  "2", 0 },
  349.     {  "0",  "6", 0 },
  350.     {  "5",  "0", 0 },
  351.     { "24", "60", 0 },
  352.     /* (a/1) = 1, any a
  353.        In particular note (0/1)=1 so that (a/b)=(a mod b/b). */
  354.     { "0", "1", 1 },
  355.     { "1", "1", 1 },
  356.     { "2", "1", 1 },
  357.     { "3", "1", 1 },
  358.     { "4", "1", 1 },
  359.     { "5", "1", 1 },
  360.     /* (0/b) = 0, b != 1 */
  361.     { "0",  "3", 0 },
  362.     { "0",  "5", 0 },
  363.     { "0",  "7", 0 },
  364.     { "0",  "9", 0 },
  365.     { "0", "11", 0 },
  366.     { "0", "13", 0 },
  367.     { "0", "15", 0 },
  368.     /* (1/b) = 1 */
  369.     { "1",  "1", 1 },
  370.     { "1",  "3", 1 },
  371.     { "1",  "5", 1 },
  372.     { "1",  "7", 1 },
  373.     { "1",  "9", 1 },
  374.     { "1", "11", 1 },
  375.     /* (-1/b) = (-1)^((b-1)/2) which is -1 for b==3 mod 4 */
  376.     { "-1",  "1",  1 },
  377.     { "-1",  "3", -1 },
  378.     { "-1",  "5",  1 },
  379.     { "-1",  "7", -1 },
  380.     { "-1",  "9",  1 },
  381.     { "-1", "11", -1 },
  382.     { "-1", "13",  1 },
  383.     { "-1", "15", -1 },
  384.     { "-1", "17",  1 },
  385.     { "-1", "19", -1 },
  386.     /* (2/b) = (-1)^((b^2-1)/8) which is -1 for b==3,5 mod 8.
  387.        try_2num() will exercise multiple powers of 2 in the numerator.  */
  388.     { "2",  "1",  1 },
  389.     { "2",  "3", -1 },
  390.     { "2",  "5", -1 },
  391.     { "2",  "7",  1 },
  392.     { "2",  "9",  1 },
  393.     { "2", "11", -1 },
  394.     { "2", "13", -1 },
  395.     { "2", "15",  1 },
  396.     { "2", "17",  1 },
  397.     /* (-2/b) = (-1)^((b^2-1)/8)*(-1)^((b-1)/2) which is -1 for b==5,7mod8.
  398.        try_2num() will exercise multiple powers of 2 in the numerator, which
  399.        will test that the shift in mpz_si_kronecker() uses unsigned not
  400.        signed.  */
  401.     { "-2",  "1",  1 },
  402.     { "-2",  "3",  1 },
  403.     { "-2",  "5", -1 },
  404.     { "-2",  "7", -1 },
  405.     { "-2",  "9",  1 },
  406.     { "-2", "11",  1 },
  407.     { "-2", "13", -1 },
  408.     { "-2", "15", -1 },
  409.     { "-2", "17",  1 },
  410.     /* (a/2)=(2/a).
  411.        try_2den() will exercise multiple powers of 2 in the denominator. */
  412.     {  "3",  "2", -1 },
  413.     {  "5",  "2", -1 },
  414.     {  "7",  "2",  1 },
  415.     {  "9",  "2",  1 },
  416.     {  "11", "2", -1 },
  417.     /* Harriet Griffin, "Elementary Theory of Numbers", page 155, various
  418.        examples.  */
  419.     {   "2", "135",  1 },
  420.     { "135",  "19", -1 },
  421.     {   "2",  "19", -1 },
  422.     {  "19", "135",  1 },
  423.     { "173", "135",  1 },
  424.     {  "38", "135",  1 },
  425.     { "135", "173",  1 },
  426.     { "173",   "5", -1 },
  427.     {   "3",   "5", -1 },
  428.     {   "5", "173", -1 },
  429.     { "173",   "3", -1 },
  430.     {   "2",   "3", -1 },
  431.     {   "3", "173", -1 },
  432.     { "253",  "21",  1 },
  433.     {   "1",  "21",  1 },
  434.     {  "21", "253",  1 },
  435.     {  "21",  "11", -1 },
  436.     {  "-1",  "11", -1 },
  437.     /* Griffin page 147 */
  438.     {  "-1",  "17",  1 },
  439.     {   "2",  "17",  1 },
  440.     {  "-2",  "17",  1 },
  441.     {  "-1",  "89",  1 },
  442.     {   "2",  "89",  1 },
  443.     /* Griffin page 148 */
  444.     {  "89",  "11",  1 },
  445.     {   "1",  "11",  1 },
  446.     {  "89",   "3", -1 },
  447.     {   "2",   "3", -1 },
  448.     {   "3",  "89", -1 },
  449.     {  "11",  "89",  1 },
  450.     {  "33",  "89", -1 },
  451.     /* H. Davenport, "The Higher Arithmetic", page 65, the quadratic
  452.        residues and non-residues mod 19.  */
  453.     {  "1", "19",  1 },
  454.     {  "4", "19",  1 },
  455.     {  "5", "19",  1 },
  456.     {  "6", "19",  1 },
  457.     {  "7", "19",  1 },
  458.     {  "9", "19",  1 },
  459.     { "11", "19",  1 },
  460.     { "16", "19",  1 },
  461.     { "17", "19",  1 },
  462.     {  "2", "19", -1 },
  463.     {  "3", "19", -1 },
  464.     {  "8", "19", -1 },
  465.     { "10", "19", -1 },
  466.     { "12", "19", -1 },
  467.     { "13", "19", -1 },
  468.     { "14", "19", -1 },
  469.     { "15", "19", -1 },
  470.     { "18", "19", -1 },
  471.     /* Residues and non-residues mod 13 */
  472.     {  "0",  "13",  0 },
  473.     {  "1",  "13",  1 },
  474.     {  "2",  "13", -1 },
  475.     {  "3",  "13",  1 },
  476.     {  "4",  "13",  1 },
  477.     {  "5",  "13", -1 },
  478.     {  "6",  "13", -1 },
  479.     {  "7",  "13", -1 },
  480.     {  "8",  "13", -1 },
  481.     {  "9",  "13",  1 },
  482.     { "10",  "13",  1 },
  483.     { "11",  "13", -1 },
  484.     { "12",  "13",  1 },
  485.     /* various */
  486.     {  "5",   "7", -1 },
  487.     { "15",  "17",  1 },
  488.     { "67",  "89",  1 },
  489.     /* special values inducing a==b==1 at the end of jac_or_kron() */
  490.     { "0x10000000000000000000000000000000000000000000000001",
  491.       "0x10000000000000000000000000000000000000000000000003", 1 },
  492.   };
  493.   int    i;
  494.   mpz_t  a, b;
  495.   mpz_init (a);
  496.   mpz_init (b);
  497.   for (i = 0; i < numberof (data); i++)
  498.     {
  499.       mpz_set_str_or_abort (a, data[i].a, 0);
  500.       mpz_set_str_or_abort (b, data[i].b, 0);
  501.       try_all (a, b, data[i].answer);
  502.     }
  503.   mpz_clear (a);
  504.   mpz_clear (b);
  505. }
  506. /* (a^2/b)=1 if gcd(a,b)=1, or (a^2/b)=0 if gcd(a,b)!=1.
  507.    This includes when a=0 or b=0. */
  508. void
  509. check_squares_zi (void)
  510. {
  511.   gmp_randstate_ptr rands = RANDS;
  512.   mpz_t  a, b, g;
  513.   int    i, answer;
  514.   mp_size_t size_range, an, bn;
  515.   mpz_t bs;
  516.   mpz_init (bs);
  517.   mpz_init (a);
  518.   mpz_init (b);
  519.   mpz_init (g);
  520.   for (i = 0; i < 50; i++)
  521.     {
  522.       mpz_urandomb (bs, rands, 32);
  523.       size_range = mpz_get_ui (bs) % 10 + 2;
  524.       mpz_urandomb (bs, rands, size_range);
  525.       an = mpz_get_ui (bs);
  526.       mpz_rrandomb (a, rands, an);
  527.       mpz_urandomb (bs, rands, size_range);
  528.       bn = mpz_get_ui (bs);
  529.       mpz_rrandomb (b, rands, bn);
  530.       mpz_gcd (g, a, b);
  531.       if (mpz_cmp_ui (g, 1L) == 0)
  532. answer = 1;
  533.       else
  534. answer = 0;
  535.       mpz_mul (a, a, a);
  536.       try_all (a, b, answer);
  537.     }
  538.   mpz_clear (bs);
  539.   mpz_clear (a);
  540.   mpz_clear (b);
  541.   mpz_clear (g);
  542. }
  543. /* Check the handling of asize==0, make sure it isn't affected by the low
  544.    limb. */
  545. void
  546. check_a_zero (void)
  547. {
  548.   mpz_t  a, b;
  549.   mpz_init_set_ui (a, 0);
  550.   mpz_init (b);
  551.   mpz_set_ui (b, 1L);
  552.   PTR(a)[0] = 0;
  553.   try_all (a, b, 1);   /* (0/1)=1 */
  554.   PTR(a)[0] = 1;
  555.   try_all (a, b, 1);   /* (0/1)=1 */
  556.   mpz_set_si (b, -1L);
  557.   PTR(a)[0] = 0;
  558.   try_all (a, b, 1);   /* (0/-1)=1 */
  559.   PTR(a)[0] = 1;
  560.   try_all (a, b, 1);   /* (0/-1)=1 */
  561.   mpz_set_ui (b, 0);
  562.   PTR(a)[0] = 0;
  563.   try_all (a, b, 0);   /* (0/0)=0 */
  564.   PTR(a)[0] = 1;
  565.   try_all (a, b, 0);   /* (0/0)=0 */
  566.   mpz_set_ui (b, 2);
  567.   PTR(a)[0] = 0;
  568.   try_all (a, b, 0);   /* (0/2)=0 */
  569.   PTR(a)[0] = 1;
  570.   try_all (a, b, 0);   /* (0/2)=0 */
  571.   mpz_clear (a);
  572.   mpz_clear (b);
  573. }
  574. int
  575. main (int argc, char *argv[])
  576. {
  577.   tests_start ();
  578.   if (argc >= 2 && strcmp (argv[1], "-p") == 0)
  579.     {
  580.       option_pari = 1;
  581.       printf ("
  582. try(a,b,answer) =n
  583. {n
  584.   if (kronecker(a,b) != answer,n
  585.     print("wrong at ", a, ",", b,n
  586.       " expected ", answer,n
  587.       " pari says ", kronecker(a,b)))n
  588. }n");
  589.     }
  590.   check_data ();
  591.   check_squares_zi ();
  592.   check_a_zero ();
  593.   tests_end ();
  594.   exit (0);
  595. }