[BACK]Return to arith2.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / pari / src / basemath

Annotation of OpenXM_contrib/pari/src/basemath/arith2.c, Revision 1.1

1.1     ! maekawa     1: /*********************************************************************/
        !             2: /**                                                                 **/
        !             3: /**                     ARITHMETIC FUNCTIONS                        **/
        !             4: /**                        (second part)                            **/
        !             5: /**                                                                 **/
        !             6: /*********************************************************************/
        !             7: /* $Id: arith2.c,v 1.1.1.1 1999/09/16 13:47:17 karim Exp $ */
        !             8: #include "pari.h"
        !             9:
        !            10: GEN arith_proto(long f(GEN), GEN x, int do_error);
        !            11: GEN garith_proto(GEN f(GEN), GEN x, int do_error);
        !            12: GEN garith_proto2gs(GEN f(GEN,long), GEN x, long y);
        !            13: static long court_p[]={evaltyp(t_INT)|m_evallg(3),evalsigne(1)|evallgefint(3),0};
        !            14:
        !            15: /***********************************************************************/
        !            16: /**                                                                   **/
        !            17: /**                          PRIME NUMBERS                            **/
        !            18: /**                                                                   **/
        !            19: /***********************************************************************/
        !            20:
        !            21: GEN
        !            22: prime(long n)
        !            23: {
        !            24:   byteptr p = diffptr;
        !            25:   long c, prime = 0;
        !            26:
        !            27:   while (n--)
        !            28:   {
        !            29:     c = *p++; if (!c) err(primer1);
        !            30:     prime += c;
        !            31:   }
        !            32:   return stoi(prime);
        !            33: }
        !            34:
        !            35: GEN
        !            36: primes(long n)
        !            37: {
        !            38:   byteptr p = diffptr;
        !            39:   long c, prime = 0;
        !            40:   GEN y,z;
        !            41:
        !            42:   z = y = cgetg(n+1,t_VEC);
        !            43:   while (n--)
        !            44:   {
        !            45:     c = *p++; if (!c) err(primer1);
        !            46:     prime += c; *++z = lstoi(prime);
        !            47:   }
        !            48:   return y;
        !            49: }
        !            50:
        !            51: /* Building/Rebuilding the diffptr table. Incorporates Ilya Zakharevich's
        !            52:  * block sweep algorithm  (see pari-dev-111, 25 April 1998).  The actual work
        !            53:  * is done by the following two subroutines;  the user entry point is the
        !            54:  * function initprimes() below.  initprimes1() is the old algorithm, called
        !            55:  * when maxnum (size) is moderate.
        !            56:  */
        !            57: static byteptr
        !            58: initprimes1(long size, long *lenp, long *lastp)
        !            59: {
        !            60:   long k;
        !            61:   byteptr q,r,s,fin, p = (byteptr) gpmalloc(size+2);
        !            62:
        !            63:   memset(p, 0, size + 2); fin = p + size;
        !            64:   for (r=q=p,k=1; r<=fin; )
        !            65:   {
        !            66:     do { r+=k; k+=2; r+=k; } while (*++q);
        !            67:     for (s=r; s<=fin; s+=k) *s=1;
        !            68:   }
        !            69:   r=p; *r++=2; *r++=1; /* 2 and 3 */
        !            70:   for (s=q=r-1; ; s=q)
        !            71:   {
        !            72:     do q++; while (*q);
        !            73:     if (q>fin) break;
        !            74:     *r++ = (q-s) << 1;
        !            75:   }
        !            76:   *r++=0;
        !            77:   *lenp = r - p;
        !            78:   *lastp = ((s - p) << 1) + 1;
        !            79: #if 0
        !            80:   fprintferr("initprimes1: q = %ld, len = %ld, last = %ld\n",
        !            81:             q, *lenp, *lastp);
        !            82: #endif
        !            83:   return (byteptr) gprealloc(p,r-p,size + 2);
        !            84: }
        !            85:
        !            86: #define PRIME_ARENA (512 * 1024)
        !            87:
        !            88: /* Here's the workhorse.  This is recursive, although normally the first
        !            89:    recursive call will bottom out and invoke initprimes1() at once.
        !            90:    (Not static;  might conceivably be useful to someone in library mode) */
        !            91: byteptr
        !            92: initprimes0(ulong maxnum, long *lenp, long *lastp)
        !            93: {
        !            94:   long k, size, alloced, asize, psize, rootnum, curlow, last, remains, need;
        !            95:   byteptr q,r,s,fin, p, p1, fin1, plast, curdiff;
        !            96:
        !            97: #if 0
        !            98:   fprintferr("initprimes0: called for maxnum = %lu\n", maxnum);
        !            99: #endif
        !           100:   if (maxnum <= 1ul<<17)       /* Arbitrary. */
        !           101:     return initprimes1(maxnum>>1, lenp, lastp);
        !           102:
        !           103:   maxnum |= 1;                 /* make it odd. */
        !           104:
        !           105:   /* Checked to be enough up to 40e6, attained at 155893 */
        !           106:   size = (long) (1.09 * maxnum/log((double)maxnum)) + 145;
        !           107:   p1 = (byteptr) gpmalloc(size);
        !           108:   rootnum = (long) sqrt((double)maxnum); /* cast it back to a long */
        !           109:   rootnum |= 1;
        !           110: #if 0
        !           111:   fprintferr("initprimes0: rootnum = %ld\n", rootnum);
        !           112: #endif
        !           113:   {
        !           114:     byteptr p2 = initprimes0(rootnum, &psize, &last); /* recursive call */
        !           115:     memcpy(p1, p2, psize); free(p2);
        !           116:   }
        !           117:   fin1 = p1 + psize - 1;
        !           118:   remains = (maxnum - rootnum) >> 1; /* number of odd numbers to check */
        !           119:
        !           120:   need = 100 * rootnum;                /* Make % overhead negligeable. */
        !           121:   if (need < PRIME_ARENA) need = PRIME_ARENA;
        !           122:   if (avma - bot < need>>1) {  /* need to do our own allocation */
        !           123:     alloced = 1; asize = need;
        !           124:   } else {                     /* scratch area is free part of PARI stack */
        !           125:     alloced = 0; asize = avma - bot;
        !           126:   }
        !           127:   if (asize > remains) asize = remains + 1;/* + room for a sentinel byte */
        !           128:   if (alloced)
        !           129:     p = (byteptr) gpmalloc(asize);
        !           130:   else
        !           131:     p = (byteptr) bot;
        !           132:   fin = p + asize - 1;         /* the 0 sentinel goes at fin. */
        !           133:   curlow = rootnum + 2;                /* We know all primes up to rootnum (odd). */
        !           134:   curdiff = fin1;
        !           135:
        !           136:   /* During each iteration p..fin-1 represents a range of odd
        !           137:      numbers.  plast is a pointer which represents the last prime seen,
        !           138:      it may point before p..fin-1. */
        !           139:   plast = p - ((rootnum - last) >> 1) - 1;
        !           140:   while (remains)
        !           141:   {
        !           142:     if (asize > remains)
        !           143:     {
        !           144:       asize = remains + 1;
        !           145:       fin = p + asize - 1;
        !           146:     }
        !           147:     memset(p, 0, asize);
        !           148:     /* p corresponds to curlow.  q runs over primediffs.  */
        !           149:     for (q = p1+2, k = 3; q <= fin1; k += *q++)
        !           150:     {
        !           151:       /* The first odd number which is >= curlow and divisible by p
        !           152:        equals (if curlow > p)
        !           153:         the last odd number which is <= curlow + 2p - 1 and 0 (mod p)
        !           154:        which equals
        !           155:         p + the last even number which is <= curlow + p - 1 and 0 (mod p)
        !           156:        which equals
        !           157:         p + the last even number which is <= curlow + p - 2 and 0 (mod p)
        !           158:        which equals
        !           159:         p + curlow + p - 2 - (curlow + p - 2)) % 2p.
        !           160:        */
        !           161:       long k2 = k*k - curlow;
        !           162:
        !           163:       if (k2 > 0)
        !           164:       {
        !           165:        r = p + (k2 >>= 1);
        !           166:        if (k2 > remains) break; /* Guard against an address wrap. */
        !           167:       } else
        !           168:        r = p - (((curlow+k-2) % (2*k)) >> 1) + k - 1;
        !           169:       for (s = r; s < fin; s += k) *s = 1;
        !           170:     }
        !           171:     /* now q runs over addresses corresponding to primes */
        !           172:     for (q = p; ; plast = q++)
        !           173:     {
        !           174:       while (*q) q++;          /* use 0-sentinel at end */
        !           175:       if (q >= fin) break;
        !           176:       *curdiff++ = (q - plast) << 1;
        !           177:     }
        !           178:     plast -= asize - 1;
        !           179:     remains -= asize - 1;
        !           180:     curlow += ((asize - 1)<<1);
        !           181:   } /* while (remains) */
        !           182:   last = curlow - ((p - plast) << 1);
        !           183:   *curdiff++ = 0;              /* sentinel */
        !           184:   *lenp = curdiff - p1;
        !           185:   *lastp = last;
        !           186:   if (alloced) free(p);
        !           187:   return (byteptr) gprealloc(p1, *lenp, size);
        !           188: }
        !           189: #if 0 /* not yet... GN */
        !           190: /* The diffptr table will contain at least 6548 entries (up to and including
        !           191:    the 6547th prime, 65557, and the terminal null byte), because the isprime/
        !           192:    small-factor-extraction machinery wants to depend on everything up to 65539
        !           193:    being in the table, and we might as well go to a multiple of 4 Bytes.--GN */
        !           194:
        !           195: void
        !           196: init_tinyprimes_tridiv(byteptr p);     /* in ifactor2.c */
        !           197: #endif
        !           198: byteptr
        !           199: initprimes(long maxnum)
        !           200: {
        !           201:   long len, last;
        !           202:   byteptr p;
        !           203:   /* The algorithm must see the next prime beyond maxnum, whence the +257. */
        !           204:   /* switch to unsigned: adding the 257 _could_ wrap to a negative number. */
        !           205:   ulong maxnum1 = ((maxnum<65302?65302:maxnum)+257ul);
        !           206:
        !           207:   if (maxnum1 > 436273000)
        !           208:     err(talker,"impossible to have prestored primes > 436273009");
        !           209:
        !           210:   p = initprimes0(maxnum1, &len, &last);
        !           211: #if 0 /* not yet... GN */
        !           212:   static int build_the_tables = 1;
        !           213:   if (build_the_tables) { init_tinyprimes_tridiv(p); build_the_tables=0; }
        !           214: #endif
        !           215:   return p;
        !           216: }
        !           217:
        !           218: static void
        !           219: cleanprimetab(void)
        !           220: {
        !           221:   long i,j, lp = lg(primetab);
        !           222:
        !           223:   for (i=j=1; i < lp; i++)
        !           224:     if (primetab[i]) primetab[j++] = primetab[i];
        !           225:   setlg(primetab,j);
        !           226: }
        !           227:
        !           228: /* primes is a single element or a row vector with "primes" to add to
        !           229:  * primetab. If the "prime" shares a non-trivial factor with another element
        !           230:  * in primetab, it is taken into account.
        !           231:  */
        !           232: GEN
        !           233: addprimes(GEN prime)
        !           234: {
        !           235:   long i,tx, av = avma, lp = lg(primetab);
        !           236:   GEN p1,p2;
        !           237:
        !           238:   if (!prime) return primetab;
        !           239:   tx = typ(prime);
        !           240:   if (is_vec_t(tx))
        !           241:   {
        !           242:     for (i=1; i < lg(prime); i++) addprimes((GEN) prime[i]);
        !           243:     return primetab;
        !           244:   }
        !           245:   if (tx != t_INT) err(typeer,"addprime");
        !           246:   if (is_pm1(prime)) return primetab;
        !           247:   if (signe(prime) < 0) prime=absi(prime);
        !           248:
        !           249:   p1=cgetg(1,t_VEC);
        !           250:   for (i=1; i < lp; i++)
        !           251:   {
        !           252:     p2 = mppgcd((GEN) primetab[i], prime);
        !           253:     if (! gcmp1(p2))
        !           254:     {
        !           255:       if (!egalii(prime,p2)) p1=concatsp(p1,p2);
        !           256:       p1 = concatsp(p1,divii((GEN)primetab[i],p2));
        !           257:       gunclone((GEN)primetab[i]); primetab[i]=0;
        !           258:     }
        !           259:   }
        !           260:   if (i == NUMPRTBELT+1 && lg(p1) == 1)
        !           261:     err(talker,"extra primetable overflows");
        !           262:   primetab[i] = lclone(prime); setlg(primetab, lp+1);
        !           263:   cleanprimetab();
        !           264:   if (lg(p1) > 1) addprimes(p1);
        !           265:   avma=av; return primetab;
        !           266: }
        !           267:
        !           268: GEN
        !           269: removeprimes(GEN prime)
        !           270: {
        !           271:   long i,tx, av = avma;
        !           272:
        !           273:   if (!prime) return primetab;
        !           274:   tx = typ(prime);
        !           275:   if (is_vec_t(tx))
        !           276:   {
        !           277:     for (i=1; i < lg(prime); i++) removeprimes((GEN) prime[i]);
        !           278:     return primetab;
        !           279:   }
        !           280:   if (tx != t_INT) err(typeer,"removeprimes");
        !           281:   if (is_pm1(prime)) return primetab;
        !           282:   if (signe(prime) < 0) prime=absi(prime);
        !           283:
        !           284:   for (i=1; i < lg(primetab); i++)
        !           285:     if (egalii((GEN) primetab[i], prime))
        !           286:     {
        !           287:       gunclone((GEN)primetab[i]); primetab[i]=0;
        !           288:       cleanprimetab(); avma=av; return primetab;
        !           289:     }
        !           290:   err(talker,"prime is not in primetable in removeprimes");
        !           291:   return NULL; /* not reached */
        !           292: }
        !           293:
        !           294: /***********************************************************************/
        !           295: /**                                                                   **/
        !           296: /**       COMPUTING THE MATRIX OF PRIME DIVISORS AND EXPONENTS        **/
        !           297: /**                                                                   **/
        !           298: /***********************************************************************/
        !           299:
        !           300: /* Configure may/should define this to 1 if MPQS is not installed --GN */
        !           301: #ifndef decomp_default_hint
        !           302: #define decomp_default_hint 0
        !           303: #endif
        !           304:
        !           305: /* Some overkill removed from this  (15 spsp for an integer < 2^32 ?!).
        !           306:    Should really revert to isprime() once the new primality tester is ready
        !           307:    --GN */
        !           308: #define pseudoprime(p) millerrabin(p,3*lgefint(p))
        !           309:
        !           310: /* where to stop trial dividing in factorization */
        !           311:
        !           312: static long
        !           313: tridiv_bound(GEN n, long all)
        !           314: {
        !           315:   long size = expi(n) + 1;
        !           316:   if (all > 1)                 /* bounded factoring */
        !           317:     return all;                        /* use the given limit */
        !           318:   if (all == 0)
        !           319:     return VERYBIGINT;         /* smallfact() case */
        !           320:   if (size <= 32)
        !           321:     return 16384;
        !           322:   else if (size <= 512)
        !           323:     return (size-16) << 10;
        !           324:   return 1L<<19;               /* Rho will generally be faster above this */
        !           325: }
        !           326:
        !           327: /********** about to become obsolete --GN **********/
        !           328: #if 0
        !           329: /* If flag != 1, use the new MPQS code: Try to factor N using ECM if flag = 2
        !           330:  * and N is not too small, followed by MPQS, or just MPQS otherwise.
        !           331:  */
        !           332: static GEN
        !           333: find_fact(GEN N, long *flag)
        !           334: {
        !           335:   GEN f;
        !           336:
        !           337:   if (*flag == 2)
        !           338:   {
        !           339:     if ((f = pollardbrent(N))) /* assignment */
        !           340:       return f;
        !           341:     f = ellfacteur(N, 0);
        !           342:     if (!f)
        !           343:     {
        !           344:       /* *flag = 0; */
        !           345:       f = mpqs(N);
        !           346:     }
        !           347:   }
        !           348:   else if (*flag == 1)
        !           349:   {
        !           350:     if ((f = pollardbrent(N))) /* assignment */
        !           351:       return f;
        !           352:     f = ellfacteur(N, 1);
        !           353:   }
        !           354:   else
        !           355:     f = mpqs(N);               /* may bail out and call ellfacteur(_,1) */
        !           356:                                /* (this is to be changed) */
        !           357:
        !           358:   return f;
        !           359: }
        !           360: #endif
        !           361: /***************************************************/
        !           362:
        !           363: /* function imported from ifactor1.c */
        !           364: long
        !           365: ifac_decomp(GEN n, long hint);
        !           366:
        !           367: static GEN
        !           368: aux_end(GEN n, long nb)
        !           369: {
        !           370:   GEN p,p1,p2, z = (GEN)avma;
        !           371:   long i;
        !           372:
        !           373:   if (n) gunclone(n);
        !           374:   p1=cgetg(nb+1,t_COL);
        !           375:   p2=cgetg(nb+1,t_COL);
        !           376:   for (i=nb; i; i--)
        !           377:   {
        !           378:     p2[i] = (long)z; z += lg(z);
        !           379:     p1[i] = (long)z; z += lg(z);
        !           380:   }
        !           381:   z[1]=(long)p1;
        !           382:   z[2]=(long)p2;
        !           383:   if (nb)
        !           384:   {
        !           385:     long av = avma;
        !           386:     GEN p1old = dummycopy(p1), p2old = dummycopy(p2);
        !           387:     p=sindexsort(p1);
        !           388:     for (i=1;i<=nb; i++)
        !           389:     {
        !           390:       p1[i]=p1old[p[i]];
        !           391:       p2[i]=p2old[p[i]];
        !           392:     }
        !           393:     avma = av;
        !           394:   }
        !           395:   return z;
        !           396: }
        !           397:
        !           398: static GEN
        !           399: auxdecomp0(GEN n, long all, long hint)
        !           400: {
        !           401:   long pp[] = { evaltyp(t_INT)|m_evallg(3), evalsigne(1)|evallgefint(3),2,0 };
        !           402:   long nb = 0,i,k,lim1,av,lp;
        !           403:   byteptr d=diffptr+1;
        !           404:
        !           405:   if (typ(n) != t_INT) err(arither1);
        !           406:   i=signe(n); if (!i) err(arither2);
        !           407:   cgetg(3,t_MAT);
        !           408:   if (i<0) { stoi(-1); stoi(1); nb++; }
        !           409:   if (is_pm1(n)) return aux_end(NULL,nb);
        !           410:
        !           411:   n = gclone(n);  setsigne(n,1);
        !           412:   i = vali(n);
        !           413:   if (i)
        !           414:   {
        !           415:     stoi(2); stoi(i); nb++;
        !           416:     av=avma; affii(shifti(n,-i), n); avma=av;
        !           417:   }
        !           418:   if (is_pm1(n)) return aux_end(n,nb);
        !           419:   lim1 = tridiv_bound(n, all);
        !           420:
        !           421:   /* trial division */
        !           422:   while (*d && pp[2] <= lim1)
        !           423:   {
        !           424:     pp[2] += *d++;
        !           425:     if (mpdivis(n,pp,n))
        !           426:     {
        !           427:       nb++; k=1; while (mpdivis(n,pp,n)) k++;
        !           428:       icopy(pp); stoi(k);
        !           429:       if (is_pm1(n)) return aux_end(n,nb);
        !           430:     }
        !           431:   }
        !           432:
        !           433:   /* pp = square of biggest p tried so far */
        !           434:   av=avma; setlg(pp,4); affii(sqri(pp),pp); avma=av;
        !           435:   if (cmpii(pp,n) > 0 || pseudoprime(n))
        !           436:   {
        !           437:     nb++;
        !           438:     icopy(n); stoi(1); return aux_end(n,nb);
        !           439:   }
        !           440:
        !           441:   lp = lg(primetab); k=0;
        !           442:   for (i=1; i<lp; i++)
        !           443:     if (mpdivis(n,(GEN) primetab[i],n))
        !           444:     {
        !           445:       nb++; k=1; while (mpdivis(n,(GEN) primetab[i],n)) k++;
        !           446:       icopy((GEN) primetab[i]); stoi(k);
        !           447:       if (is_pm1(n)) return aux_end(n,nb);
        !           448:     }
        !           449:
        !           450:   /* test primality again, _if_ primetab made a difference  */
        !           451:   if(k && (cmpii(pp,n) > 0 || pseudoprime(n)))
        !           452:   {
        !           453:     nb++;
        !           454:     icopy(n); stoi(1); return aux_end(n,nb);
        !           455:   }
        !           456:
        !           457:   /* now we have a large composite.  Use hint as is if all==1 */
        !           458:   if (all!=1) hint = 15; /* turn off everything except pure powers */
        !           459:   nb += ifac_decomp(n, hint);
        !           460:
        !           461:   return aux_end(n, nb);
        !           462: }
        !           463:
        !           464: GEN
        !           465: auxdecomp(GEN n, long all)
        !           466: {
        !           467:   return auxdecomp0(n,all,decomp_default_hint);
        !           468: }
        !           469:
        !           470: /* see before ifac_crack() in ifactor1.c for current semantics of `hint'
        !           471:    (factorint's `flag') */
        !           472: GEN
        !           473: factorint(GEN n, long flag)
        !           474: {
        !           475:   return auxdecomp0(n,1,flag);
        !           476: }
        !           477:
        !           478: GEN
        !           479: decomp(GEN n)
        !           480: {
        !           481:   return auxdecomp0(n,1,decomp_default_hint);
        !           482: }
        !           483:
        !           484: GEN
        !           485: smallfact(GEN n)
        !           486: {
        !           487:   return boundfact(n,0);
        !           488: }
        !           489:
        !           490: GEN
        !           491: gboundfact(GEN n, long lim)
        !           492: {
        !           493:   return garith_proto2gs(boundfact,n,lim);
        !           494: }
        !           495:
        !           496: GEN
        !           497: boundfact(GEN n, long lim)
        !           498: {
        !           499:   GEN p1,p2,p3,p4,p5,y;
        !           500:   long av,tetpil;
        !           501:
        !           502:   if (lim<=1) lim=0;
        !           503:   switch(typ(n))
        !           504:   {
        !           505:     case t_INT:
        !           506:       return auxdecomp(n,lim);
        !           507:     case t_FRACN:
        !           508:       av=avma; n=gred(n); /* fall through */
        !           509:     case t_FRAC:
        !           510:       if (typ(n)==t_FRAC) av=avma;
        !           511:       p1=auxdecomp((GEN)n[1],lim);
        !           512:       p2=auxdecomp((GEN)n[2],lim);
        !           513:       p4=concatsp((GEN)p1[1],(GEN)p2[1]);
        !           514:       p5=concatsp((GEN)p1[2],gneg((GEN)p2[2]));
        !           515:       p3=indexsort(p4);
        !           516:
        !           517:       tetpil=avma; y=cgetg(3,t_MAT);
        !           518:       y[1]=(long)extract(p4,p3);
        !           519:       y[2]=(long)extract(p5,p3);
        !           520:       return gerepile(av,tetpil,y);
        !           521:   }
        !           522:   err(arither1);
        !           523:   return NULL; /* not reached */
        !           524: }
        !           525:
        !           526: /***********************************************************************/
        !           527: /**                                                                   **/
        !           528: /**                    BASIC ARITHMETIC FUNCTIONS                     **/
        !           529: /**                                                                   **/
        !           530: /***********************************************************************/
        !           531:
        !           532: /* functions imported from ifactor1.c */
        !           533: long
        !           534: ifac_moebius(GEN n, long hint);
        !           535:
        !           536: long
        !           537: ifac_issquarefree(GEN n, long hint);
        !           538:
        !           539: long
        !           540: ifac_omega(GEN n, long hint);
        !           541:
        !           542: long
        !           543: ifac_bigomega(GEN n, long hint);
        !           544:
        !           545: GEN
        !           546: ifac_totient(GEN n, long hint);
        !           547:
        !           548: GEN
        !           549: ifac_numdiv(GEN n, long hint);
        !           550:
        !           551: GEN
        !           552: ifac_sumdiv(GEN n, long hint);
        !           553:
        !           554: GEN
        !           555: ifac_sumdivk(GEN n, long k, long hint);
        !           556:
        !           557: GEN
        !           558: gmu(GEN n)
        !           559: {
        !           560:   return arith_proto(mu,n,1);
        !           561: }
        !           562:
        !           563: long
        !           564: mu(GEN n)
        !           565: {
        !           566:   byteptr d = diffptr+1;       /* point at 3 - 2 */
        !           567:   GEN p;
        !           568:   long av = avma, lim1, s, v;
        !           569:
        !           570:   if (typ(n) != t_INT) err(arither1);
        !           571:   if (!signe(n)) err(arither2);
        !           572:   if (is_pm1(n)) return 1;
        !           573:   v = vali(n);
        !           574:   if (v>1) return 0;
        !           575:   s = v ? -1 : 1;
        !           576:   n=absi(shifti(n,-v)); p=court_p; p[2]=2;
        !           577:   if (is_pm1(n)) return s;
        !           578:   lim1 = tridiv_bound(n,1);
        !           579:
        !           580:   while (*d && p[2] < lim1)
        !           581:   {
        !           582:     p[2] += *d++;
        !           583:     if (mpdivis(n,p,n))
        !           584:     {
        !           585:       if (divise(n,p)) { avma=av; return 0; }
        !           586:       s = -s; if (is_pm1(n)) { avma=av; return s; }
        !           587:     }
        !           588:   }
        !           589:   /* we normally get here with p==nextprime(PRE_TUNE), which will already
        !           590:      have been tested against n, so p^2 >= n  (instead of p^2 > n)  is
        !           591:      enough to guarantee n is prime */
        !           592:   if (cmpii(sqri(p),n) >= 0 || pseudoprime(n)) { avma=av; return -s; }
        !           593:   /* large composite without small factors */
        !           594:   v = ifac_moebius(n, decomp_default_hint);
        !           595:   avma=av;
        !           596:   return (s<0 ? -v : v);       /* correct also if v==0 */
        !           597: }
        !           598:
        !           599: GEN
        !           600: gissquarefree(GEN x)
        !           601: {
        !           602:   return arith_proto(issquarefree,x,0);
        !           603: }
        !           604:
        !           605: long
        !           606: issquarefree(GEN x)
        !           607: {
        !           608:   long av=avma,lim1,tx;
        !           609:   GEN p;
        !           610:
        !           611:   if (gcmp0(x)) return 0;
        !           612:   tx=typ(x);
        !           613:   if (tx == t_INT)
        !           614:   {
        !           615:     long v;
        !           616:     byteptr d=diffptr+1;
        !           617:     if (is_pm1(x)) return 1;
        !           618:     if((v = vali(x)) > 1) return 0;
        !           619:     x=absi(shifti(x,-v)); p=court_p; p[2]=2;
        !           620:     if (is_pm1(x)) return 1;
        !           621:     lim1 = tridiv_bound(x,1);
        !           622:
        !           623:     while (*d && p[2] < lim1)
        !           624:     {
        !           625:       p[2] += *d++;
        !           626:       if (mpdivis(x,p,x))
        !           627:       {
        !           628:        if (divise(x,p)) { avma=av; return 0; }
        !           629:        if (is_pm1(x)) { avma=av; return 1; }
        !           630:       }
        !           631:     }
        !           632:     if (cmpii(sqri(p),x) >= 0 || pseudoprime(x)) { avma=av; return 1; }
        !           633:     v = ifac_issquarefree(x, decomp_default_hint);
        !           634:     avma=av;
        !           635:     return v;
        !           636:   }
        !           637:   if (tx != t_POL) err(typeer,"issquarefree");
        !           638:   p = ggcd(x, derivpol(x));
        !           639:   avma=av; return (lgef(p)==3);
        !           640: }
        !           641:
        !           642: GEN
        !           643: gomega(GEN n)
        !           644: {
        !           645:   return arith_proto(omega,n,1);
        !           646: }
        !           647:
        !           648: long
        !           649: omega(GEN n)
        !           650: {
        !           651:   byteptr d=diffptr+1;
        !           652:   GEN p;
        !           653:   long nb,av=avma,lim1,v;
        !           654:
        !           655:   if (typ(n) != t_INT) err(arither1);
        !           656:   if (!signe(n)) err(arither2);
        !           657:   if (is_pm1(n)) return 0;
        !           658:   v=vali(n);
        !           659:   nb = v ? 1 : 0;
        !           660:   n=absi(shifti(n,-v)); p=court_p; p[2]=2;
        !           661:   if (is_pm1(n)) return nb;
        !           662:   lim1 = tridiv_bound(n,1);
        !           663:
        !           664:   while (*d && p[2] < lim1)
        !           665:   {
        !           666:     p[2] += *d++;
        !           667:     if (mpdivis(n,p,n))
        !           668:     {
        !           669:       nb++; while (mpdivis(n,p,n)); /* empty */
        !           670:       if (is_pm1(n)) { avma = av; return nb; }
        !           671:     }
        !           672:   }
        !           673:   if (cmpii(sqri(p),n) >= 0 || pseudoprime(n)) { avma = av; return nb+1; }
        !           674:   /* large composite without small factors */
        !           675:   nb += ifac_omega(n, decomp_default_hint);
        !           676:   avma=av; return nb;
        !           677: }
        !           678:
        !           679: GEN
        !           680: gbigomega(GEN n)
        !           681: {
        !           682:   return arith_proto(bigomega,n,1);
        !           683: }
        !           684:
        !           685: long
        !           686: bigomega(GEN n)
        !           687: {
        !           688:   byteptr d=diffptr+1;
        !           689:   GEN p;
        !           690:   long nb,av=avma,lim1,v;
        !           691:
        !           692:   if (typ(n) != t_INT) err(arither1);
        !           693:   if (!signe(n)) err(arither2);
        !           694:   if (is_pm1(n)) return 0;
        !           695:   nb=v=vali(n);
        !           696:   n=absi(shifti(n,-v)); p=court_p; p[2]=2;
        !           697:   if (is_pm1(n)) { avma = av; return nb; }
        !           698:   lim1 = tridiv_bound(n,1);
        !           699:
        !           700:   while (*d && p[2] < lim1)
        !           701:   {
        !           702:     p[2] += *d++;
        !           703:     if (mpdivis(n,p,n))
        !           704:     {
        !           705:       do nb++; while (mpdivis(n,p,n));
        !           706:       if (is_pm1(n)) { avma = av; return nb; }
        !           707:     }
        !           708:   }
        !           709:   if (cmpii(sqri(p),n) >= 0 || pseudoprime(n)) { avma = av; return nb+1; }
        !           710:   nb += ifac_bigomega(n, decomp_default_hint);
        !           711:   avma=av; return nb;
        !           712: }
        !           713:
        !           714: GEN
        !           715: gphi(GEN n)
        !           716: {
        !           717:   return garith_proto(phi,n,1);
        !           718: }
        !           719:
        !           720: GEN
        !           721: phi(GEN n)
        !           722: {
        !           723:   byteptr d = diffptr+1;
        !           724:   GEN p,m;
        !           725:   long av = avma, lim1, v;
        !           726:
        !           727:   if (typ(n) != t_INT) err(arither1);
        !           728:   if (!signe(n)) err(arither2);
        !           729:   if (is_pm1(n)) return gun;
        !           730:   v=vali(n);
        !           731:   n=absi(shifti(n,-v)); p=court_p; p[2]=2;
        !           732:   m = (v > 1 ? shifti(gun,v-1) : stoi(1));
        !           733:   if (is_pm1(n)) { return gerepileupto(av,m); }
        !           734:   lim1 = tridiv_bound(n,1);
        !           735:
        !           736:   while (*d && p[2] < lim1)
        !           737:   {
        !           738:     court_p[2] += *d++;
        !           739:     if (mpdivis(n,p,n))
        !           740:     {
        !           741:       m = mulii(m,addsi(-1,p));
        !           742:       while (mpdivis(n,p,n)) m = mulii(m,p);
        !           743:       if (is_pm1(n)) { return gerepileupto(av,m); }
        !           744:     }
        !           745:   }
        !           746:   if (cmpii(sqri(p),n) >= 0 || pseudoprime(n))
        !           747:   {
        !           748:     m = mulii(m,addsi(-1,n));
        !           749:     return gerepileupto(av,m);
        !           750:   }
        !           751:   m = mulii(m, ifac_totient(n, decomp_default_hint));
        !           752:   return gerepileupto(av,m);
        !           753: }
        !           754:
        !           755: GEN
        !           756: gnumbdiv(GEN n)
        !           757: {
        !           758:   return garith_proto(numbdiv,n,1);
        !           759: }
        !           760:
        !           761: GEN
        !           762: numbdiv(GEN n)
        !           763: {
        !           764:   byteptr d=diffptr+1;
        !           765:   GEN p,m;
        !           766:   long l, av=avma, lim1, v;
        !           767:
        !           768:   if (typ(n) != t_INT) err(arither1);
        !           769:   if (!signe(n)) err(arither2);
        !           770:   if (is_pm1(n)) return gun;
        !           771:   v=vali(n);
        !           772:   n=absi(shifti(n,-v)); p=court_p; p[2]=2;
        !           773:   m = stoi(v+1);
        !           774:   if (is_pm1(n)) { return gerepileupto(av,m); }
        !           775:   lim1 = tridiv_bound(n,1);
        !           776:
        !           777:   while (*d && p[2] < lim1)
        !           778:   {
        !           779:     p[2] += *d++;
        !           780:     l=1; while (mpdivis(n,p,n)) l++;
        !           781:     m = mulsi(l,m); if (is_pm1(n)) { return gerepileupto(av,m); }
        !           782:   }
        !           783:   if(cmpii(sqri(p),n) >= 0 || pseudoprime(n))
        !           784:   {
        !           785:     m = shifti(m,1);
        !           786:     return gerepileupto(av,m);
        !           787:   }
        !           788:   m = mulii(m, ifac_numdiv(n, decomp_default_hint));
        !           789:   return gerepileupto(av,m);
        !           790: }
        !           791:
        !           792: GEN
        !           793: gsumdiv(GEN n)
        !           794: {
        !           795:   return garith_proto(sumdiv,n,1);
        !           796: }
        !           797:
        !           798: GEN
        !           799: sumdiv(GEN n)
        !           800: {
        !           801:   byteptr d=diffptr+1;
        !           802:   GEN p,m,m1;
        !           803:   long av=avma,lim1,v;
        !           804:
        !           805:   if (typ(n) != t_INT) err(arither1);
        !           806:   if (!signe(n)) err(arither2);
        !           807:   if (is_pm1(n)) return gun;
        !           808:   v=vali(n);
        !           809:   n=absi(shifti(n,-v)); p=court_p; p[2]=2;
        !           810:   m = (v ? addsi(-1,shifti(gun,v+1)) : stoi(1));
        !           811:   if (is_pm1(n)) { return gerepileupto(av,m); }
        !           812:   lim1 = tridiv_bound(n,1);
        !           813:
        !           814:   while (*d && p[2] < lim1)
        !           815:   {
        !           816:     p[2] += *d++;
        !           817:     if (mpdivis(n,p,n))
        !           818:     {
        !           819:       m1=addsi(1,p);
        !           820:       while (mpdivis(n,p,n)) m1=addsi(1,mulii(p,m1));
        !           821:       m = mulii(m1,m); if (is_pm1(n)) { return gerepileupto(av,m); }
        !           822:     }
        !           823:   }
        !           824:   if(cmpii(sqri(p),n) >= 0 || pseudoprime(n))
        !           825:   {
        !           826:     m = mulii(m,addsi(1,n));
        !           827:     return gerepileupto(av,m);
        !           828:   }
        !           829:   m = mulii(m, ifac_sumdiv(n, decomp_default_hint));
        !           830:   return gerepileupto(av,m);
        !           831: }
        !           832:
        !           833: GEN
        !           834: gsumdivk(GEN n, long k)
        !           835: {
        !           836:   return garith_proto2gs(sumdivk,n,k);
        !           837: }
        !           838:
        !           839: GEN
        !           840: sumdivk(GEN n, long k)
        !           841: {
        !           842:   byteptr d=diffptr+1;
        !           843:   GEN p,p1,m,m1,pk;
        !           844:   long av=avma,tetpil,k1,lim1,v;
        !           845:
        !           846:   if (!k) return numbdiv(n);
        !           847:   if (k==1) return sumdiv(n);
        !           848:   if (typ(n) != t_INT) err(arither1);
        !           849:   if (!signe(n)) err(arither2);
        !           850:   if (is_pm1(n)) return gun;
        !           851:   k1=k;
        !           852:   if (k==-1) { p1=ginv(n); m=sumdiv(n); goto fin; }
        !           853:   if (k<0) { k= -k; p1=gpuigs(n,k1); }
        !           854:   v=vali(n);
        !           855:   n=absi(shifti(n,-v));
        !           856:   p = court_p; p[2]=2; m=stoi(1);
        !           857:   while (v--) { m=addsi(1,shifti(m,k)); }
        !           858:   if (is_pm1(n)) goto fin;
        !           859:   lim1 = tridiv_bound(n,1);
        !           860:
        !           861:   while (*d && p[2] < lim1)
        !           862:   {
        !           863:     p[2] += *d++;
        !           864:     if (mpdivis(n,p,n))
        !           865:     {
        !           866:       pk=gpuigs(p,k); m1=addsi(1,pk);
        !           867:       while (mpdivis(n,p,n)) m1=addsi(1,mulii(pk,m1));
        !           868:       m = mulii(m1,m); if (is_pm1(n)) goto fin;
        !           869:     }
        !           870:   }
        !           871:   if(cmpii(sqri(p),n) >= 0 || pseudoprime(n))
        !           872:   {
        !           873:     pk=gpuigs(n,k);
        !           874:     m = mulii(m,addsi(1,pk));
        !           875:     goto fin;
        !           876:   }
        !           877:   m = mulii(m, ifac_sumdivk(n, k, decomp_default_hint));
        !           878:  fin:
        !           879:   if (k1>=0) return gerepileupto(av,m);
        !           880:   tetpil=avma; return gerepile(av,tetpil,gmul(p1,m));
        !           881: }
        !           882:
        !           883: /***********************************************************************/
        !           884: /**                                                                   **/
        !           885: /**                MISCELLANEOUS ARITHMETIC FUNCTIONS                 **/
        !           886: /**         (all of these ultimately depend on auxdecomp())           **/
        !           887: /**                                                                   **/
        !           888: /***********************************************************************/
        !           889:
        !           890: GEN
        !           891: divisors(GEN n)
        !           892: {
        !           893:   long tetpil,av=avma,i,j,l;
        !           894:   GEN *d,*t,*t1,*t2,*t3, nbdiv,e;
        !           895:
        !           896:   if (typ(n) != t_MAT || lg(n) != 3) n = auxdecomp(n,1);
        !           897:
        !           898:   e = (GEN) n[2], n = (GEN) n[1]; l = lg(n);
        !           899:   if (l>1 && signe(n[1]) < 0) { e++; n++; l--; } /* skip -1 */
        !           900:   nbdiv = gun;
        !           901:   for (i=1; i<l; i++)
        !           902:   {
        !           903:     e[i] = itos((GEN)e[i]);
        !           904:     nbdiv = mulis(nbdiv,1+e[i]);
        !           905:   }
        !           906:   d = t = (GEN*) cgetg(itos(nbdiv)+1,t_VEC);
        !           907:   *++d = gun;
        !           908:   for (i=1; i<l; i++)
        !           909:     for (t1=t,j=e[i]; j; j--,t1=t2)
        !           910:       for (t2=d,t3=t1; t3<t2; )
        !           911:        *++d = mulii(*++t3, (GEN)n[i]);
        !           912:   tetpil=avma; return gerepile(av,tetpil,sort((GEN)t));
        !           913: }
        !           914:
        !           915: GEN
        !           916: core(GEN n)
        !           917: {
        !           918:   long av=avma,tetpil,i;
        !           919:   GEN fa,p1,p2,res=gun;
        !           920:
        !           921:   fa=auxdecomp(n,1); p1=(GEN)fa[1]; p2=(GEN)fa[2];
        !           922:   for (i=1; i<lg(p1); i++)
        !           923:     if (mod2((GEN)p2[i])) res = mulii(res,(GEN)p1[i]);
        !           924:   tetpil=avma; return gerepile(av,tetpil,icopy(res));
        !           925: }
        !           926:
        !           927: GEN
        !           928: core2(GEN n)
        !           929: {
        !           930:   long av=avma,tetpil,i;
        !           931:
        !           932:   GEN fa,p1,p2,p3,res=gun,res2=gun,y;
        !           933:
        !           934:   fa=auxdecomp(n,1); p1=(GEN)fa[1]; p2=(GEN)fa[2];
        !           935:   for (i=1; i<lg(p1); i++)
        !           936:   {
        !           937:     p3=(GEN)p2[i];
        !           938:     if (mod2(p3)) res=mulii(res,(GEN)p1[i]);
        !           939:     if (!gcmp1(p3)) res2=mulii(res2,gpui((GEN)p1[i],shifti(p3,-1),0));
        !           940:   }
        !           941:   tetpil=avma; y=cgetg(3,t_VEC);
        !           942:   y[1]=(long)icopy(res); y[2]=(long)icopy(res2);
        !           943:   return gerepile(av,tetpil,y);
        !           944: }
        !           945:
        !           946: GEN
        !           947: core0(GEN n,long flag)
        !           948: {
        !           949:   return flag? core2(n): core(n);
        !           950: }
        !           951:
        !           952: GEN
        !           953: coredisc(GEN n)
        !           954: {
        !           955:   long av=avma,tetpil,r;
        !           956:   GEN p1=core(n);
        !           957:
        !           958:   r=mod4(p1); if (signe(p1)<0) r = 4-r;
        !           959:   if (r==1 || r==4) return p1;
        !           960:   tetpil=avma; return gerepile(av,tetpil,shifti(p1,2));
        !           961: }
        !           962:
        !           963: GEN
        !           964: coredisc2(GEN n)
        !           965: {
        !           966:   long av=avma,tetpil,r;
        !           967:   GEN y,p1,p2=core2(n);
        !           968:
        !           969:   p1=(GEN)p2[1]; r=mod4(p1); if (signe(p1)<0) r=4-r;
        !           970:   if (r==1 || r==4) return p2;
        !           971:   tetpil=avma; y=cgetg(3,t_VEC);
        !           972:   y[1]=lshifti(p1,2); y[2]=lmul2n((GEN)p2[2],-1);
        !           973:   return gerepile(av,tetpil,y);
        !           974: }
        !           975:
        !           976: GEN
        !           977: coredisc0(GEN n,long flag)
        !           978: {
        !           979:   return flag? coredisc2(n): coredisc(n);
        !           980: }
        !           981:
        !           982: /***********************************************************************/
        !           983: /**                                                                   **/
        !           984: /**                      BINARY QUADRATIC FORMS                       **/
        !           985: /**                                                                   **/
        !           986: /***********************************************************************/
        !           987:
        !           988: GEN
        !           989: qf_disc(GEN x, GEN y, GEN z)
        !           990: {
        !           991:   if (!y) { y=(GEN)x[2]; z=(GEN)x[3]; x=(GEN)x[1]; }
        !           992:   return subii(sqri(y), shifti(mulii(x,z),2));
        !           993: }
        !           994:
        !           995: static GEN
        !           996: qf_create(GEN x, GEN y, GEN z, long s)
        !           997: {
        !           998:   GEN t;
        !           999:   if (typ(x)!=t_INT || typ(y)!=t_INT || typ(z)!=t_INT) err(typeer,"Qfb");
        !          1000:   if (!s)
        !          1001:   {
        !          1002:     long av=avma; s = signe(qf_disc(x,y,z)); avma=av;
        !          1003:     if (!s) err(talker,"zero discriminant in Qfb");
        !          1004:   }
        !          1005:   t = (s>0)? cgetg(5,t_QFR): cgetg(4,t_QFI);
        !          1006:   t[1]=(long)icopy(x); t[2]=(long)icopy(y); t[3]=(long)icopy(z);
        !          1007:   return t;
        !          1008: }
        !          1009:
        !          1010: GEN
        !          1011: qfi(GEN x, GEN y, GEN z)
        !          1012: {
        !          1013:   return qf_create(x,y,z,-1);
        !          1014: }
        !          1015:
        !          1016: GEN
        !          1017: qfr(GEN x, GEN y, GEN z, GEN d)
        !          1018: {
        !          1019:   GEN t = qf_create(x,y,z,1);
        !          1020:   if (typ(d) != t_REAL)
        !          1021:     err(talker,"Shanks distance should be a t_REAL (in qfr)");
        !          1022:   t[4]=lrcopy(d); return t;
        !          1023: }
        !          1024:
        !          1025: GEN
        !          1026: Qfb0(GEN x, GEN y, GEN z, GEN d, long prec)
        !          1027: {
        !          1028:   GEN t = qf_create(x,y,z,0);
        !          1029:   if (lg(t)==4) return t;
        !          1030:   if (!d) d = gzero;
        !          1031:   if (typ(d) == t_REAL)
        !          1032:     t[4] = lrcopy(d);
        !          1033:   else
        !          1034:     { t[4]=lgetr(prec); gaffect(d,(GEN)t[4]); }
        !          1035:   return t;
        !          1036: }
        !          1037:
        !          1038: /* composition */
        !          1039:
        !          1040: static void
        !          1041: comp_gen(GEN z,GEN x,GEN y)
        !          1042: {
        !          1043:   GEN s,n,d,d1,x1,x2,y1,y2,v1,v2,v3,b3,c3,m,p1,r;
        !          1044:
        !          1045:   s=shifti(addii((GEN)x[2],(GEN)y[2]),-1);
        !          1046:   n=subii((GEN)y[2],s);
        !          1047:   d = bezout((GEN)y[1],(GEN)x[1],&y1,&x1);
        !          1048:   d1 = bezout(s,d,&x2,&y2);
        !          1049:   if (gcmp1(d1))
        !          1050:   {
        !          1051:     v3 = (GEN)x[1];
        !          1052:     v2 = (GEN)y[1];
        !          1053:   }
        !          1054:   else
        !          1055:   {
        !          1056:     v1=divii((GEN)x[1],d1);
        !          1057:     v2=divii((GEN)y[1],d1);
        !          1058:     v3 = mulii(v1, mppgcd(d1,mppgcd((GEN)x[3],mppgcd((GEN)y[3],n))));
        !          1059:   }
        !          1060:   m = addii(mulii(mulii(y1,y2),n), mulii((GEN)y[3],x2));
        !          1061:   setsigne(m,-signe(m));
        !          1062:   r=modii(m,v3); p1=mulii(v2,r); b3=shifti(p1,1);
        !          1063:   c3=addii(mulii((GEN)y[3],d1),mulii(r,addii((GEN)y[2],p1)));
        !          1064:   z[1]=lmulii(v3,v2);
        !          1065:   z[2]=laddii((GEN)y[2],b3);
        !          1066:   z[3]=ldivii(c3,v3);
        !          1067: }
        !          1068:
        !          1069: static GEN
        !          1070: compimag0(GEN x, GEN y, int raw)
        !          1071: {
        !          1072:   long tx = typ(x), av = avma, tetpil;
        !          1073:   GEN z;
        !          1074:
        !          1075:   if (typ(y) != tx || tx!=t_QFI) err(typeer,"composition");
        !          1076:   if (cmpii((GEN)x[1],(GEN)y[1]) > 0) { z=x; x=y; y=z; }
        !          1077:   z=cgetg(4,t_QFI); comp_gen(z,x,y); tetpil=avma;
        !          1078:   return gerepile(av,tetpil,raw? gcopy(z): redimag(z));
        !          1079: }
        !          1080:
        !          1081: static GEN
        !          1082: compreal0(GEN x, GEN y, int raw)
        !          1083: {
        !          1084:   long tx = typ(x), av = avma, tetpil;
        !          1085:   GEN z;
        !          1086:
        !          1087:   if (typ(y) != tx || tx!=t_QFR) err(typeer,"composition");
        !          1088:   z=cgetg(5,t_QFR); comp_gen(z,x,y);
        !          1089:   z[4]=laddrr((GEN)x[4],(GEN)y[4]); tetpil=avma;
        !          1090:   return gerepile(av,tetpil, raw? gcopy(z): redreal(z));
        !          1091: }
        !          1092:
        !          1093: GEN
        !          1094: compreal(GEN x, GEN y) { return compreal0(x,y,0); }
        !          1095:
        !          1096: GEN
        !          1097: comprealraw(GEN x, GEN y) { return compreal0(x,y,1); }
        !          1098:
        !          1099: GEN
        !          1100: compimag(GEN x, GEN y) { return compimag0(x,y,0); }
        !          1101:
        !          1102: GEN
        !          1103: compimagraw(GEN x, GEN y) { return compimag0(x,y,1); }
        !          1104:
        !          1105: GEN
        !          1106: compraw(GEN x, GEN y)
        !          1107: {
        !          1108:   return (typ(x)==t_QFI)? compimagraw(x,y): comprealraw(x,y);
        !          1109: }
        !          1110:
        !          1111: static void
        !          1112: sq_gen(GEN z, GEN x)
        !          1113: {
        !          1114:   GEN d1,x2,y2,v1,v3,b3,c3,m,p1,r;
        !          1115:
        !          1116:   d1 = bezout((GEN)x[2],(GEN)x[1],&x2,&y2);
        !          1117:   if (gcmp1(d1)) v1 = v3 = (GEN)x[1];
        !          1118:   else
        !          1119:   {
        !          1120:     v1 = divii((GEN)x[1],d1);
        !          1121:     v3 = mulii(v1,mppgcd(d1,(GEN)x[3]));
        !          1122:   }
        !          1123:   m=mulii((GEN)x[3],x2); setsigne(m,-signe(m));
        !          1124:   r=modii(m,v3); p1=mulii(v1,r); b3=shifti(p1,1);
        !          1125:   c3=addii(mulii((GEN)x[3],d1),mulii(r,addii((GEN)x[2],p1)));
        !          1126:   z[1]=lmulii(v3,v1);
        !          1127:   z[2]=laddii((GEN)x[2],b3);
        !          1128:   z[3]=ldivii(c3,v3);
        !          1129: }
        !          1130:
        !          1131: GEN
        !          1132: sqcompimag0(GEN x, long raw)
        !          1133: {
        !          1134:   long av = avma, tetpil;
        !          1135:   GEN z = cgetg(4,t_QFI);
        !          1136:
        !          1137:   if (typ(x)!=t_QFI) err(typeer,"composition");
        !          1138:   sq_gen(z,x); tetpil=avma;
        !          1139:   return gerepile(av,tetpil,raw? gcopy(z): redimag(z));
        !          1140: }
        !          1141:
        !          1142: static GEN
        !          1143: sqcompreal0(GEN x, long raw)
        !          1144: {
        !          1145:   long av = avma, tetpil;
        !          1146:   GEN z = cgetg(5,t_QFR);
        !          1147:
        !          1148:   if (typ(x)!=t_QFR) err(typeer,"composition");
        !          1149:   sq_gen(z,x); z[4]=lshiftr((GEN)x[4],1); tetpil=avma;
        !          1150:   return gerepile(av,tetpil,raw? gcopy(z): redreal(z));
        !          1151: }
        !          1152:
        !          1153: GEN
        !          1154: sqcompreal(GEN x) { return sqcompreal0(x,0); }
        !          1155:
        !          1156: GEN
        !          1157: sqcomprealraw(GEN x) { return sqcompreal0(x,1); }
        !          1158:
        !          1159: GEN
        !          1160: sqcompimag(GEN x) { return sqcompimag0(x,0); }
        !          1161:
        !          1162: GEN
        !          1163: sqcompimagraw(GEN x) { return sqcompimag0(x,1); }
        !          1164:
        !          1165: GEN
        !          1166: real_unit_form(GEN x)
        !          1167: {
        !          1168:   long av = avma, tetpil,prec;
        !          1169:   GEN p1,p2, y = cgetg(5,t_QFR);
        !          1170:
        !          1171:   y[1]=un; p1=qf_disc(x,NULL,NULL); p2=racine(p1);
        !          1172:   /* we know that p1 and p2 are non-zero */
        !          1173:   if (mod2(p1) != mod2(p2)) p2=addsi(-1,p2);
        !          1174:   y[2]=(long)p2;
        !          1175:   y[3]=lshifti(subii(sqri(p2),p1),-2);
        !          1176:   prec = precision((GEN)x[4]);
        !          1177:   if (!prec)
        !          1178:     err(talker,"not a type real in 4th component of a t_QFR");
        !          1179:   y[4]=(long)realzero(prec); tetpil=avma;
        !          1180:   return gerepile(av,tetpil,gcopy(y));
        !          1181: }
        !          1182:
        !          1183: GEN
        !          1184: imag_unit_form(GEN x)
        !          1185: {
        !          1186:   long av,tetpil;
        !          1187:   GEN p1,p2, y = cgetg(4,t_QFI);
        !          1188:   y[1]=un;
        !          1189:   y[2]=mpodd((GEN)x[2])? un: zero;
        !          1190:   av=avma; p1=mulii((GEN)x[1],(GEN)x[3]);
        !          1191:   p2=shifti(sqri((GEN)x[2]),-2); tetpil=avma;
        !          1192:   y[3]=lpile(av,tetpil,subii(p1,p2));
        !          1193:   return y;
        !          1194: }
        !          1195:
        !          1196: GEN
        !          1197: powrealraw(GEN x, long n)
        !          1198: {
        !          1199:   long av = avma, m;
        !          1200:   GEN y;
        !          1201:
        !          1202:   if (typ(x) != t_QFR)
        !          1203:     err(talker,"not a real quadratic form in powreal");
        !          1204:   if (!n) return real_unit_form(x);
        !          1205:   if (n== 1) return gcopy(x);
        !          1206:   if (n==-1) return ginv(x);
        !          1207:
        !          1208:   y = NULL; m=labs(n);
        !          1209:   for (; m>1; m>>=1)
        !          1210:   {
        !          1211:     if (m&1) y = y? comprealraw(y,x): x;
        !          1212:     x=sqcomprealraw(x);
        !          1213:   }
        !          1214:   y = y? comprealraw(y,x): x;
        !          1215:   if (n<0) y = ginv(y);
        !          1216:   return gerepileupto(av,y);
        !          1217: }
        !          1218:
        !          1219: GEN
        !          1220: powimagraw(GEN x, long n)
        !          1221: {
        !          1222:   long av = avma, m;
        !          1223:   GEN y;
        !          1224:
        !          1225:   if (typ(x) != t_QFI)
        !          1226:     err(talker,"not an imaginary quadratic form in powimag");
        !          1227:   if (!n) return imag_unit_form(x);
        !          1228:   if (n== 1) return gcopy(x);
        !          1229:   if (n==-1) return ginv(x);
        !          1230:
        !          1231:   y = NULL; m=labs(n);
        !          1232:   for (; m>1; m>>=1)
        !          1233:   {
        !          1234:     if (m&1) y = y? compimagraw(y,x): x;
        !          1235:     x=sqcompimagraw(x);
        !          1236:   }
        !          1237:   y = y? compimagraw(y,x): x;
        !          1238:   if (n<0) y = ginv(y);
        !          1239:   return gerepileupto(av,y);
        !          1240: }
        !          1241:
        !          1242: GEN
        !          1243: powraw(GEN x, long n)
        !          1244: {
        !          1245:   return (typ(x)==t_QFI)? powimagraw(x,n): powrealraw(x,n);
        !          1246: }
        !          1247:
        !          1248: /* composition: Shanks' NUCOMP & NUDUPL */
        !          1249: /* l = floor((|d|/4)^(1/4)) */
        !          1250: GEN
        !          1251: nucomp(GEN x, GEN y, GEN l)
        !          1252: {
        !          1253:   long av=avma,tetpil,cz;
        !          1254:   GEN a,a1,a2,b,b2,d,d1,e,g,n,p1,p2,p3,q1,q2,q3,q4,s,t2,t3,u,u1,v,v1,v2,v3,z;
        !          1255:
        !          1256:   if (x==y) return nudupl(x,l);
        !          1257:   if (typ(x) != t_QFI || typ(y) != t_QFI)
        !          1258:     err(talker,"not an imaginary quadratic form in nucomp");
        !          1259:
        !          1260:   if (cmpii((GEN)x[1],(GEN)y[1]) < 0) { s=x; x=y; y=s; }
        !          1261:   s=shifti(addii((GEN)x[2],(GEN)y[2]),-1); n=subii((GEN)y[2],s);
        !          1262:   a1=(GEN)x[1]; a2=(GEN)y[1]; d=bezout(a2,a1,&u,&v);
        !          1263:   if (gcmp1(d)) { a=negi(gmul(u,n)); d1=d; }
        !          1264:   else
        !          1265:     if (divise(s,d))
        !          1266:     {
        !          1267:       a=negi(gmul(u,n)); d1=d; a1=divii(a1,d1);
        !          1268:       a2=divii(a2,d1); s=divii(s,d1);
        !          1269:     }
        !          1270:     else
        !          1271:     {
        !          1272:       d1=bezout(s,d,&u1,&v1);
        !          1273:       if (!gcmp1(d1))
        !          1274:       {
        !          1275:        a1=divii(a1,d1); a2=divii(a2,d1);
        !          1276:        s=divii(s,d1); d=divii(d,d1);
        !          1277:       }
        !          1278:       p1=resii((GEN)x[3],d); p2=resii((GEN)y[3],d);
        !          1279:       p3=modii(negi(mulii(u1,addii(mulii(u,p1),mulii(v,p2)))),d);
        !          1280:       a=subii(mulii(p3,divii(a1,d)),mulii(u,divii(n,d)));
        !          1281:     }
        !          1282:   a=modii(a,a1); p1=subii(a1,a); if (cmpii(a,p1)>0) a=negi(p1);
        !          1283:   v=gzero; d=a1; v2=gun; v3=a;
        !          1284:   for (cz=0; absi_cmp(v3,l) > 0; cz++)
        !          1285:   {
        !          1286:     p1=dvmdii(d,v3,&t3); t2=subii(v,mulii(p1,v2));
        !          1287:     v=v2; d=v3; v2=t2; v3=t3;
        !          1288:   }
        !          1289:   z=cgetg(4,t_QFI);
        !          1290:   if (!cz)
        !          1291:   {
        !          1292:     q1=mulii(a2,v3); q2=addii(q1,n);
        !          1293:     g=divii(addii(mulii(v3,s),(GEN)y[3]),d);
        !          1294:     z[1]=lmulii(d,a2);
        !          1295:     z[2]=laddii(shifti(q1,1),(GEN)y[2]);
        !          1296:     z[3]=laddii(mulii(v3,divii(q2,d)), mulii(g,d1));
        !          1297:   }
        !          1298:   else
        !          1299:   {
        !          1300:     if (cz&1) { v3=negi(v3); v2=negi(v2); }
        !          1301:     b=divii(addii(mulii(a2,d),mulii(n,v)),a1);
        !          1302:     q1=mulii(b,v3); q2=addii(q1,n);
        !          1303:     e=divii(addii(mulii(s,d),mulii((GEN)y[3],v)),a1);
        !          1304:     q3=mulii(e,v2); q4=subii(q3,s);
        !          1305:     g=divii(q4,v); b2=addii(q3,q4);
        !          1306:     if (!gcmp1(d1)) { v2=mulii(d1,v2); v=mulii(d1,v); b2=mulii(d1,b2); }
        !          1307:     z[1]=laddii(mulii(d,b),mulii(e,v));
        !          1308:     z[2]=laddii(b2,addii(q1,q2));
        !          1309:     z[3]=laddii(mulii(v3,divii(q2,d)), mulii(g,v2));
        !          1310:   }
        !          1311:   tetpil=avma; return gerepile(av,tetpil,redimag(z));
        !          1312: }
        !          1313:
        !          1314: GEN
        !          1315: nudupl(GEN x, GEN l)
        !          1316: {
        !          1317:   long av=avma,tetpil,cz;
        !          1318:   GEN u,v,d,d1,p1,a,b,c,b2,z,v2,v3,t2,t3,e,g;
        !          1319:
        !          1320:   if (typ(x) != t_QFI)
        !          1321:     err(talker,"not an imaginary quadratic form in nudupl");
        !          1322:   d1=bezout((GEN)x[2],(GEN)x[1],&u,&v);
        !          1323:   a=divii((GEN)x[1],d1); b=divii((GEN)x[2],d1);
        !          1324:   c=modii(negi(mulii(u,(GEN)x[3])),a); p1=subii(a,c);
        !          1325:   if (cmpii(c,p1)>0) c=negi(p1);
        !          1326:   v=gzero; d=a; v2=gun; v3=c;
        !          1327:   for (cz=0; absi_cmp(v3,l) > 0; cz++)
        !          1328:   {
        !          1329:     p1=dvmdii(d,v3,&t3); t2=subii(v,mulii(p1,v2));
        !          1330:     v=v2; d=v3; v2=t2; v3=t3;
        !          1331:   }
        !          1332:   z=cgetg(4,t_QFI);
        !          1333:   if (!cz)
        !          1334:   {
        !          1335:     g=divii(addii(mulii(v3,b),(GEN)x[3]),d);
        !          1336:     z[1]=(long)sqri(d);
        !          1337:     z[2]=laddii((GEN)x[2],shifti(mulii(d,v3),1));
        !          1338:     z[3]=laddii(sqri(v3),mulii(g,d1));
        !          1339:   }
        !          1340:   else
        !          1341:   {
        !          1342:     if (cz&1) { v=negi(v); d=negi(d); }
        !          1343:     e=divii(addii(mulii((GEN)x[3],v),mulii(b,d)),a);
        !          1344:     g=divii(subii(mulii(e,v2),b),v);
        !          1345:     b2=addii(mulii(e,v2),mulii(v,g));
        !          1346:     if (!gcmp1(d1)) { v2=mulii(d1,v2); v=mulii(d1,v); b2=mulii(d1,b2); }
        !          1347:     z[1]=laddii(sqri(d),mulii(e,v));
        !          1348:     z[2]=laddii(b2,shifti(mulii(d,v3),1));
        !          1349:     z[3]=laddii(sqri(v3),mulii(g,v2));
        !          1350:   }
        !          1351:   tetpil=avma; return gerepile(av,tetpil,redimag(z));
        !          1352: }
        !          1353:
        !          1354: GEN
        !          1355: nupow(GEN x, GEN n)
        !          1356: {
        !          1357:   long av,tetpil,i,j;
        !          1358:   unsigned long m;
        !          1359:   GEN y,l;
        !          1360:
        !          1361:   if (typ(n) != t_INT) err(talker,"not an integer exponent in nupow");
        !          1362:   if (gcmp1(n)) return gcopy(x);
        !          1363:   av=avma; y = imag_unit_form(x);
        !          1364:   if (!signe(n)) return y;
        !          1365:
        !          1366:   l = racine(shifti(racine((GEN)y[3]),1));
        !          1367:   for (i=lgefint(n)-1; i>2; i--)
        !          1368:     for (m=n[i],j=0; j<BITS_IN_LONG; j++,m>>=1)
        !          1369:     {
        !          1370:       if (m&1) y=nucomp(y,x,l);
        !          1371:       x=nudupl(x,l);
        !          1372:     }
        !          1373:   for (m=n[2]; m>1; m>>=1)
        !          1374:   {
        !          1375:     if (m&1) y=nucomp(y,x,l);
        !          1376:     x=nudupl(x,l);
        !          1377:   }
        !          1378:   tetpil=avma; y=nucomp(y,x,l);
        !          1379:   if (signe(n)<0 && !egalii((GEN)y[1],(GEN)y[2])
        !          1380:                  && !egalii((GEN)y[1],(GEN)y[3]))
        !          1381:     setsigne(y[2],-signe(y[2]));
        !          1382:   return gerepile(av,tetpil,y);
        !          1383: }
        !          1384:
        !          1385: /* reduction */
        !          1386:
        !          1387: static GEN
        !          1388: abs_dvmdii(GEN b, GEN p1, GEN *pt, long s)
        !          1389: {
        !          1390:   if (s<0) setsigne(b, 1); p1 = dvmdii(b,p1,pt);
        !          1391:   if (s<0) setsigne(b,-1); return p1;
        !          1392: }
        !          1393:
        !          1394: static GEN
        !          1395: rhoimag0(GEN x, long *flag)
        !          1396: {
        !          1397:   GEN p1,b,d,z;
        !          1398:   long fl, s = signe(x[2]);
        !          1399:
        !          1400:   fl = cmpii((GEN)x[1], (GEN)x[3]);
        !          1401:   if (fl <= 0)
        !          1402:   {
        !          1403:     long fg = absi_cmp((GEN)x[1], (GEN)x[2]);
        !          1404:     if (fg >= 0)
        !          1405:     {
        !          1406:       *flag = (s<0 && (!fl || !fg))? 2 /* set x[2] = negi(x[2]) in caller */
        !          1407:                                    : 1;
        !          1408:       return x;
        !          1409:     }
        !          1410:   }
        !          1411:   p1=shifti((GEN)x[3],1); d = abs_dvmdii((GEN)x[2],p1,&b,s);
        !          1412:   if (s>=0)
        !          1413:   {
        !          1414:     setsigne(d,-signe(d));
        !          1415:     if (cmpii(b,(GEN)x[3])<=0) setsigne(b,-signe(b));
        !          1416:     else { d=addsi(-1,d); b=subii(p1,b); }
        !          1417:   }
        !          1418:   else if (cmpii(b,(GEN)x[3])>=0) { d=addsi(1,d); b=subii(b,p1); }
        !          1419:
        !          1420:   z=cgetg(4,t_QFI);
        !          1421:   z[1] = x[3];
        !          1422:   z[3] = laddii((GEN)x[1], mulii(d,shifti(subii((GEN)x[2],b),-1)));
        !          1423:   if (signe(b)<0 && !fl) setsigne(b,1);
        !          1424:   z[2] = (long)b; *flag = 0; return z;
        !          1425: }
        !          1426:
        !          1427: /* if sqrtD != NULL, compute Shanks' distance as well */
        !          1428: static GEN
        !          1429: rhoreal0(GEN x, GEN D, GEN isqrtD, GEN sqrtD)
        !          1430: {
        !          1431:   long s = signe(x[3]);
        !          1432:   GEN p1,p2, z = cgetg(5,t_QFR);
        !          1433:
        !          1434:   if (!sqrtD)
        !          1435:     z[4] = x[4];
        !          1436:   else
        !          1437:   {
        !          1438:     p1 = divrr(addir((GEN)x[2],sqrtD), subir((GEN)x[2],sqrtD));
        !          1439:     if (signe(p1)<0) setsigne(p1,1); /* p1 = |(b+sqrtD) / (b-sqrtD)| */
        !          1440:     z[4] = laddrr(shiftr(mplog(p1),-1), (GEN) x[4]);
        !          1441:   }
        !          1442:   z[1] = x[3]; setsigne(z[1],1);
        !          1443:   p1=shifti((GEN)z[1],1);
        !          1444:   p2 = (cmpii(isqrtD,(GEN)z[1]) >= 0)? isqrtD: (GEN)z[1];
        !          1445:   p2 = divii(addii(p2,(GEN)x[2]),p1);
        !          1446:   z[2] = lsubii(mulii(p2,p1), (GEN)x[2]);
        !          1447:
        !          1448:   setsigne(z[1],s);
        !          1449:   p1=shifti(subii(sqri((GEN)z[2]),D),-2);
        !          1450:   z[3] = ldivii(p1,(GEN)z[1]); return z;
        !          1451: }
        !          1452:
        !          1453: static GEN
        !          1454: redreal0(GEN x, long flag, GEN D, GEN isqrtD, GEN sqrtD)
        !          1455: {
        !          1456:   long av=avma,l,step, use_d;
        !          1457:
        !          1458:   if (typ(x) != t_QFR) err(talker,"not a real quadratic form in redreal");
        !          1459:   switch(flag)
        !          1460:   {
        !          1461:     case 0: use_d=1; step=0; break;
        !          1462:     case 1: use_d=1; step=1; break;
        !          1463:     case 2: use_d=0; step=0; break;
        !          1464:     case 3: use_d=0; step=1; break;
        !          1465:     default: err(flagerr,"qfbred");
        !          1466:   }
        !          1467:
        !          1468:   if (!D) D = qf_disc(x,NULL,NULL);
        !          1469:   else if (typ(D) != t_INT) err(arither1);
        !          1470:
        !          1471:   if (!isqrtD || (use_d && !sqrtD))
        !          1472:   {
        !          1473:     l=max(lg(x[4]),3);
        !          1474:     l=max(l,((BITS_IN_LONG-1-expo(x[4]))>>TWOPOTBITS_IN_LONG)+2);
        !          1475:     sqrtD=gsqrt(D,l); isqrtD=mptrunc(sqrtD);
        !          1476:   }
        !          1477:   else
        !          1478:   {
        !          1479:     if (typ(isqrtD) != t_INT) err(arither1);
        !          1480:     if (sqrtD)
        !          1481:     {
        !          1482:       l=typ(sqrtD); if (!is_intreal_t(l)) err(arither1);
        !          1483:     }
        !          1484:   }
        !          1485:   if (step)
        !          1486:     x = rhoreal0(x,D,isqrtD,sqrtD);
        !          1487:   else
        !          1488:     for(;;)
        !          1489:     {
        !          1490:       if (signe(x[2]) > 0 && cmpii((GEN)x[2],isqrtD) <= 0 )
        !          1491:       {
        !          1492:         GEN p1=subii(isqrtD, shifti(absi((GEN)x[1]),1));
        !          1493:
        !          1494:         l = absi_cmp((GEN)x[2],p1);
        !          1495:         if (l>0 || (l==0 && signe(p1)<0)) break;
        !          1496:       }
        !          1497:       x = rhoreal0(x,D,isqrtD,sqrtD);
        !          1498:     }
        !          1499:   l=avma; return gerepile(av,l,gcopy(x));
        !          1500: }
        !          1501:
        !          1502: GEN
        !          1503: redimag(GEN x)
        !          1504: {
        !          1505:   long av=avma, tetpil, fl;
        !          1506:   do x = rhoimag0(x, &fl); while (fl == 0);
        !          1507:   tetpil=avma; x = gerepile(av,tetpil,gcopy(x));
        !          1508:   if (fl == 2) setsigne(x[2], -signe(x[2]));
        !          1509:   return x;
        !          1510: }
        !          1511:
        !          1512: GEN
        !          1513: redreal(GEN x)
        !          1514: {
        !          1515:   return redreal0(x,0,NULL,NULL,NULL);
        !          1516: }
        !          1517:
        !          1518: GEN
        !          1519: rhoreal(GEN x)
        !          1520: {
        !          1521:   return redreal0(x,1,NULL,NULL,NULL);
        !          1522: }
        !          1523:
        !          1524: GEN
        !          1525: redrealnod(GEN x, GEN isqrtD)
        !          1526: {
        !          1527:   return redreal0(x,2,NULL,isqrtD,NULL);
        !          1528: }
        !          1529:
        !          1530: GEN
        !          1531: rhorealnod(GEN x, GEN isqrtD)
        !          1532: {
        !          1533:   return redreal0(x,3,NULL,isqrtD,NULL);
        !          1534: }
        !          1535:
        !          1536: GEN
        !          1537: qfbred0(GEN x, long flag, GEN D, GEN isqrtD, GEN sqrtD)
        !          1538: {
        !          1539:   long tx=typ(x),av,tetpil,fl;
        !          1540:
        !          1541:   if (!is_qf_t(tx)) err(talker,"not a quadratic form in qfbred");
        !          1542:   if (!D) D = qf_disc(x,NULL,NULL);
        !          1543:   switch(signe(D))
        !          1544:   {
        !          1545:     case 1 :
        !          1546:       return redreal0(x,flag,D,isqrtD,sqrtD);
        !          1547:
        !          1548:     case -1:
        !          1549:       if (!flag) return  redimag(x);
        !          1550:       if (flag !=1) err(flagerr,"qfbred");
        !          1551:       av=avma; x = rhoimag0(x,&fl); tetpil=avma;
        !          1552:       x = gerepile(av,tetpil,gcopy(x));
        !          1553:       if (fl == 2) setsigne(x[2], -signe(x[2]));
        !          1554:       return x;
        !          1555:   }
        !          1556:   err(redpoler,"qfbred");
        !          1557:   return NULL; /* not reached */
        !          1558: }
        !          1559:
        !          1560: GEN
        !          1561: primeform(GEN x, GEN p, long prec)
        !          1562: {
        !          1563:   long av,tetpil,s=signe(x);
        !          1564:   GEN y,b;
        !          1565:
        !          1566:   if (typ(x) != t_INT || !s) err(arither1);
        !          1567:   if (typ(p) != t_INT || signe(p) <= 0) err(arither1);
        !          1568:   if (s < 0)
        !          1569:   {
        !          1570:     y = cgetg(4,t_QFI); s = 8-mod8(x);
        !          1571:   }
        !          1572:   else
        !          1573:   {
        !          1574:     y = cgetg(5,t_QFR); s = mod8(x);
        !          1575:     y[4]=(long)realzero(prec);
        !          1576:   }
        !          1577:   switch(s&3)
        !          1578:   {
        !          1579:     case 2: case 3: err(funder2,"primeform");
        !          1580:   }
        !          1581:   y[1] = (long)icopy(p); av=avma;
        !          1582:   if (egalii(p,gdeux))
        !          1583:   {
        !          1584:     switch(s)
        !          1585:     {
        !          1586:       case 0: y[2]=zero; break;
        !          1587:       case 8: s=0; y[2]=zero; break;
        !          1588:       case 1: s=1; y[2]=un; break;
        !          1589:       case 4: s=4; y[2]=deux; break;
        !          1590:       default: err(sqrter5);
        !          1591:     }
        !          1592:     b=subsi(s,x); tetpil=avma; b=shifti(b,-3);
        !          1593:   }
        !          1594:   else
        !          1595:   {
        !          1596:     b = mpsqrtmod(x,p); if (!b) err(sqrter5);
        !          1597:     if (mod2(b) == mod2(x)) y[2] = (long)b;
        !          1598:     else
        !          1599:     { tetpil = avma; y[2] = lpile(av,tetpil,subii(p,b)); }
        !          1600:
        !          1601:     av=avma; b=shifti(subii(sqri((GEN)y[2]),x),-2);
        !          1602:     tetpil=avma; b=divii(b,p);
        !          1603:   }
        !          1604:   y[3]=lpile(av,tetpil,b); return y;
        !          1605: }

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