[BACK]Return to t-jac.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gmp / tests / mpz

Annotation of OpenXM_contrib/gmp/tests/mpz/t-jac.c, Revision 1.1

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>