[BACK]Return to mp.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / pari-2.2 / src / kernel / none

Annotation of OpenXM_contrib/pari-2.2/src/kernel/none/mp.c, Revision 1.1.1.1

1.1       noro        1: /* $Id: mp.c,v 1.47 2001/09/28 17:16:45 xavier Exp $
                      2:
                      3: Copyright (C) 2000  The PARI group.
                      4:
                      5: This file is part of the PARI/GP package.
                      6:
                      7: PARI/GP is free software; you can redistribute it and/or modify it under the
                      8: terms of the GNU General Public License as published by the Free Software
                      9: Foundation. It is distributed in the hope that it will be useful, but WITHOUT
                     10: ANY WARRANTY WHATSOEVER.
                     11:
                     12: Check the License for details. You should have received a copy of it, along
                     13: with the package; see the file 'COPYING'. If not, write to the Free Software
                     14: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
                     15:
                     16: /***********************************************************************/
                     17: /**                                                                  **/
                     18: /**                     MULTIPRECISION KERNEL                        **/
                     19: /**                                                                   **/
                     20: /***********************************************************************/
                     21: /* most of the routines in this file are commented out in 68k */
                     22: /* version (#ifdef __M68K__) since they are defined in mp.s   */
                     23: #include "pari.h"
                     24:
                     25: /* NOTE: arguments of "spec" routines (muliispec, addiispec, etc.) aren't
                     26:  * GENs but pairs (long *a, long na) representing a list of digits (in basis
                     27:  * BITS_IN_LONG) : a[0], ..., a[na-1]. [ In ordre to facilitate splitting: no
                     28:  * need to reintroduce codewords ]
                     29:  * Use speci(a,na) to visualize the coresponding GEN.
                     30:  */
                     31:
                     32: /* z2 := z1[imin..imax].f shifted left sh bits (feeding f from the right) */
                     33: #define shift_left2(z2,z1,imin,imax,f, sh,m) {\
                     34:   register ulong _l,_k = ((ulong)f)>>m;\
                     35:   GEN t1 = z1 + imax, t2 = z2 + imax, T = z1 + imin;\
                     36:   while (t1 > T) {\
                     37:     _l = *t1--;\
                     38:     *t2-- = (_l<<(ulong)sh) | _k;\
                     39:     _k = _l>>(ulong)m;\
                     40:   }\
                     41:   *t2 = (*t1<<(ulong)sh) | _k;\
                     42: }
                     43: #define shift_left(z2,z1,imin,imax,f, sh) {\
                     44:   register const ulong _m = BITS_IN_LONG - sh;\
                     45:   shift_left2((z2),(z1),(imin),(imax),(f),(sh),(_m));\
                     46: }
                     47:
                     48: /* z2 := f.z1[imin..imax-1] shifted right sh bits (feeding f from the left) */
                     49: #define shift_right2(z2,z1,imin,imax,f, sh,m) {\
                     50:   register GEN t1 = z1 + imin, t2 = z2 + imin, T = z1 + imax;\
                     51:   register ulong _k,_l = *t1++;\
                     52:   *t2++ = (_l>>(ulong)sh) | ((ulong)f<<(ulong)m);\
                     53:   while (t1 < T) {\
                     54:     _k = _l<<(ulong)m; _l = *t1++;\
                     55:     *t2++ = (_l>>(ulong)sh) | _k;\
                     56:   }\
                     57: }
                     58: #define shift_right(z2,z1,imin,imax,f, sh) {\
                     59:   register const ulong _m = BITS_IN_LONG - sh;\
                     60:   shift_right2((z2),(z1),(imin),(imax),(f),(sh),(_m));\
                     61: }
                     62:
                     63: #define MASK(x) (((ulong)(x)) & (LGEFINTBITS | SIGNBITS))
                     64: int
                     65: egalii(GEN x, GEN y)
                     66: {
                     67:   long i;
                     68:   if (MASK(x[1]) != MASK(y[1])) return 0;
                     69:   i = lgefint(x)-1; while (i>1 && x[i]==y[i]) i--;
                     70:   return i==1;
                     71: }
                     72: #undef MASK
                     73:
                     74: #ifdef INLINE
                     75: INLINE
                     76: #endif
                     77: GEN
                     78: addsispec(long s, GEN x, long nx)
                     79: {
                     80:   GEN xd, zd = (GEN)avma;
                     81:   long lz;
                     82:   LOCAL_OVERFLOW;
                     83:
                     84:   lz = nx+3; (void)new_chunk(lz);
                     85:   xd = x + nx;
                     86:   *--zd = addll(*--xd, s);
                     87:   if (overflow)
                     88:     for(;;)
                     89:     {
                     90:       if (xd == x) { *--zd = 1; break; } /* enlarge z */
                     91:       *--zd = ((ulong)*--xd) + 1;
                     92:       if (*zd) { lz--; break; }
                     93:     }
                     94:   else lz--;
                     95:   while (xd > x) *--zd = *--xd;
                     96:   *--zd = evalsigne(1) | evallgefint(lz);
                     97:   *--zd = evaltyp(t_INT) | evallg(lz);
                     98:   avma=(long)zd; return zd;
                     99: }
                    100:
                    101: #define swapspec(x,y, nx,ny) {long _a=nx;GEN _z=x; nx=ny; ny=_a; x=y; y=_z;}
                    102:
                    103: #ifdef INLINE
                    104: INLINE
                    105: #endif
                    106: GEN
                    107: addiispec(GEN x, GEN y, long nx, long ny)
                    108: {
                    109:   GEN xd,yd,zd;
                    110:   long lz;
                    111:   LOCAL_OVERFLOW;
                    112:
                    113:   if (nx < ny) swapspec(x,y, nx,ny);
                    114:   if (ny == 1) return addsispec(*y,x,nx);
                    115:   zd = (GEN)avma;
                    116:   lz = nx+3; (void)new_chunk(lz);
                    117:   xd = x + nx;
                    118:   yd = y + ny;
                    119:   *--zd = addll(*--xd, *--yd);
                    120:   while (yd > y) *--zd = addllx(*--xd, *--yd);
                    121:   if (overflow)
                    122:     for(;;)
                    123:     {
                    124:       if (xd == x) { *--zd = 1; break; } /* enlarge z */
                    125:       *--zd = ((ulong)*--xd) + 1;
                    126:       if (*zd) { lz--; break; }
                    127:     }
                    128:   else lz--;
                    129:   while (xd > x) *--zd = *--xd;
                    130:   *--zd = evalsigne(1) | evallgefint(lz);
                    131:   *--zd = evaltyp(t_INT) | evallg(lz);
                    132:   avma=(long)zd; return zd;
                    133: }
                    134:
                    135: /* assume x >= y */
                    136: #ifdef INLINE
                    137: INLINE
                    138: #endif
                    139: GEN
                    140: subisspec(GEN x, long s, long nx)
                    141: {
                    142:   GEN xd, zd = (GEN)avma;
                    143:   long lz;
                    144:   LOCAL_OVERFLOW;
                    145:
                    146:   lz = nx+2; (void)new_chunk(lz);
                    147:   xd = x + nx;
                    148:   *--zd = subll(*--xd, s);
                    149:   if (overflow)
                    150:     for(;;)
                    151:     {
                    152:       *--zd = ((ulong)*--xd) - 1;
                    153:       if (*xd) break;
                    154:     }
                    155:   if (xd == x)
                    156:     while (*zd == 0) { zd++; lz--; } /* shorten z */
                    157:   else
                    158:     do  *--zd = *--xd; while (xd > x);
                    159:   *--zd = evalsigne(1) | evallgefint(lz);
                    160:   *--zd = evaltyp(t_INT) | evallg(lz);
                    161:   avma=(long)zd; return zd;
                    162: }
                    163:
                    164: /* assume x > y */
                    165: #ifdef INLINE
                    166: INLINE
                    167: #endif
                    168: GEN
                    169: subiispec(GEN x, GEN y, long nx, long ny)
                    170: {
                    171:   GEN xd,yd,zd;
                    172:   long lz;
                    173:   LOCAL_OVERFLOW;
                    174:
                    175:   if (ny==1) return subisspec(x,*y,nx);
                    176:   zd = (GEN)avma;
                    177:   lz = nx+2; (void)new_chunk(lz);
                    178:   xd = x + nx;
                    179:   yd = y + ny;
                    180:   *--zd = subll(*--xd, *--yd);
                    181:   while (yd > y) *--zd = subllx(*--xd, *--yd);
                    182:   if (overflow)
                    183:     for(;;)
                    184:     {
                    185:       *--zd = ((ulong)*--xd) - 1;
                    186:       if (*xd) break;
                    187:     }
                    188:   if (xd == x)
                    189:     while (*zd == 0) { zd++; lz--; } /* shorten z */
                    190:   else
                    191:     do  *--zd = *--xd; while (xd > x);
                    192:   *--zd = evalsigne(1) | evallgefint(lz);
                    193:   *--zd = evaltyp(t_INT) | evallg(lz);
                    194:   avma=(long)zd; return zd;
                    195: }
                    196:
                    197: #ifndef __M68K__
                    198:
                    199: /* prototype of positive small ints */
                    200: static long pos_s[] = {
                    201:   evaltyp(t_INT) | m_evallg(3), evalsigne(1) | evallgefint(3), 0 };
                    202:
                    203: /* prototype of negative small ints */
                    204: static long neg_s[] = {
                    205:   evaltyp(t_INT) | m_evallg(3), evalsigne(-1) | evallgefint(3), 0 };
                    206:
                    207: void
                    208: affir(GEN x, GEN y)
                    209: {
                    210:   const long s=signe(x),ly=lg(y);
                    211:   long lx,sh,i;
                    212:
                    213:   if (!s)
                    214:   {
                    215:     y[1] = evalexpo(-bit_accuracy(ly));
                    216:     y[2] = 0; return;
                    217:   }
                    218:
                    219:   lx=lgefint(x); sh=bfffo(x[2]);
                    220:   y[1] = evalsigne(s) | evalexpo(bit_accuracy(lx)-sh-1);
                    221:   if (sh)
                    222:   {
                    223:     if (lx>ly)
                    224:     { shift_left(y,x,2,ly-1, x[ly],sh); }
                    225:     else
                    226:     {
                    227:       for (i=lx; i<ly; i++) y[i]=0;
                    228:       shift_left(y,x,2,lx-1, 0,sh);
                    229:     }
                    230:     return;
                    231:   }
                    232:
                    233:   if (lx>=ly)
                    234:     for (i=2; i<ly; i++) y[i]=x[i];
                    235:   else
                    236:   {
                    237:     for (i=2; i<lx; i++) y[i]=x[i];
                    238:     for (   ; i<ly; i++) y[i]=0;
                    239:   }
                    240: }
                    241:
                    242: void
                    243: affrr(GEN x, GEN y)
                    244: {
                    245:   long lx,ly,i;
                    246:
                    247:   y[1] = x[1]; if (!signe(x)) { y[2]=0; return; }
                    248:
                    249:   lx=lg(x); ly=lg(y);
                    250:   if (lx>=ly)
                    251:     for (i=2; i<ly; i++) y[i]=x[i];
                    252:   else
                    253:   {
                    254:     for (i=2; i<lx; i++) y[i]=x[i];
                    255:     for (   ; i<ly; i++) y[i]=0;
                    256:   }
                    257: }
                    258:
                    259: GEN
                    260: shifti(GEN x, long n)
                    261: {
                    262:   const long s=signe(x);
                    263:   long lx,ly,i,m;
                    264:   GEN y;
                    265:
                    266:   if (!s) return gzero;
                    267:   if (!n) return icopy(x);
                    268:   lx = lgefint(x);
                    269:   if (n > 0)
                    270:   {
                    271:     GEN z = (GEN)avma;
                    272:     long d = n>>TWOPOTBITS_IN_LONG;
                    273:
                    274:     ly = lx+d; y = new_chunk(ly);
                    275:     for ( ; d; d--) *--z = 0;
                    276:     m = n & (BITS_IN_LONG-1);
                    277:     if (!m) for (i=2; i<lx; i++) y[i]=x[i];
                    278:     else
                    279:     {
                    280:       register const ulong sh = BITS_IN_LONG - m;
                    281:       shift_left2(y,x, 2,lx-1, 0,m,sh);
                    282:       i = ((ulong)x[2]) >> sh;
                    283:       if (i) { ly++; y = new_chunk(1); y[2] = i; }
                    284:     }
                    285:   }
                    286:   else
                    287:   {
                    288:     n = -n;
                    289:     ly = lx - (n>>TWOPOTBITS_IN_LONG);
                    290:     if (ly<3) return gzero;
                    291:     y = new_chunk(ly);
                    292:     m = n & (BITS_IN_LONG-1);
                    293:     if (!m) for (i=2; i<ly; i++) y[i]=x[i];
                    294:     else
                    295:     {
                    296:       shift_right(y,x, 2,ly, 0,m);
                    297:       if (y[2] == 0)
                    298:       {
                    299:         if (ly==3) { avma = (long)(y+3); return gzero; }
                    300:         ly--; avma = (long)(++y);
                    301:       }
                    302:     }
                    303:   }
                    304:   y[1] = evalsigne(s)|evallgefint(ly);
                    305:   y[0] = evaltyp(t_INT)|evallg(ly); return y;
                    306: }
                    307:
                    308: GEN
                    309: mptrunc(GEN x)
                    310: {
                    311:   long d,e,i,s,m;
                    312:   GEN y;
                    313:
                    314:   if (typ(x)==t_INT) return icopy(x);
                    315:   if ((s=signe(x)) == 0 || (e=expo(x)) < 0) return gzero;
                    316:   d = (e>>TWOPOTBITS_IN_LONG) + 3;
                    317:   m = e & (BITS_IN_LONG-1);
                    318:   if (d > lg(x)) err(precer, "mptrunc (precision loss in truncation)");
                    319:
                    320:   y=cgeti(d); y[1] = evalsigne(s) | evallgefint(d);
                    321:   if (++m == BITS_IN_LONG)
                    322:     for (i=2; i<d; i++) y[i]=x[i];
                    323:   else
                    324:   {
                    325:     register const ulong sh = BITS_IN_LONG - m;
                    326:     shift_right2(y,x, 2,d,0, sh,m);
                    327:   }
                    328:   return y;
                    329: }
                    330:
                    331: /* integral part */
                    332: GEN
                    333: mpent(GEN x)
                    334: {
                    335:   long d,e,i,lx,m;
                    336:   GEN y;
                    337:
                    338:   if (typ(x)==t_INT) return icopy(x);
                    339:   if (signe(x) >= 0) return mptrunc(x);
                    340:   if ((e=expo(x)) < 0) return stoi(-1);
                    341:   d = (e>>TWOPOTBITS_IN_LONG) + 3;
                    342:   m = e & (BITS_IN_LONG-1);
                    343:   lx=lg(x); if (d>lx) err(precer, "mpent (precision loss in trucation)");
                    344:   y = new_chunk(d);
                    345:   if (++m == BITS_IN_LONG)
                    346:   {
                    347:     for (i=2; i<d; i++) y[i]=x[i];
                    348:     i=d; while (i<lx && !x[i]) i++;
                    349:     if (i==lx) goto END;
                    350:   }
                    351:   else
                    352:   {
                    353:     register const ulong sh = BITS_IN_LONG - m;
                    354:     shift_right2(y,x, 2,d,0, sh,m);
                    355:     if (x[d-1]<<m == 0)
                    356:     {
                    357:       i=d; while (i<lx && !x[i]) i++;
                    358:       if (i==lx) goto END;
                    359:     }
                    360:   }
                    361:   /* set y:=y+1 */
                    362:   for (i=d-1; i>=2; i--) { y[i]++; if (y[i]) goto END; }
                    363:   y=new_chunk(1); y[2]=1; d++;
                    364: END:
                    365:   y[1] = evalsigne(-1) | evallgefint(d);
                    366:   y[0] = evaltyp(t_INT) | evallg(d); return y;
                    367: }
                    368:
                    369: int
                    370: cmpsi(long x, GEN y)
                    371: {
                    372:   ulong p;
                    373:
                    374:   if (!x) return -signe(y);
                    375:
                    376:   if (x>0)
                    377:   {
                    378:     if (signe(y)<=0) return 1;
                    379:     if (lgefint(y)>3) return -1;
                    380:     p=y[2]; if (p == (ulong)x) return 0;
                    381:     return p < (ulong)x ? 1 : -1;
                    382:   }
                    383:
                    384:   if (signe(y)>=0) return -1;
                    385:   if (lgefint(y)>3) return 1;
                    386:   p=y[2]; if (p == (ulong)-x) return 0;
                    387:   return p < (ulong)(-x) ? -1 : 1;
                    388: }
                    389:
                    390: int
                    391: cmpii(GEN x, GEN y)
                    392: {
                    393:   const long sx = signe(x), sy = signe(y);
                    394:   long lx,ly,i;
                    395:
                    396:   if (sx<sy) return -1;
                    397:   if (sx>sy) return 1;
                    398:   if (!sx) return 0;
                    399:
                    400:   lx=lgefint(x); ly=lgefint(y);
                    401:   if (lx>ly) return sx;
                    402:   if (lx<ly) return -sx;
                    403:   i=2; while (i<lx && x[i]==y[i]) i++;
                    404:   if (i==lx) return 0;
                    405:   return ((ulong)x[i] > (ulong)y[i]) ? sx : -sx;
                    406: }
                    407:
                    408: int
                    409: cmprr(GEN x, GEN y)
                    410: {
                    411:   const long sx = signe(x), sy = signe(y);
                    412:   long ex,ey,lx,ly,lz,i;
                    413:
                    414:   if (sx<sy) return -1;
                    415:   if (sx>sy) return 1;
                    416:   if (!sx) return 0;
                    417:
                    418:   ex=expo(x); ey=expo(y);
                    419:   if (ex>ey) return sx;
                    420:   if (ex<ey) return -sx;
                    421:
                    422:   lx=lg(x); ly=lg(y); lz = (lx<ly)?lx:ly;
                    423:   i=2; while (i<lz && x[i]==y[i]) i++;
                    424:   if (i<lz) return ((ulong)x[i] > (ulong)y[i]) ? sx : -sx;
                    425:   if (lx>=ly)
                    426:   {
                    427:     while (i<lx && !x[i]) i++;
                    428:     return (i==lx) ? 0 : sx;
                    429:   }
                    430:   while (i<ly && !y[i]) i++;
                    431:   return (i==ly) ? 0 : -sx;
                    432: }
                    433:
                    434: GEN
                    435: addss(long x, long y)
                    436: {
                    437:   if (!x) return stoi(y);
                    438:   if (x>0) { pos_s[2] = x; return addsi(y,pos_s); }
                    439:   neg_s[2] = -x; return addsi(y,neg_s);
                    440: }
                    441:
                    442: GEN
                    443: addsi(long x, GEN y)
                    444: {
                    445:   long sx,sy,ly;
                    446:   GEN z;
                    447:
                    448:   if (!x) return icopy(y);
                    449:   sy=signe(y); if (!sy) return stoi(x);
                    450:   if (x<0) { sx=-1; x=-x; } else sx=1;
                    451:   if (sx==sy)
                    452:   {
                    453:     z = addsispec(x,y+2, lgefint(y)-2);
                    454:     setsigne(z,sy); return z;
                    455:   }
                    456:   ly=lgefint(y);
                    457:   if (ly==3)
                    458:   {
                    459:     const long d = y[2] - x;
                    460:     if (!d) return gzero;
                    461:     z=cgeti(3);
                    462:     if (y[2] < 0 || d > 0) {
                    463:       z[1] = evalsigne(sy) | evallgefint(3);
                    464:       z[2] = d;
                    465:     }
                    466:     else {
                    467:       z[1] = evalsigne(-sy) | evallgefint(3);
                    468:       z[2] =-d;
                    469:     }
                    470:     return z;
                    471:   }
                    472:   z = subisspec(y+2,x, ly-2);
                    473:   setsigne(z,sy); return z;
                    474: }
                    475:
                    476: GEN
                    477: addii(GEN x, GEN y)
                    478: {
                    479:   long sx = signe(x);
                    480:   long sy = signe(y);
                    481:   long lx,ly;
                    482:   GEN z;
                    483:
                    484:   if (!sx) return sy? icopy(y): gzero;
                    485:   if (!sy) return icopy(x);
                    486:   lx=lgefint(x); ly=lgefint(y);
                    487:
                    488:   if (sx==sy)
                    489:     z = addiispec(x+2,y+2,lx-2,ly-2);
                    490:   else
                    491:   { /* sx != sy */
                    492:     long i = lx - ly;
                    493:     if (i==0)
                    494:     {
                    495:       i = absi_cmp(x,y);
                    496:       if (!i) return gzero;
                    497:     }
                    498:     if (i<0) { sx=sy; swapspec(x,y, lx,ly); } /* ensure |x| >= |y| */
                    499:     z = subiispec(x+2,y+2,lx-2,ly-2);
                    500:   }
                    501:   setsigne(z,sx); return z;
                    502: }
                    503:
                    504: GEN
                    505: addsr(long x, GEN y)
                    506: {
                    507:   if (!x) return rcopy(y);
                    508:   if (x>0) { pos_s[2]=x; return addir(pos_s,y); }
                    509:   neg_s[2] = -x; return addir(neg_s,y);
                    510: }
                    511:
                    512: GEN
                    513: addir(GEN x, GEN y)
                    514: {
                    515:   long e,l,ly;
                    516:   GEN z;
                    517:
                    518:   if (!signe(x)) return rcopy(y);
                    519:   e = expo(y)-expi(x);
                    520:   if (!signe(y))
                    521:   {
                    522: #if 0
                    523:     if (e>0) err(adder3);
                    524: #else /* design issue: make 0.0 "absorbing" */
                    525:     if (e>0) return rcopy(y);
                    526: #endif
                    527:     z = cgetr(3 + ((-e)>>TWOPOTBITS_IN_LONG));
                    528:     affir(x,z); return z;
                    529:   }
                    530:
                    531:   ly=lg(y);
                    532:   if (e>0)
                    533:   {
                    534:     l = ly - (e>>TWOPOTBITS_IN_LONG);
                    535:     if (l<3) return rcopy(y);
                    536:   }
                    537:   else l = ly + ((-e)>>TWOPOTBITS_IN_LONG)+1;
                    538:   z=cgetr(l); affir(x,z); y=addrr(z,y);
                    539:   z = y+l; ly = lg(y); while (ly--) z[ly] = y[ly];
                    540:   avma=(long)z; return z;
                    541: }
                    542:
                    543: GEN
                    544: addrr(GEN x, GEN y)
                    545: {
                    546:   long sx=signe(x),sy=signe(y),ex=expo(x),ey=expo(y);
                    547:   long e,m,flag,i,j,f2,lx,ly,lz;
                    548:   GEN z;
                    549:   LOCAL_OVERFLOW;
                    550:
                    551:   e = ey-ex;
                    552:   if (!sy)
                    553:   {
                    554:     if (!sx)
                    555:     {
                    556:       if (e > 0) ex=ey;
                    557:       z=cgetr(3); z[1]=evalexpo(ex); z[2]=0; return z;
                    558:     }
                    559:     if (e > 0) { z=cgetr(3); z[1]=evalexpo(ey); z[2]=0; return z; }
                    560:     lz = 3 + ((-e)>>TWOPOTBITS_IN_LONG);
                    561:     lx = lg(x); if (lz>lx) lz=lx;
                    562:     z = cgetr(lz); while(--lz) z[lz]=x[lz];
                    563:     return z;
                    564:   }
                    565:   if (!sx)
                    566:   {
                    567:     if (e < 0) { z=cgetr(3); z[1]=evalexpo(ex); z[2]=0; return z; }
                    568:     lz = 3 + (e>>TWOPOTBITS_IN_LONG);
                    569:     ly = lg(y); if (lz>ly) lz=ly;
                    570:     z = cgetr(lz); while (--lz) z[lz]=y[lz];
                    571:     return z;
                    572:   }
                    573:
                    574:   if (e < 0) { z=x; x=y; y=z; ey=ex; i=sx; sx=sy; sy=i; e=-e; }
                    575:   /* now ey >= ex */
                    576:   lx=lg(x); ly=lg(y);
                    577:   if (e)
                    578:   {
                    579:     long d = e >> TWOPOTBITS_IN_LONG, l = ly-d;
                    580:     if (l > lx)     { flag=0; lz=lx+d+1; }
                    581:     else if (l > 2) { flag=1; lz=ly; lx=l; }
                    582:     else return rcopy(y);
                    583:     m = e & (BITS_IN_LONG-1);
                    584:   }
                    585:   else
                    586:   {
                    587:     if (lx > ly) lx = ly;
                    588:     flag=2; lz=lx; m=0;
                    589:   }
                    590:   z = cgetr(lz);
                    591:   if (m)
                    592:   { /* shift right x m bits */
                    593:     const ulong sh = BITS_IN_LONG-m;
                    594:     GEN p1 = x; x = new_chunk(lx+1);
                    595:     shift_right2(x,p1,2,lx, 0,m,sh);
                    596:     if (flag==0)
                    597:     {
                    598:       x[lx] = p1[lx-1] << sh;
                    599:       if (x[lx]) { flag = 3; lx++; }
                    600:     }
                    601:   }
                    602:
                    603:   if (sx==sy)
                    604:   { /* addition */
                    605:     i=lz-1; avma = (long)z;
                    606:     if (flag==0) { z[i] = y[i]; i--; }
                    607:     overflow=0;
                    608:     for (j=lx-1; j>=2; i--,j--) z[i] = addllx(x[j],y[i]);
                    609:
                    610:     if (overflow)
                    611:       for (;;)
                    612:       {
                    613:         if (i==1)
                    614:         {
                    615:           shift_right(z,z, 2,lz, 1,1);
                    616:           ey=evalexpo(ey+1);
                    617:           z[1] = evalsigne(sx) | ey; return z;
                    618:         }
                    619:         z[i] = y[i]+1; if (z[i--]) break;
                    620:       }
                    621:     for (; i>=2; i--) z[i]=y[i];
                    622:     z[1] = evalsigne(sx) | evalexpo(ey); return z;
                    623:   }
                    624:
                    625:   /* subtraction */
                    626:   if (e) f2 = 1;
                    627:   else
                    628:   {
                    629:     i=2; while (i<lx && x[i]==y[i]) i++;
                    630:     if (i==lx)
                    631:     {
                    632:       avma = (long)(z+lz);
                    633:       e = evalexpo(ey - bit_accuracy(lx));
                    634:       z=cgetr(3); z[1]=e; z[2]=0; return z;
                    635:     }
                    636:     f2 = ((ulong)y[i] > (ulong)x[i]);
                    637:   }
                    638:
                    639:   /* result is non-zero. f2 = (y > x) */
                    640:   i=lz-1;
                    641:   if (f2)
                    642:   {
                    643:     if (flag==0) { z[i] = y[i]; i--; }
                    644:     j=lx-1; z[i] = subll(y[i],x[j]); i--; j--;
                    645:     for (; j>=2; i--,j--) z[i] = subllx(y[i],x[j]);
                    646:     if (overflow)
                    647:       for (;;) { z[i] = y[i]-1; if (y[i--]) break; }
                    648:     for (; i>=2; i--) z[i]=y[i];
                    649:     sx = sy;
                    650:   }
                    651:   else
                    652:   {
                    653:     if (flag==0) { z[i] = -y[i]; i--; overflow=1; } else overflow=0;
                    654:     for (; i>=2; i--) z[i]=subllx(x[i],y[i]);
                    655:   }
                    656:
                    657:   x = z+2; i=0; while (!x[i]) i++;
                    658:   lz -= i; z += i; m = bfffo(z[2]);
                    659:   e = evalexpo(ey - (m | (i<<TWOPOTBITS_IN_LONG)));
                    660:   if (m) shift_left(z,z,2,lz-1, 0,m);
                    661:   z[1] = evalsigne(sx) | e;
                    662:   z[0] = evaltyp(t_REAL) | evallg(lz);
                    663:   avma = (long)z; return z;
                    664: }
                    665:
                    666: GEN
                    667: mulss(long x, long y)
                    668: {
                    669:   long s,p1;
                    670:   GEN z;
                    671:   LOCAL_HIREMAINDER;
                    672:
                    673:   if (!x || !y) return gzero;
                    674:   if (x<0) { s = -1; x = -x; } else s=1;
                    675:   if (y<0) { s = -s; y = -y; }
                    676:   p1 = mulll(x,y);
                    677:   if (hiremainder)
                    678:   {
                    679:     z=cgeti(4); z[1] = evalsigne(s) | evallgefint(4);
                    680:     z[2]=hiremainder; z[3]=p1; return z;
                    681:   }
                    682:   z=cgeti(3); z[1] = evalsigne(s) | evallgefint(3);
                    683:   z[2]=p1; return z;
                    684: }
                    685: #endif
                    686:
                    687: GEN
                    688: muluu(ulong x, ulong y)
                    689: {
                    690:   long p1;
                    691:   GEN z;
                    692:   LOCAL_HIREMAINDER;
                    693:
                    694:   if (!x || !y) return gzero;
                    695:   p1 = mulll(x,y);
                    696:   if (hiremainder)
                    697:   {
                    698:     z=cgeti(4); z[1] = evalsigne(1) | evallgefint(4);
                    699:     z[2]=hiremainder; z[3]=p1; return z;
                    700:   }
                    701:   z=cgeti(3); z[1] = evalsigne(1) | evallgefint(3);
                    702:   z[2]=p1; return z;
                    703: }
                    704:
                    705: /* assume ny > 0 */
                    706: #ifdef INLINE
                    707: INLINE
                    708: #endif
                    709: GEN
                    710: mulsispec(long x, GEN y, long ny)
                    711: {
                    712:   GEN yd, z = (GEN)avma;
                    713:   long lz = ny+3;
                    714:   LOCAL_HIREMAINDER;
                    715:
                    716:   (void)new_chunk(lz);
                    717:   yd = y + ny; *--z = mulll(x, *--yd);
                    718:   while (yd > y) *--z = addmul(x,*--yd);
                    719:   if (hiremainder) *--z = hiremainder; else lz--;
                    720:   *--z = evalsigne(1) | evallgefint(lz);
                    721:   *--z = evaltyp(t_INT) | evallg(lz);
                    722:   avma=(long)z; return z;
                    723: }
                    724:
                    725: GEN
                    726: mului(ulong x, GEN y)
                    727: {
                    728:   long s = signe(y);
                    729:   GEN z;
                    730:
                    731:   if (!s || !x) return gzero;
                    732:   z = mulsispec(x, y+2, lgefint(y)-2);
                    733:   setsigne(z,s); return z;
                    734: }
                    735:
                    736: /* a + b*Y, assume Y >= 0, 0 <= a,b <= VERYBIGINT */
                    737: GEN
                    738: addsmulsi(long a, long b, GEN Y)
                    739: {
                    740:   GEN yd,y,z;
                    741:   long ny,lz;
                    742:   LOCAL_HIREMAINDER;
                    743:   LOCAL_OVERFLOW;
                    744:
                    745:   if (!signe(Y)) return stoi(a);
                    746:
                    747:   y = Y+2; z = (GEN)avma;
                    748:   ny = lgefint(Y)-2;
                    749:   lz = ny+3;
                    750:
                    751:   (void)new_chunk(lz);
                    752:   yd = y + ny; *--z = addll(a, mulll(b, *--yd));
                    753:   if (overflow) hiremainder++; /* can't overflow */
                    754:   while (yd > y) *--z = addmul(b,*--yd);
                    755:   if (hiremainder) *--z = hiremainder; else lz--;
                    756:   *--z = evalsigne(1) | evallgefint(lz);
                    757:   *--z = evaltyp(t_INT) | evallg(lz);
                    758:   avma=(long)z; return z;
                    759: }
                    760:
                    761: #ifndef __M68K__
                    762:
                    763: GEN
                    764: mulsi(long x, GEN y)
                    765: {
                    766:   long s = signe(y);
                    767:   GEN z;
                    768:
                    769:   if (!s || !x) return gzero;
                    770:   if (x<0) { s = -s; x = -x; }
                    771:   z = mulsispec(x, y+2, lgefint(y)-2);
                    772:   setsigne(z,s); return z;
                    773: }
                    774:
                    775: GEN
                    776: mulsr(long x, GEN y)
                    777: {
                    778:   long lx,i,s,garde,e,sh,m;
                    779:   GEN z;
                    780:   LOCAL_HIREMAINDER;
                    781:
                    782:   if (!x) return gzero;
                    783:   s = signe(y);
                    784:   if (!s)
                    785:   {
                    786:     if (x<0) x = -x;
                    787:     e = y[1] + (BITS_IN_LONG-1)-bfffo(x);
                    788:     if (e & ~EXPOBITS) err(muler2);
                    789:     z=cgetr(3); z[1]=e; z[2]=0; return z;
                    790:   }
                    791:   if (x<0) { s = -s; x = -x; }
                    792:   if (x==1) { z=rcopy(y); setsigne(z,s); return z; }
                    793:
                    794:   lx = lg(y); e = expo(y);
                    795:   z=cgetr(lx); y--; garde=mulll(x,y[lx]);
                    796:   for (i=lx-1; i>=3; i--) z[i]=addmul(x,y[i]);
                    797:   z[2]=hiremainder;
                    798:
                    799:   sh = bfffo(hiremainder); m = BITS_IN_LONG-sh;
                    800:   if (sh) shift_left2(z,z, 2,lx-1, garde,sh,m);
                    801:   e = evalexpo(m+e);
                    802:   z[1] = evalsigne(s) | e; return z;
                    803: }
                    804:
                    805: GEN
                    806: mulrr(GEN x, GEN y)
                    807: {
                    808:   long sx = signe(x), sy = signe(y);
                    809:   long i,j,ly,lz,lzz,e,flag,p1;
                    810:   ulong garde;
                    811:   GEN z, y1;
                    812:   LOCAL_HIREMAINDER;
                    813:   LOCAL_OVERFLOW;
                    814:
                    815:   e = evalexpo(expo(x)+expo(y));
                    816:   if (!sx || !sy) { z=cgetr(3); z[1]=e; z[2]=0; return z; }
                    817:   if (sy<0) sx = -sx;
                    818:   lz=lg(x); ly=lg(y);
                    819:   if (lz>ly) { lz=ly; z=x; x=y; y=z; flag=1; } else flag = (lz!=ly);
                    820:   z=cgetr(lz); z[1] = evalsigne(sx) | e;
                    821:   if (lz==3)
                    822:   {
                    823:     if (flag)
                    824:     {
                    825:       (void)mulll(x[2],y[3]);
                    826:       garde = addmul(x[2],y[2]);
                    827:     }
                    828:     else
                    829:       garde = mulll(x[2],y[2]);
                    830:     if ((long)hiremainder<0) { z[2]=hiremainder; z[1]++; }
                    831:     else z[2]=(hiremainder<<1) | (garde>>(BITS_IN_LONG-1));
                    832:     return z;
                    833:   }
                    834:
                    835:   if (flag) { (void)mulll(x[2],y[lz]); garde = hiremainder; } else garde=0;
                    836:   lzz=lz-1; p1=x[lzz];
                    837:   if (p1)
                    838:   {
                    839:     (void)mulll(p1,y[3]);
                    840:     garde = addll(addmul(p1,y[2]), garde);
                    841:     z[lzz] = overflow+hiremainder;
                    842:   }
                    843:   else z[lzz]=0;
                    844:   for (j=lz-2, y1=y-j; j>=3; j--)
                    845:   {
                    846:     p1 = x[j]; y1++;
                    847:     if (p1)
                    848:     {
                    849:       (void)mulll(p1,y1[lz+1]);
                    850:       garde = addll(addmul(p1,y1[lz]), garde);
                    851:       for (i=lzz; i>j; i--)
                    852:       {
                    853:         hiremainder += overflow;
                    854:        z[i] = addll(addmul(p1,y1[i]), z[i]);
                    855:       }
                    856:       z[j] = hiremainder+overflow;
                    857:     }
                    858:     else z[j]=0;
                    859:   }
                    860:   p1=x[2]; y1++;
                    861:   garde = addll(mulll(p1,y1[lz]), garde);
                    862:   for (i=lzz; i>2; i--)
                    863:   {
                    864:     hiremainder += overflow;
                    865:     z[i] = addll(addmul(p1,y1[i]), z[i]);
                    866:   }
                    867:   z[2] = hiremainder+overflow;
                    868:   if (z[2] < 0) z[1]++;
                    869:   else
                    870:     shift_left(z,z,2,lzz,garde, 1);
                    871:   return z;
                    872: }
                    873:
                    874: GEN
                    875: mulir(GEN x, GEN y)
                    876: {
                    877:   long sx=signe(x),sy,lz,lzz,ey,e,p1,i,j;
                    878:   ulong garde;
                    879:   GEN z,y1;
                    880:   LOCAL_HIREMAINDER;
                    881:   LOCAL_OVERFLOW;
                    882:
                    883:   if (!sx) return gzero;
                    884:   if (!is_bigint(x)) return mulsr(itos(x),y);
                    885:   sy=signe(y); ey=expo(y);
                    886:   if (!sy)
                    887:   {
                    888:     e = evalexpo(expi(x)+ey);
                    889:     z=cgetr(3); z[1]=e; z[2]=0; return z;
                    890:   }
                    891:
                    892:   if (sy<0) sx = -sx;
                    893:   lz=lg(y); z=cgetr(lz);
                    894:   y1=cgetr(lz+1);
                    895:   affir(x,y1); x=y; y=y1;
                    896:   e = evalexpo(expo(y)+ey);
                    897:   z[1] = evalsigne(sx) | e;
                    898:   if (lz==3)
                    899:   {
                    900:     (void)mulll(x[2],y[3]);
                    901:     garde=addmul(x[2],y[2]);
                    902:     if ((long)hiremainder < 0) { z[2]=hiremainder; z[1]++; }
                    903:     else z[2]=(hiremainder<<1) | (garde>>(BITS_IN_LONG-1));
                    904:     avma=(long)z; return z;
                    905:   }
                    906:
                    907:   (void)mulll(x[2],y[lz]); garde=hiremainder;
                    908:   lzz=lz-1; p1=x[lzz];
                    909:   if (p1)
                    910:   {
                    911:     (void)mulll(p1,y[3]);
                    912:     garde=addll(addmul(p1,y[2]),garde);
                    913:     z[lzz] = overflow+hiremainder;
                    914:   }
                    915:   else z[lzz]=0;
                    916:   for (j=lz-2, y1=y-j; j>=3; j--)
                    917:   {
                    918:     p1=x[j]; y1++;
                    919:     if (p1)
                    920:     {
                    921:       (void)mulll(p1,y1[lz+1]);
                    922:       garde = addll(addmul(p1,y1[lz]), garde);
                    923:       for (i=lzz; i>j; i--)
                    924:       {
                    925:         hiremainder += overflow;
                    926:         z[i] = addll(addmul(p1,y1[i]), z[i]);
                    927:       }
                    928:       z[j] = hiremainder+overflow;
                    929:     }
                    930:     else z[j]=0;
                    931:   }
                    932:   p1=x[2]; y1++;
                    933:   garde = addll(mulll(p1,y1[lz]), garde);
                    934:   for (i=lzz; i>2; i--)
                    935:   {
                    936:     hiremainder += overflow;
                    937:     z[i] = addll(addmul(p1,y1[i]), z[i]);
                    938:   }
                    939:   z[2] = hiremainder+overflow;
                    940:   if (z[2] < 0) z[1]++;
                    941:   else
                    942:     shift_left(z,z,2,lzz,garde, 1);
                    943:   avma=(long)z; return z;
                    944: }
                    945:
                    946: /* written by Bruno Haible following an idea of Robert Harley */
                    947: long
                    948: vals(ulong z)
                    949: {
                    950:   static char tab[64]={-1,0,1,12,2,6,-1,13,3,-1,7,-1,-1,-1,-1,14,10,4,-1,-1,8,-1,-1,25,-1,-1,-1,-1,-1,21,27,15,31,11,5,-1,-1,-1,-1,-1,9,-1,-1,24,-1,-1,20,26,30,-1,-1,-1,-1,23,-1,19,29,-1,22,18,28,17,16,-1};
                    951: #ifdef LONG_IS_64BIT
                    952:   long s;
                    953: #endif
                    954:
                    955:   if (!z) return -1;
                    956: #ifdef LONG_IS_64BIT
                    957:   if (! (z&0xffffffff)) { s = 32; z >>=32; } else s = 0;
                    958: #endif
                    959:   z |= ~z + 1;
                    960:   z += z << 4;
                    961:   z += z << 6;
                    962:   z ^= z << 16; /* or  z -= z<<16 */
                    963: #ifdef LONG_IS_64BIT
                    964:   return s + tab[(z&0xffffffff)>>26];
                    965: #else
                    966:   return tab[z>>26];
                    967: #endif
                    968: }
                    969:
                    970: GEN
                    971: modss(long x, long y)
                    972: {
                    973:   LOCAL_HIREMAINDER;
                    974:
                    975:   if (!y) err(moder1);
                    976:   if (y<0) y=-y;
                    977:   hiremainder=0; divll(labs(x),y);
                    978:   if (!hiremainder) return gzero;
                    979:   return (x < 0) ? stoi(y-hiremainder) : stoi(hiremainder);
                    980: }
                    981:
                    982: GEN
                    983: resss(long x, long y)
                    984: {
                    985:   LOCAL_HIREMAINDER;
                    986:
                    987:   if (!y) err(reser1);
                    988:   hiremainder=0; divll(labs(x),labs(y));
                    989:   return (x < 0) ? stoi(-((long)hiremainder)) : stoi(hiremainder);
                    990: }
                    991:
                    992: GEN
                    993: divsi(long x, GEN y)
                    994: {
                    995:   long p1, s = signe(y);
                    996:   LOCAL_HIREMAINDER;
                    997:
                    998:   if (!s) err(diver2);
                    999:   if (!x || lgefint(y)>3 || ((long)y[2])<0)
                   1000:   {
                   1001:     hiremainder=x; SAVE_HIREMAINDER; return gzero;
                   1002:   }
                   1003:   hiremainder=0; p1=divll(labs(x),y[2]);
                   1004:   if (x<0) { hiremainder = -((long)hiremainder); p1 = -p1; }
                   1005:   if (s<0) p1 = -p1;
                   1006:   SAVE_HIREMAINDER; return stoi(p1);
                   1007: }
                   1008: #endif
                   1009:
                   1010: GEN
                   1011: modui(ulong x, GEN y)
                   1012: {
                   1013:   LOCAL_HIREMAINDER;
                   1014:
                   1015:   if (!signe(y)) err(diver2);
                   1016:   if (!x || lgefint(y)>3) hiremainder=x;
                   1017:   else
                   1018:   {
                   1019:     hiremainder=0; (void)divll(x,y[2]);
                   1020:   }
                   1021:   return utoi(hiremainder);
                   1022: }
                   1023:
                   1024: ulong
                   1025: umodiu(GEN y, ulong x)
                   1026: {
                   1027:   long sy=signe(y),ly,i;
                   1028:   LOCAL_HIREMAINDER;
                   1029:
                   1030:   if (!x) err(diver4);
                   1031:   if (!sy) return 0;
                   1032:   ly = lgefint(y);
                   1033:   if (x <= (ulong)y[2]) hiremainder=0;
                   1034:   else
                   1035:   {
                   1036:     if (ly==3) return (sy > 0)? (ulong)y[2]: x - (ulong)y[2];
                   1037:     hiremainder=y[2]; ly--; y++;
                   1038:   }
                   1039:   for (i=2; i<ly; i++) (void)divll(y[i],x);
                   1040:   if (!hiremainder) return 0;
                   1041:   return (sy > 0)? hiremainder: x - hiremainder;
                   1042: }
                   1043:
                   1044: GEN
                   1045: modiu(GEN y, ulong x) { return utoi(umodiu(y,x)); }
                   1046:
                   1047: #ifndef __M68K__
                   1048:
                   1049: GEN
                   1050: modsi(long x, GEN y)
                   1051: {
                   1052:   long s = signe(y);
                   1053:   GEN p1;
                   1054:   LOCAL_HIREMAINDER;
                   1055:
                   1056:   if (!s) err(diver2);
                   1057:   if (!x || lgefint(y)>3 || ((long)y[2])<0) hiremainder=x;
                   1058:   else
                   1059:   {
                   1060:     hiremainder=0; (void)divll(labs(x),y[2]);
                   1061:     if (x<0) hiremainder = -((long)hiremainder);
                   1062:   }
                   1063:   if (!hiremainder) return gzero;
                   1064:   if (x>0) return stoi(hiremainder);
                   1065:   if (s<0)
                   1066:     { setsigne(y,1); p1=addsi(hiremainder,y); setsigne(y,-1); }
                   1067:   else
                   1068:     p1=addsi(hiremainder,y);
                   1069:   return p1;
                   1070: }
                   1071:
                   1072: GEN
                   1073: divis(GEN y, long x)
                   1074: {
                   1075:   long sy=signe(y),ly,s,i;
                   1076:   GEN z;
                   1077:   LOCAL_HIREMAINDER;
                   1078:
                   1079:   if (!x) err(diver4);
                   1080:   if (!sy) { hiremainder=0; SAVE_HIREMAINDER; return gzero; }
                   1081:   if (x<0) { s = -sy; x = -x; } else s=sy;
                   1082:
                   1083:   ly = lgefint(y);
                   1084:   if ((ulong)x <= (ulong)y[2]) hiremainder=0;
                   1085:   else
                   1086:   {
                   1087:     if (ly==3) { hiremainder=itos(y); SAVE_HIREMAINDER; return gzero; }
                   1088:     hiremainder=y[2]; ly--; y++;
                   1089:   }
                   1090:   z = cgeti(ly); z[1] = evallgefint(ly) | evalsigne(s);
                   1091:   for (i=2; i<ly; i++) z[i]=divll(y[i],x);
                   1092:   if (sy<0) hiremainder = - ((long)hiremainder);
                   1093:   SAVE_HIREMAINDER; return z;
                   1094: }
                   1095:
                   1096: GEN
                   1097: divir(GEN x, GEN y)
                   1098: {
                   1099:   GEN xr,z;
                   1100:   long av,ly;
                   1101:
                   1102:   if (!signe(y)) err(diver5);
                   1103:   if (!signe(x)) return gzero;
                   1104:   ly=lg(y); z=cgetr(ly); av=avma; xr=cgetr(ly+1); affir(x,xr);
                   1105:   affrr(divrr(xr,y),z); avma=av; return z;
                   1106: }
                   1107:
                   1108: GEN
                   1109: divri(GEN x, GEN y)
                   1110: {
                   1111:   GEN yr,z;
                   1112:   long av,lx,s=signe(y);
                   1113:
                   1114:   if (!s) err(diver8);
                   1115:   if (!signe(x))
                   1116:   {
                   1117:     const long ex = evalexpo(expo(x) - expi(y));
                   1118:
                   1119:     if (ex<0) err(diver12);
                   1120:     z=cgetr(3); z[1]=ex; z[2]=0; return z;
                   1121:   }
                   1122:   if (!is_bigint(y)) return divrs(x, s>0? y[2]: -y[2]);
                   1123:
                   1124:   lx=lg(x); z=cgetr(lx);
                   1125:   av=avma; yr=cgetr(lx+1); affir(y,yr);
                   1126:   affrr(divrr(x,yr),z); avma=av; return z;
                   1127: }
                   1128:
                   1129: void
                   1130: diviiz(GEN x, GEN y, GEN z)
                   1131: {
                   1132:   long av=avma,lz;
                   1133:   GEN xr,yr;
                   1134:
                   1135:   if (typ(z)==t_INT) { affii(divii(x,y),z); avma=av; return; }
                   1136:   lz=lg(z); xr=cgetr(lz); affir(x,xr); yr=cgetr(lz); affir(y,yr);
                   1137:   affrr(divrr(xr,yr),z); avma=av;
                   1138: }
                   1139:
                   1140: void
                   1141: mpdivz(GEN x, GEN y, GEN z)
                   1142: {
                   1143:   long av=avma;
                   1144:
                   1145:   if (typ(z)==t_INT)
                   1146:   {
                   1147:     if (typ(x)==t_REAL || typ(y)==t_REAL) err(divzer1);
                   1148:     affii(divii(x,y),z); avma=av; return;
                   1149:   }
                   1150:   if (typ(x)==t_INT)
                   1151:   {
                   1152:     GEN xr,yr;
                   1153:     long lz;
                   1154:
                   1155:     if (typ(y)==t_REAL) { affrr(divir(x,y),z); avma=av; return; }
                   1156:     lz=lg(z); xr=cgetr(lz); affir(x,xr); yr=cgetr(lz); affir(y,yr);
                   1157:     affrr(divrr(xr,yr),z); avma=av; return;
                   1158:   }
                   1159:   if (typ(y)==t_REAL) { affrr(divrr(x,y),z); avma=av; return; }
                   1160:   affrr(divri(x,y),z); avma=av;
                   1161: }
                   1162:
                   1163: GEN
                   1164: divsr(long x, GEN y)
                   1165: {
                   1166:   long av,ly;
                   1167:   GEN p1,z;
                   1168:
                   1169:   if (!signe(y)) err(diver3);
                   1170:   if (!x) return gzero;
                   1171:   ly=lg(y); z=cgetr(ly); av=avma;
                   1172:   p1=cgetr(ly+1); affsr(x,p1); affrr(divrr(p1,y),z);
                   1173:   avma=av; return z;
                   1174: }
                   1175:
                   1176: GEN
                   1177: modii(GEN x, GEN y)
                   1178: {
                   1179:   switch(signe(x))
                   1180:   {
                   1181:     case 0: return gzero;
                   1182:     case 1: return resii(x,y);
                   1183:     default:
                   1184:     {
                   1185:       long av = avma;
                   1186:       (void)new_chunk(lgefint(y));
                   1187:       x = resii(x,y); avma=av;
                   1188:       if (x==gzero) return x;
                   1189:       return subiispec(y+2,x+2,lgefint(y)-2,lgefint(x)-2);
                   1190:     }
                   1191:   }
                   1192: }
                   1193:
                   1194: void
                   1195: modiiz(GEN x, GEN y, GEN z)
                   1196: {
                   1197:   const long av = avma;
                   1198:   affii(modii(x,y),z); avma=av;
                   1199: }
                   1200:
                   1201: GEN
                   1202: divrs(GEN x, long y)
                   1203: {
                   1204:   long i,lx,ex,garde,sh,s=signe(x);
                   1205:   GEN z;
                   1206:   LOCAL_HIREMAINDER;
                   1207:
                   1208:   if (!y) err(diver6);
                   1209:   if (!s)
                   1210:   {
                   1211:     z=cgetr(3); z[1] = x[1] - (BITS_IN_LONG-1) + bfffo(y);
                   1212:     if (z[1]<0) err(diver7);
                   1213:     z[2]=0; return z;
                   1214:   }
                   1215:   if (y<0) { s = -s; y = -y; }
                   1216:   if (y==1) { z=rcopy(x); setsigne(z,s); return z; }
                   1217:
                   1218:   z=cgetr(lx=lg(x)); hiremainder=0;
                   1219:   for (i=2; i<lx; i++) z[i]=divll(x[i],y);
                   1220:
                   1221:   /* we may have hiremainder != 0 ==> garde */
                   1222:   garde=divll(0,y); sh=bfffo(z[2]); ex=evalexpo(expo(x)-sh);
                   1223:   if (sh) shift_left(z,z, 2,lx-1, garde,sh);
                   1224:   z[1] = evalsigne(s) | ex;
                   1225:   return z;
                   1226: }
                   1227:
                   1228: GEN
                   1229: divrr(GEN x, GEN y)
                   1230: {
                   1231:   long sx=signe(x), sy=signe(y), lx,ly,lz,e,i,j;
                   1232:   ulong si,saux;
                   1233:   GEN z,x1;
                   1234:
                   1235:   if (!sy) err(diver9);
                   1236:   e = evalexpo(expo(x) - expo(y));
                   1237:   if (!sx) { z=cgetr(3); z[1]=e; z[2]=0; return z; }
                   1238:   if (sy<0) sx = -sx;
                   1239:   e = evalsigne(sx) | e;
                   1240:   lx=lg(x); ly=lg(y);
                   1241:   if (ly==3)
                   1242:   {
                   1243:     ulong k = x[2], l = (lx>3)? x[3]: 0;
                   1244:     LOCAL_HIREMAINDER;
                   1245:     if (k < (ulong)y[2]) e--;
                   1246:     else
                   1247:     {
                   1248:       l >>= 1; if (k&1) l |= HIGHBIT;
                   1249:       k >>= 1;
                   1250:     }
                   1251:     z=cgetr(3); z[1]=e;
                   1252:     hiremainder=k; z[2]=divll(l,y[2]); return z;
                   1253:   }
                   1254:
                   1255:   lz = (lx<=ly)? lx: ly;
                   1256:   x1 = (z=new_chunk(lz))-1;
                   1257:   x1[1]=0; for (i=2; i<lz; i++) x1[i]=x[i];
                   1258:   x1[lz] = (lx>lz)? x[lz]: 0;
                   1259:   x=z; si=y[2]; saux=y[3];
                   1260:   for (i=0; i<lz-1; i++)
                   1261:   { /* x1 = x + (i-1) */
                   1262:     ulong k,qp;
                   1263:     LOCAL_HIREMAINDER;
                   1264:     LOCAL_OVERFLOW;
                   1265:     if ((ulong)x1[1] == si)
                   1266:     {
                   1267:       qp = MAXULONG; k=addll(si,x1[2]);
                   1268:     }
                   1269:     else
                   1270:     {
                   1271:       if ((ulong)x1[1] > si) /* can't happen if i=0 */
                   1272:       {
                   1273:         GEN y1 = y+1;
                   1274:        overflow=0;
                   1275:        for (j=lz-i; j>0; j--) x1[j] = subllx(x1[j],y1[j]);
                   1276:        j=i; do x[--j]++; while (j && !x[j]);
                   1277:       }
                   1278:       hiremainder=x1[1]; overflow=0;
                   1279:       qp=divll(x1[2],si); k=hiremainder;
                   1280:     }
                   1281:     if (!overflow)
                   1282:     {
                   1283:       long k3 = subll(mulll(qp,saux), x1[3]);
                   1284:       long k4 = subllx(hiremainder,k);
                   1285:       while (!overflow && k4) { qp--; k3=subll(k3,saux); k4=subllx(k4,si); }
                   1286:     }
                   1287:     j = lz-i+1;
                   1288:     if (j<ly) (void)mulll(qp,y[j]); else { hiremainder=0 ; j=ly; }
                   1289:     for (j--; j>1; j--)
                   1290:     {
                   1291:       x1[j] = subll(x1[j], addmul(qp,y[j]));
                   1292:       hiremainder += overflow;
                   1293:     }
                   1294:     if ((ulong)x1[1] != hiremainder)
                   1295:     {
                   1296:       if ((ulong)x1[1] < hiremainder)
                   1297:       {
                   1298:         qp--;
                   1299:         overflow=0; for (j=lz-i; j>1; j--) x1[j]=addllx(x1[j], y[j]);
                   1300:       }
                   1301:       else
                   1302:       {
                   1303:        x1[1] -= hiremainder;
                   1304:        while (x1[1])
                   1305:        {
                   1306:          qp++; if (!qp) { j=i; do x[--j]++; while (j && !x[j]); }
                   1307:           overflow=0; for (j=lz-i; j>1; j--) x1[j]=subllx(x1[j],y[j]);
                   1308:          x1[1] -= overflow;
                   1309:        }
                   1310:       }
                   1311:     }
                   1312:     x1[1]=qp; x1++;
                   1313:   }
                   1314:   x1 = x-1; for (j=lz-1; j>=2; j--) x[j]=x1[j];
                   1315:   if (*x) { shift_right(x,x, 2,lz, 1,1); } else e--;
                   1316:   x[0]=evaltyp(t_REAL)|evallg(lz);
                   1317:   x[1]=e; return x;
                   1318: }
                   1319: #endif /* !defined(__M68K__) */
                   1320: /* The following ones are not in mp.s (mulii is, with a different algorithm) */
                   1321:
                   1322: /* Integer division x / y:
                   1323:  *   if z = ONLY_REM return remainder, otherwise return quotient
                   1324:  *   if z != NULL set *z to remainder
                   1325:  *   *z is the last object on stack (and thus can be disposed of with cgiv
                   1326:  *   instead of gerepile)
                   1327:  * If *z is zero, we put gzero here and no copy.
                   1328:  * space needed: lx + ly
                   1329:  */
                   1330: GEN
                   1331: dvmdii(GEN x, GEN y, GEN *z)
                   1332: {
                   1333:   long sx=signe(x),sy=signe(y);
                   1334:   long av,lx,ly,lz,i,j,sh,k,lq,lr;
                   1335:   ulong si,qp,saux, *xd,*rd,*qd;
                   1336:   GEN r,q,x1;
                   1337:
                   1338:   if (!sy) err(dvmer1);
                   1339:   if (!sx)
                   1340:   {
                   1341:     if (!z || z == ONLY_REM) return gzero;
                   1342:     *z=gzero; return gzero;
                   1343:   }
                   1344:   lx=lgefint(x);
                   1345:   ly=lgefint(y); lz=lx-ly;
                   1346:   if (lz <= 0)
                   1347:   {
                   1348:     if (lz == 0)
                   1349:     {
                   1350:       for (i=2; i<lx; i++)
                   1351:         if (x[i] != y[i])
                   1352:         {
                   1353:           if ((ulong)x[i] > (ulong)y[i]) goto DIVIDE;
                   1354:           goto TRIVIAL;
                   1355:         }
                   1356:       if (z == ONLY_REM) return gzero;
                   1357:       if (z) *z = gzero;
                   1358:       if (sx < 0) sy = -sy;
                   1359:       return stoi(sy);
                   1360:     }
                   1361: TRIVIAL:
                   1362:     if (z == ONLY_REM) return icopy(x);
                   1363:     if (z) *z = icopy(x);
                   1364:     return gzero;
                   1365:   }
                   1366: DIVIDE: /* quotient is non-zero */
                   1367:   av=avma; if (sx<0) sy = -sy;
                   1368:   if (ly==3)
                   1369:   {
                   1370:     LOCAL_HIREMAINDER;
                   1371:     si = y[2];
                   1372:     if (si <= (ulong)x[2]) hiremainder=0;
                   1373:     else
                   1374:     {
                   1375:       hiremainder = x[2]; lx--; x++;
                   1376:     }
                   1377:     q = new_chunk(lx); for (i=2; i<lx; i++) q[i]=divll(x[i],si);
                   1378:     if (z == ONLY_REM)
                   1379:     {
                   1380:       avma=av; if (!hiremainder) return gzero;
                   1381:       r=cgeti(3);
                   1382:       r[1] = evalsigne(sx) | evallgefint(3);
                   1383:       r[2]=hiremainder; return r;
                   1384:     }
                   1385:     q[1] = evalsigne(sy) | evallgefint(lx);
                   1386:     q[0] = evaltyp(t_INT) | evallg(lx);
                   1387:     if (!z) return q;
                   1388:     if (!hiremainder) { *z=gzero; return q; }
                   1389:     r=cgeti(3);
                   1390:     r[1] = evalsigne(sx) | evallgefint(3);
                   1391:     r[2] = hiremainder; *z=r; return q;
                   1392:   }
                   1393:
                   1394:   x1 = new_chunk(lx); sh = bfffo(y[2]);
                   1395:   if (sh)
                   1396:   { /* normalize so that highbit(y) = 1 (shift left x and y by sh bits)*/
                   1397:     register const ulong m = BITS_IN_LONG - sh;
                   1398:     r = new_chunk(ly);
                   1399:     shift_left2(r, y,2,ly-1, 0,sh,m); y = r;
                   1400:     shift_left2(x1,x,2,lx-1, 0,sh,m);
                   1401:     x1[1] = ((ulong)x[2]) >> m;
                   1402:   }
                   1403:   else
                   1404:   {
                   1405:     x1[1]=0; for (j=2; j<lx; j++) x1[j]=x[j];
                   1406:   }
                   1407:   x=x1; si=y[2]; saux=y[3];
                   1408:   for (i=0; i<=lz; i++)
                   1409:   { /* x1 = x + i */
                   1410:     LOCAL_HIREMAINDER;
                   1411:     LOCAL_OVERFLOW;
                   1412:     if ((ulong)x1[1] == si)
                   1413:     {
                   1414:       qp = MAXULONG; k=addll(si,x1[2]);
                   1415:     }
                   1416:     else
                   1417:     {
                   1418:       hiremainder=x1[1]; overflow=0;
                   1419:       qp=divll(x1[2],si); k=hiremainder;
                   1420:     }
                   1421:     if (!overflow)
                   1422:     {
                   1423:       long k3 = subll(mulll(qp,saux), x1[3]);
                   1424:       long k4 = subllx(hiremainder,k);
                   1425:       while (!overflow && k4) { qp--; k3=subll(k3,saux); k4=subllx(k4,si); }
                   1426:     }
                   1427:     hiremainder=0;
                   1428:     for (j=ly-1; j>1; j--)
                   1429:     {
                   1430:       x1[j] = subll(x1[j], addmul(qp,y[j]));
                   1431:       hiremainder+=overflow;
                   1432:     }
                   1433:     if ((ulong)x1[1] < hiremainder)
                   1434:     {
                   1435:       overflow=0; qp--;
                   1436:       for (j=ly-1; j>1; j--) x1[j] = addllx(x1[j],y[j]);
                   1437:     }
                   1438:     x1[1]=qp; x1++;
                   1439:   }
                   1440:
                   1441:   lq = lz+2;
                   1442:   if (!z)
                   1443:   {
                   1444:     qd = (ulong*)av;
                   1445:     xd = (ulong*)(x + lq);
                   1446:     if (x[1]) { lz++; lq++; }
                   1447:     while (lz--) *--qd = *--xd;
                   1448:     *--qd = evalsigne(sy) | evallgefint(lq);
                   1449:     *--qd = evaltyp(t_INT) | evallg(lq);
                   1450:     avma = (long)qd; return (GEN)qd;
                   1451:   }
                   1452:
                   1453:   j=lq; while (j<lx && !x[j]) j++;
                   1454:   lz = lx-j;
                   1455:   if (z == ONLY_REM)
                   1456:   {
                   1457:     if (lz==0) { avma = av; return gzero; }
                   1458:     rd = (ulong*)av; lr = lz+2;
                   1459:     xd = (ulong*)(x + lx);
                   1460:     if (!sh) while (lz--) *--rd = *--xd;
                   1461:     else
                   1462:     { /* shift remainder right by sh bits */
                   1463:       const ulong shl = BITS_IN_LONG - sh;
                   1464:       ulong l;
                   1465:       xd--;
                   1466:       while (--lz) /* fill r[3..] */
                   1467:       {
                   1468:         l = *xd >> sh;
                   1469:         *--rd = l | (*--xd << shl);
                   1470:       }
                   1471:       l = *xd >> sh;
                   1472:       if (l) *--rd = l; else lr--;
                   1473:     }
                   1474:     *--rd = evalsigne(sx) | evallgefint(lr);
                   1475:     *--rd = evaltyp(t_INT) | evallg(lr);
                   1476:     avma = (long)rd; return (GEN)rd;
                   1477:   }
                   1478:
                   1479:   lr = lz+2;
                   1480:   rd = NULL; /* gcc -Wall */
                   1481:   if (lz)
                   1482:   { /* non zero remainder: initialize rd */
                   1483:     xd = (ulong*)(x + lx);
                   1484:     if (!sh)
                   1485:     {
                   1486:       rd = (ulong*)avma; (void)new_chunk(lr);
                   1487:       while (lz--) *--rd = *--xd;
                   1488:     }
                   1489:     else
                   1490:     { /* shift remainder right by sh bits */
                   1491:       const ulong shl = BITS_IN_LONG - sh;
                   1492:       ulong l;
                   1493:       rd = (ulong*)x; /* overwrite shifted y */
                   1494:       xd--;
                   1495:       while (--lz)
                   1496:       {
                   1497:         l = *xd >> sh;
                   1498:         *--rd = l | (*--xd << shl);
                   1499:       }
                   1500:       l = *xd >> sh;
                   1501:       if (l) *--rd = l; else lr--;
                   1502:     }
                   1503:     *--rd = evalsigne(sx) | evallgefint(lr);
                   1504:     *--rd = evaltyp(t_INT) | evallg(lr);
                   1505:     rd += lr;
                   1506:   }
                   1507:   qd = (ulong*)av;
                   1508:   xd = (ulong*)(x + lq);
                   1509:   if (x[1]) lq++;
                   1510:   j = lq-2; while (j--) *--qd = *--xd;
                   1511:   *--qd = evalsigne(sy) | evallgefint(lq);
                   1512:   *--qd = evaltyp(t_INT) | evallg(lq);
                   1513:   q = (GEN)qd;
                   1514:   if (lr==2) *z = gzero;
                   1515:   else
                   1516:   { /* rd has been properly initialized: we had lz > 0 */
                   1517:     while (lr--) *--qd = *--rd;
                   1518:     *z = (GEN)qd;
                   1519:   }
                   1520:   avma = (long)qd; return q;
                   1521: }
                   1522:
                   1523: /* assume y > x > 0. return y mod x */
                   1524: ulong
                   1525: mppgcd_resiu(GEN y, ulong x)
                   1526: {
                   1527:   long i, ly = lgefint(y);
                   1528:   LOCAL_HIREMAINDER;
                   1529:
                   1530:   hiremainder = 0;
                   1531:   for (i=2; i<ly; i++) (void)divll(y[i],x);
                   1532:   return hiremainder;
                   1533: }
                   1534:
                   1535: /* Assume x>y>0, both of them odd. return x-y if x=y mod 4, x+y otherwise */
                   1536: void
                   1537: mppgcd_plus_minus(GEN x, GEN y, GEN res)
                   1538: {
                   1539:   long av = avma;
                   1540:   long lx = lgefint(x)-1;
                   1541:   long ly = lgefint(y)-1, lt,m,i;
                   1542:   GEN t;
                   1543:
                   1544:   if ((x[lx]^y[ly]) & 3) /* x != y mod 4*/
                   1545:     t = addiispec(x+2,y+2,lx-1,ly-1);
                   1546:   else
                   1547:     t = subiispec(x+2,y+2,lx-1,ly-1);
                   1548:
                   1549:   lt = lgefint(t)-1; while (!t[lt]) lt--;
                   1550:   m = vals(t[lt]); lt++;
                   1551:   if (m == 0) /* 2^32 | t */
                   1552:   {
                   1553:     for (i = 2; i < lt; i++) res[i] = t[i];
                   1554:   }
                   1555:   else if (t[2] >> m)
                   1556:   {
                   1557:     shift_right(res,t, 2,lt, 0,m);
                   1558:   }
                   1559:   else
                   1560:   {
                   1561:     lt--; t++;
                   1562:     shift_right(res,t, 2,lt, t[1],m);
                   1563:   }
                   1564:   res[1] = evalsigne(1)|evallgefint(lt);
                   1565:   avma = av;
                   1566: }
                   1567:
                   1568: /* private version of mulss */
                   1569: ulong
                   1570: smulss(ulong x, ulong y, ulong *rem)
                   1571: {
                   1572:   LOCAL_HIREMAINDER;
                   1573:   x=mulll(x,y); *rem=hiremainder; return x;
                   1574: }
                   1575:
                   1576: #ifdef LONG_IS_64BIT
                   1577: #  define DIVCONVI 7
                   1578: #else
                   1579: #  define DIVCONVI 14
                   1580: #endif
                   1581:
                   1582: /* convert integer --> base 10^9 [assume x > 0] */
                   1583: GEN
                   1584: convi(GEN x)
                   1585: {
                   1586:   ulong av=avma, lim;
                   1587:   long lz;
                   1588:   GEN z,p1;
                   1589:
                   1590:   lz = 3 + ((lgefint(x)-2)*15)/DIVCONVI;
                   1591:   z=new_chunk(lz); z[1] = -1; p1 = z+2;
                   1592:   lim = stack_lim(av,1);
                   1593:   for(;;)
                   1594:   {
                   1595:     x = divis(x,1000000000); *p1++ = hiremainder;
                   1596:     if (!signe(x)) { avma=av; return p1; }
                   1597:     if (low_stack(lim, stack_lim(av,1))) x = gerepileuptoint((long)z,x);
                   1598:   }
                   1599: }
                   1600: #undef DIVCONVI
                   1601:
                   1602: /* convert fractional part --> base 10^9 [assume expo(x) < 0] */
                   1603: GEN
                   1604: confrac(GEN x)
                   1605: {
                   1606:   long lx=lg(x), ex = -expo(x)-1, d,m,ly,ey,lr,i,j;
                   1607:   GEN y,y1;
                   1608:
                   1609:   ey = ex + bit_accuracy(lx);
                   1610:   ly = 1 + ((ey-1) >> TWOPOTBITS_IN_LONG);
                   1611:   d = ex >> TWOPOTBITS_IN_LONG;
                   1612:   m = ex & (BITS_IN_LONG-1);
                   1613:   y = new_chunk(ly); y1 = y + (d-2);
                   1614:   while (d--) y[d]=0;
                   1615:   if (!m)
                   1616:     for (i=2; i<lx; i++) y1[i] = x[i];
                   1617:   else
                   1618:   { /* shift x left sh bits */
                   1619:     const ulong sh=BITS_IN_LONG-m;
                   1620:     ulong k=0, l;
                   1621:     for (i=2; i<lx; i++)
                   1622:     {
                   1623:       l = x[i];
                   1624:       y1[i] = (l>>m)|k;
                   1625:       k = l<<sh;
                   1626:     }
                   1627:     y1[i] = k;
                   1628:   }
                   1629:   lr = 1 + ((long) (ey*L2SL10))/9;
                   1630:   y1 = new_chunk(lr);
                   1631:   for (j=0; j<lr; j++)
                   1632:   {
                   1633:     LOCAL_HIREMAINDER;
                   1634:     hiremainder=0;
                   1635:     for (i=ly-1; i>=0; i--) y[i]=addmul(y[i],1000000000);
                   1636:     y1[j]=hiremainder;
                   1637:   }
                   1638:   return y1;
                   1639: }
                   1640:
                   1641: GEN
                   1642: truedvmdii(GEN x, GEN y, GEN *z)
                   1643: {
                   1644:   long av = avma;
                   1645:   GEN r, q = dvmdii(x,y,&r); /* assume that r is last on stack */
                   1646:   GEN *gptr[2];
                   1647:
                   1648:   if (signe(r)>=0)
                   1649:   {
                   1650:     if (z == ONLY_REM) return gerepileuptoint(av,r);
                   1651:     if (z) *z = r; else cgiv(r);
                   1652:     return q;
                   1653:   }
                   1654:
                   1655:   if (z == ONLY_REM)
                   1656:   {
                   1657:     r = subiispec(y+2,r+2, lgefint(y)-2,lgefint(r)-2);
                   1658:     return gerepileuptoint(av, r);
                   1659:   }
                   1660:   q = addsi(-signe(y),q);
                   1661:   if (!z) return gerepileuptoint(av, q);
                   1662:
                   1663:   *z = subiispec(y+2,r+2, lgefint(y)-2,lgefint(r)-2);
                   1664:   gptr[0]=&q; gptr[1]=z; gerepilemanysp(av,(long)r,gptr,2);
                   1665:   return q;
                   1666: }
                   1667:
                   1668: /* EXACT INTEGER DIVISION */
                   1669:
                   1670: /* Find c such that 1=c*b mod 2^BITS_IN_LONG, assuming b odd (unchecked) */
                   1671: static ulong
                   1672: invrev(ulong b)
                   1673: {
                   1674:   ulong x;
                   1675:   switch(b & 7)
                   1676:   {
                   1677:     case 3:
                   1678:     case 5:  x = b+8; break;
                   1679:     default: x = b; break;
                   1680:   } /* x = b^(-1) mod 2^4 */
                   1681:   x = x*(2-b*x);
                   1682:   x = x*(2-b*x);
                   1683:   x = x*(2-b*x); /* b^(-1) mod 2^32 (Newton applied to 1/x - b = 0) */
                   1684: #ifdef LONG_IS_64BIT
                   1685:   x = x*(2-b*x); /* b^(-1) mod 2^64 */
                   1686: #endif
                   1687:   return x;
                   1688: }
                   1689:
                   1690: /* assume xy>0, y odd */
                   1691: GEN
                   1692: diviuexact(GEN x, ulong y)
                   1693: {
                   1694:   long i,lz,lx;
                   1695:   ulong q, yinv;
                   1696:   GEN z, z0, x0, x0min;
                   1697:
                   1698:   if (y == 1) return icopy(x);
                   1699:   lx = lgefint(x);
                   1700:   if (lx == 3) return stoi((ulong)x[2] / y);
                   1701:   yinv = invrev(y);
                   1702:   lz = (y <= (ulong)x[2]) ? lx : lx-1;
                   1703:   z = new_chunk(lz);
                   1704:   z0 = z + lz;
                   1705:   x0 = x + lx; x0min = x + lx-lz+2;
                   1706:
                   1707:   while (x0 > x0min)
                   1708:   {
                   1709:     *--z0 = q = yinv*((ulong)*--x0); /* i-th quotient */
                   1710:     if (!q) continue;
                   1711:     /* x := x - q * y */
                   1712:     { /* update neither lowest word (could set it to 0) nor highest ones */
                   1713:       register GEN x1 = x0 - 1;
                   1714:       LOCAL_HIREMAINDER;
                   1715:       (void)mulll(q,y);
                   1716:       if (hiremainder)
                   1717:       {
                   1718:         if ((ulong)*x1 < hiremainder)
                   1719:         {
                   1720:           *x1 -= hiremainder;
                   1721:           do (*--x1)--; while ((ulong)*x1 == MAXULONG);
                   1722:         }
                   1723:         else
                   1724:           *x1 -= hiremainder;
                   1725:       }
                   1726:     }
                   1727:   }
                   1728:   i=2; while(!z[i]) i++;
                   1729:   z += i-2; lz -= i-2;
                   1730:   z[0] = evaltyp(t_INT)|evallg(lz);
                   1731:   z[1] = evalsigne(1)|evallg(lz);
                   1732:   avma = (ulong)z; return z;
                   1733: }
                   1734:
                   1735: /* Find z such that x=y*z, knowing that y | x (unchecked)
                   1736:  * Method: y0 z0 = x0 mod B = 2^BITS_IN_LONG ==> z0 = 1/y0 mod B.
                   1737:  *    Set x := (x - z0 y) / B, updating only relevant words, and repeat */
                   1738: GEN
                   1739: diviiexact(GEN x, GEN y)
                   1740: {
                   1741:   long av,lx,ly,lz,vy,i,ii,sx = signe(x), sy = signe(y);
                   1742:   ulong y0inv,q;
                   1743:   GEN z;
                   1744:
                   1745:   if (!sy) err(dvmer1);
                   1746:   if (!sx) return gzero;
                   1747:   vy = vali(y); av = avma;
                   1748:   (void)new_chunk(lgefint(x)); /* enough room for z */
                   1749:   if (vy)
                   1750:   { /* make y odd */
                   1751: #if 0
                   1752:     if (vali(x) < vy) err(talker,"impossible division in diviiexact");
                   1753: #endif
                   1754:     y = shifti(y,-vy);
                   1755:     x = shifti(x,-vy);
                   1756:   }
                   1757:   else x = icopy(x); /* necessary because we destroy x */
                   1758:   avma = av; /* will erase our x,y when exiting */
                   1759:   /* now y is odd */
                   1760:   ly = lgefint(y);
                   1761:   if (ly == 3)
                   1762:   {
                   1763:     x = diviuexact(x,(ulong)y[2]);
                   1764:     if (signe(x)) setsigne(x,sx*sy); /* should have x != 0 at this point */
                   1765:     return x;
                   1766:   }
                   1767:   lx = lgefint(x); if (ly>lx) err(talker,"impossible division in diviiexact");
                   1768:   y0inv = invrev(y[ly-1]);
                   1769:   i=2; while (i<ly && y[i]==x[i]) i++;
                   1770:   lz = (i==ly || (ulong)y[i] < (ulong)x[i]) ? lx-ly+3 : lx-ly+2;
                   1771:   z = new_chunk(lz);
                   1772:
                   1773:   y += ly - 1; /* now y[-i] = i-th word of y */
                   1774:   for (ii=lx-1,i=lz-1; i>=2; i--,ii--)
                   1775:   {
                   1776:     long limj;
                   1777:     LOCAL_HIREMAINDER;
                   1778:     LOCAL_OVERFLOW;
                   1779:
                   1780:     z[i] = q = y0inv*((ulong)x[ii]); /* i-th quotient */
                   1781:     if (!q) continue;
                   1782:
                   1783:     /* x := x - q * y */
                   1784:     (void)mulll(q,y[0]); limj = max(lx - lz, ii+3-ly);
                   1785:     { /* update neither lowest word (could set it to 0) nor highest ones */
                   1786:       register GEN x0 = x + (ii - 1), y0 = y - 1, xlim = x + limj;
                   1787:       for (; x0 >= xlim; x0--, y0--)
                   1788:       {
                   1789:         *x0 = subll(*x0, addmul(q,*y0));
                   1790:         hiremainder += overflow;
                   1791:       }
                   1792:       if (hiremainder && limj != lx - lz)
                   1793:       {
                   1794:         if ((ulong)*x0 < hiremainder)
                   1795:         {
                   1796:           *x0 -= hiremainder;
                   1797:           do (*--x0)--; while ((ulong)*x0 == MAXULONG);
                   1798:         }
                   1799:         else
                   1800:           *x0 -= hiremainder;
                   1801:       }
                   1802:     }
                   1803:   }
                   1804: #if 0
                   1805:   i=2; while(i<lz && !z[i]) i++;
                   1806:   if (i==lz) err(bugparier,"diviiexact");
                   1807: #else
                   1808:   i=2; while(!z[i]) i++;
                   1809: #endif
                   1810:   z += i-2; lz -= (i-2);
                   1811:   z[0] = evaltyp(t_INT)|evallg(lz);
                   1812:   z[1] = evalsigne(sx*sy)|evallg(lz);
                   1813:   avma = (ulong)z; return z;
                   1814: }
                   1815:
                   1816: long
                   1817: smodsi(long x, GEN y)
                   1818: {
                   1819:   if (x<0) err(talker,"negative small integer in smodsi");
                   1820:   (void)divsi(x,y); return hiremainder;
                   1821: }
                   1822:
                   1823: /* x and y are integers. Return 1 if |x| == |y|, 0 otherwise */
                   1824: int
                   1825: absi_equal(GEN x, GEN y)
                   1826: {
                   1827:   long lx,i;
                   1828:
                   1829:   if (!signe(x)) return !signe(y);
                   1830:   if (!signe(y)) return 0;
                   1831:
                   1832:   lx=lgefint(x); if (lx != lgefint(y)) return 0;
                   1833:   i=2; while (i<lx && x[i]==y[i]) i++;
                   1834:   return (i==lx);
                   1835: }
                   1836:
                   1837: /* x and y are integers. Return sign(|x| - |y|) */
                   1838: int
                   1839: absi_cmp(GEN x, GEN y)
                   1840: {
                   1841:   long lx,ly,i;
                   1842:
                   1843:   if (!signe(x)) return signe(y)? -1: 0;
                   1844:   if (!signe(y)) return 1;
                   1845:
                   1846:   lx=lgefint(x); ly=lgefint(y);
                   1847:   if (lx>ly) return 1;
                   1848:   if (lx<ly) return -1;
                   1849:   i=2; while (i<lx && x[i]==y[i]) i++;
                   1850:   if (i==lx) return 0;
                   1851:   return ((ulong)x[i] > (ulong)y[i])? 1: -1;
                   1852: }
                   1853:
                   1854: /* x and y are reals. Return sign(|x| - |y|) */
                   1855: int
                   1856: absr_cmp(GEN x, GEN y)
                   1857: {
                   1858:   long ex,ey,lx,ly,lz,i;
                   1859:
                   1860:   if (!signe(x)) return signe(y)? -1: 0;
                   1861:   if (!signe(y)) return 1;
                   1862:
                   1863:   ex=expo(x); ey=expo(y);
                   1864:   if (ex>ey) return  1;
                   1865:   if (ex<ey) return -1;
                   1866:
                   1867:   lx=lg(x); ly=lg(y); lz = (lx<ly)?lx:ly;
                   1868:   i=2; while (i<lz && x[i]==y[i]) i++;
                   1869:   if (i<lz) return ((ulong)x[i] > (ulong)y[i])? 1: -1;
                   1870:   if (lx>=ly)
                   1871:   {
                   1872:     while (i<lx && !x[i]) i++;
                   1873:     return (i==lx)? 0: 1;
                   1874:   }
                   1875:   while (i<ly && !y[i]) i++;
                   1876:   return (i==ly)? 0: -1;
                   1877: }
                   1878:
                   1879: /********************************************************************/
                   1880: /**                                                                **/
                   1881: /**               INTEGER MULTIPLICATION (KARATSUBA)               **/
                   1882: /**                                                                **/
                   1883: /********************************************************************/
                   1884: #define _sqri_l 47
                   1885: #define _muli_l 25 /* optimal on PII 350MHz + gcc 2.7.2.1 (gp-dyn) */
                   1886:
                   1887: #if 0 /* for tunings */
                   1888: long KARATSUBA_SQRI_LIMIT = _sqri_l;
                   1889: long KARATSUBA_MULI_LIMIT = _muli_l;
                   1890:
                   1891: void setsqri(long a) { KARATSUBA_SQRI_LIMIT = a; }
                   1892: void setmuli(long a) { KARATSUBA_MULI_LIMIT = a; }
                   1893:
                   1894: GEN
                   1895: speci(GEN x, long nx)
                   1896: {
                   1897:   GEN z;
                   1898:   long i;
                   1899:   if (!nx) return gzero;
                   1900:   z = cgeti(nx+2); z[1] = evalsigne(1)|evallgefint(nx+2);
                   1901:   for (i=0; i<nx; i++) z[i+2] = x[i];
                   1902:   return z;
                   1903: }
                   1904: #else
                   1905: #  define KARATSUBA_SQRI_LIMIT _sqri_l
                   1906: #  define KARATSUBA_MULI_LIMIT _muli_l
                   1907: #endif
                   1908:
                   1909: /* nx >= ny = num. of digits of x, y (not GEN, see mulii) */
                   1910: #ifdef INLINE
                   1911: INLINE
                   1912: #endif
                   1913: GEN
                   1914: muliispec(GEN x, GEN y, long nx, long ny)
                   1915: {
                   1916:   GEN z2e,z2d,yd,xd,ye,zd;
                   1917:   long p1,lz;
                   1918:   LOCAL_HIREMAINDER;
                   1919:
                   1920:   if (!ny) return gzero;
                   1921:   zd = (GEN)avma; lz = nx+ny+2;
                   1922:   (void)new_chunk(lz);
                   1923:   xd = x + nx;
                   1924:   yd = y + ny;
                   1925:   ye = yd; p1 = *--xd;
                   1926:
                   1927:   *--zd = mulll(p1, *--yd); z2e = zd;
                   1928:   while (yd > y) *--zd = addmul(p1, *--yd);
                   1929:   *--zd = hiremainder;
                   1930:
                   1931:   while (xd > x)
                   1932:   {
                   1933:     LOCAL_OVERFLOW;
                   1934:     yd = ye; p1 = *--xd;
                   1935:
                   1936:     z2d = --z2e;
                   1937:     *z2d = addll(mulll(p1, *--yd), *z2d); z2d--;
                   1938:     while (yd > y)
                   1939:     {
                   1940:       hiremainder += overflow;
                   1941:       *z2d = addll(addmul(p1, *--yd), *z2d); z2d--;
                   1942:     }
                   1943:     *--zd = hiremainder + overflow;
                   1944:   }
                   1945:   if (*zd == 0) { zd++; lz--; } /* normalize */
                   1946:   *--zd = evalsigne(1) | evallgefint(lz);
                   1947:   *--zd = evaltyp(t_INT) | evallg(lz);
                   1948:   avma=(long)zd; return zd;
                   1949: }
                   1950:
                   1951: #ifdef INLINE
                   1952: INLINE
                   1953: #endif
                   1954: GEN
                   1955: sqrispec(GEN x, long nx)
                   1956: {
                   1957:   GEN z2e,z2d,yd,xd,zd,x0,z0;
                   1958:   long p1,lz;
                   1959:   LOCAL_HIREMAINDER;
                   1960:
                   1961:   if (!nx) return gzero;
                   1962:   zd = (GEN)avma; lz = (nx+1) << 1;
                   1963:   z0 = new_chunk(lz);
                   1964:   if (nx == 1)
                   1965:   {
                   1966:     *--zd = mulll(*x, *x);
                   1967:     *--zd = hiremainder; goto END;
                   1968:   }
                   1969:   xd = x + nx;
                   1970:
                   1971:   /* compute double products --> zd */
                   1972:   p1 = *--xd; yd = xd; --zd;
                   1973:   *--zd = mulll(p1, *--yd); z2e = zd;
                   1974:   while (yd > x) *--zd = addmul(p1, *--yd);
                   1975:   *--zd = hiremainder;
                   1976:
                   1977:   x0 = x+1;
                   1978:   while (xd > x0)
                   1979:   {
                   1980:     LOCAL_OVERFLOW;
                   1981:     p1 = *--xd; yd = xd;
                   1982:
                   1983:     z2e -= 2; z2d = z2e;
                   1984:     *z2d = addll(mulll(p1, *--yd), *z2d); z2d--;
                   1985:     while (yd > x)
                   1986:     {
                   1987:       hiremainder += overflow;
                   1988:       *z2d = addll(addmul(p1, *--yd), *z2d); z2d--;
                   1989:     }
                   1990:     *--zd = hiremainder + overflow;
                   1991:   }
                   1992:   /* multiply zd by 2 (put result in zd - 1) */
                   1993:   zd[-1] = ((*zd & HIGHBIT) != 0);
                   1994:   shift_left(zd, zd, 0, (nx<<1)-3, 0, 1);
                   1995:
                   1996:   /* add the squares */
                   1997:   xd = x + nx; zd = z0 + lz;
                   1998:   p1 = *--xd;
                   1999:   zd--; *zd = mulll(p1,p1);
                   2000:   zd--; *zd = addll(hiremainder, *zd);
                   2001:   while (xd > x)
                   2002:   {
                   2003:     p1 = *--xd;
                   2004:     zd--; *zd = addll(mulll(p1,p1)+ overflow, *zd);
                   2005:     zd--; *zd = addll(hiremainder + overflow, *zd);
                   2006:   }
                   2007:
                   2008: END:
                   2009:   if (*zd == 0) { zd++; lz--; } /* normalize */
                   2010:   *--zd = evalsigne(1) | evallgefint(lz);
                   2011:   *--zd = evaltyp(t_INT) | evallg(lz);
                   2012:   avma=(long)zd; return zd;
                   2013: }
                   2014:
                   2015: /* return (x shifted left d words) + y. Assume d > 0, x > 0 and y >= 0 */
                   2016: static GEN
                   2017: addshiftw(GEN x, GEN y, long d)
                   2018: {
                   2019:   GEN z,z0,y0,yd, zd = (GEN)avma;
                   2020:   long a,lz,ly = lgefint(y);
                   2021:
                   2022:   z0 = new_chunk(d);
                   2023:   a = ly-2; yd = y+ly;
                   2024:   if (a >= d)
                   2025:   {
                   2026:     y0 = yd-d; while (yd > y0) *--zd = *--yd; /* copy last d words of y */
                   2027:     a -= d;
                   2028:     if (a)
                   2029:       z = addiispec(x+2, y+2, lgefint(x)-2, a);
                   2030:     else
                   2031:       z = icopy(x);
                   2032:   }
                   2033:   else
                   2034:   {
                   2035:     y0 = yd-a; while (yd > y0) *--zd = *--yd; /* copy last a words of y */
                   2036:     while (zd >= z0) *--zd = 0;    /* complete with 0s */
                   2037:     z = icopy(x);
                   2038:   }
                   2039:   lz = lgefint(z)+d;
                   2040:   z[1] = evalsigne(1) | evallgefint(lz);
                   2041:   z[0] = evaltyp(t_INT) | evallg(lz); return z;
                   2042: }
                   2043:
                   2044: /* Fast product (Karatsuba) of integers. a and b are "special" GENs
                   2045:  * c,c0,c1,c2 are genuine GENs.
                   2046:  */
                   2047: static GEN
                   2048: quickmulii(GEN a, GEN b, long na, long nb)
                   2049: {
                   2050:   GEN a0,c,c0;
                   2051:   long av,n0,n0a,i;
                   2052:
                   2053:   if (na < nb) swapspec(a,b, na,nb);
                   2054:   if (nb == 1) return mulsispec(*b, a, na);
                   2055:   if (nb == 0) return gzero;
                   2056:   if (nb < KARATSUBA_MULI_LIMIT) return muliispec(a,b,na,nb);
                   2057:   i=(na>>1); n0=na-i; na=i;
                   2058:   av=avma; a0=a+na; n0a=n0;
                   2059:   while (!*a0 && n0a) { a0++; n0a--; }
                   2060:
                   2061:   if (n0a && nb > n0)
                   2062:   { /* nb <= na <= n0 */
                   2063:     GEN b0,c1,c2;
                   2064:     long n0b;
                   2065:
                   2066:     nb -= n0;
                   2067:     c = quickmulii(a,b,na,nb);
                   2068:     b0 = b+nb; n0b = n0;
                   2069:     while (!*b0 && n0b) { b0++; n0b--; }
                   2070:     if (n0b)
                   2071:     {
                   2072:       c0 = quickmulii(a0,b0, n0a,n0b);
                   2073:
                   2074:       c2 = addiispec(a0,a, n0a,na);
                   2075:       c1 = addiispec(b0,b, n0b,nb);
                   2076:       c1 = quickmulii(c1+2,c2+2, lgefint(c1)-2,lgefint(c2)-2);
                   2077:       c2 = addiispec(c0+2, c+2, lgefint(c0)-2,lgefint(c) -2);
                   2078:
                   2079:       c1 = subiispec(c1+2,c2+2, lgefint(c1)-2,lgefint(c2)-2);
                   2080:     }
                   2081:     else
                   2082:     {
                   2083:       c0 = gzero;
                   2084:       c1 = quickmulii(a0,b, n0a,nb);
                   2085:     }
                   2086:     c = addshiftw(c,c1, n0);
                   2087:   }
                   2088:   else
                   2089:   {
                   2090:     c = quickmulii(a,b,na,nb);
                   2091:     c0 = quickmulii(a0,b,n0a,nb);
                   2092:   }
                   2093:   return gerepileuptoint(av, addshiftw(c,c0, n0));
                   2094: }
                   2095:
                   2096: /* actual operations will take place on a+2 and b+2: we strip the codewords */
                   2097: GEN
                   2098: mulii(GEN a,GEN b)
                   2099: {
                   2100:   long sa,sb;
                   2101:   GEN z;
                   2102:
                   2103:   sa=signe(a); if (!sa) return gzero;
                   2104:   sb=signe(b); if (!sb) return gzero;
                   2105:   if (sb<0) sa = -sa;
                   2106:   z = quickmulii(a+2,b+2, lgefint(a)-2,lgefint(b)-2);
                   2107:   setsigne(z,sa); return z;
                   2108: }
                   2109:
                   2110: GEN
                   2111: resiimul(GEN x, GEN sy)
                   2112: {
                   2113:   GEN r, q, y = (GEN)sy[1], invy;
                   2114:   long av = avma, k;
                   2115:
                   2116:   k = cmpii(x, y);
                   2117:   if (k <= 0) return k? icopy(x): gzero;
                   2118:   invy = (GEN)sy[2];
                   2119:   q = mulir(x,invy);
                   2120:   q = mptrunc(q); /* <= divii(x, y) (at most 1 less) */
                   2121:   r = subii(x, mulii(y,q));
                   2122:   /* resii(x,y) + y >= r >= resii(x,y) */
                   2123:   k = cmpii(r, y);
                   2124:   if (k >= 0)
                   2125:   {
                   2126:     if (k == 0) { avma = av; return gzero; }
                   2127:     r = subiispec(r+2, y+2, lgefint(r)-2, lgefint(y)-2);
                   2128:   }
                   2129: #if 0
                   2130:   q = subii(r,resii(x,y));
                   2131:   if (signe(q))
                   2132:     err(talker,"bug in resiimul: x = %Z\ny = %Z\ndif = %Z", x,y,q);
                   2133: #endif
                   2134:   return gerepileuptoint(av, r); /* = resii(x, y) */
                   2135: }
                   2136:
                   2137: /* x % (2^n), assuming x, n >= 0 */
                   2138: GEN
                   2139: resmod2n(GEN x, long n)
                   2140: {
                   2141:   long hi,l,k,lx,ly;
                   2142:   GEN z, xd, zd;
                   2143:
                   2144:   if (!signe(x) || !n) return gzero;
                   2145:
                   2146:   l = n & (BITS_IN_LONG-1);    /* n % BITS_IN_LONG */
                   2147:   k = n >> TWOPOTBITS_IN_LONG; /* n / BITS_IN_LONG */
                   2148:   lx = lgefint(x);
                   2149:   if (lx < k+3) return icopy(x);
                   2150:
                   2151:   xd = x + (lx-k-1);
                   2152:   /* x = |_|...|#|1|...|k| : copy the last l bits of # and the last k words
                   2153:    *            ^--- initial xd  */
                   2154:   hi = *xd & ((1<<l) - 1); /* last l bits of # = top bits of result */
                   2155:   if (!hi)
                   2156:   { /* strip leading zeroes from result */
                   2157:     xd++; while (k && !*xd) { k--; xd++; }
                   2158:     if (!k) return gzero;
                   2159:     ly = k+2; xd--;
                   2160:   }
                   2161:   else
                   2162:     ly = k+3;
                   2163:
                   2164:   zd = z = cgeti(ly);
                   2165:   *++zd = evalsigne(1) | evallgefint(ly);
                   2166:   if (hi) *++zd = hi;
                   2167:   for ( ;k; k--) *++zd = *++xd;
                   2168:   return z;
                   2169: }
                   2170:
                   2171: static GEN
                   2172: quicksqri(GEN a, long na)
                   2173: {
                   2174:   GEN a0,c;
                   2175:   long av,n0,n0a,i;
                   2176:
                   2177:   if (na < KARATSUBA_SQRI_LIMIT) return sqrispec(a,na);
                   2178:   i=(na>>1); n0=na-i; na=i;
                   2179:   av=avma; a0=a+na; n0a=n0;
                   2180:   while (!*a0 && n0a) { a0++; n0a--; }
                   2181:   c = quicksqri(a,na);
                   2182:   if (n0a)
                   2183:   {
                   2184:     GEN t, c1, c0 = quicksqri(a0,n0a);
                   2185: #if 0
                   2186:     c1 = shifti(quickmulii(a0,a, n0a,na),1);
                   2187: #else /* slower !!! */
                   2188:     t = addiispec(a0,a,n0a,na);
                   2189:     t = quicksqri(t+2,lgefint(t)-2);
                   2190:     c1= addiispec(c0+2,c+2, lgefint(c0)-2, lgefint(c)-2);
                   2191:     c1= subiispec(t+2, c1+2, lgefint(t)-2, lgefint(c1)-2);
                   2192: #endif
                   2193:     c = addshiftw(c,c1, n0);
                   2194:     c = addshiftw(c,c0, n0);
                   2195:   }
                   2196:   else
                   2197:     c = addshiftw(c,gzero,n0<<1);
                   2198:   return gerepileuptoint(av, c);
                   2199: }
                   2200:
                   2201: GEN
                   2202: sqri(GEN a) { return quicksqri(a+2, lgefint(a)-2); }
                   2203:
                   2204: #define MULRR_LIMIT  32
                   2205: #define MULRR2_LIMIT 32
                   2206:
                   2207: #if 0
                   2208: GEN
                   2209: karamulrr1(GEN x, GEN y)
                   2210: {
                   2211:   long sx,sy;
                   2212:   long i,i1,i2,lx=lg(x),ly=lg(y),e,flag,garde;
                   2213:   long lz2,lz3,lz4;
                   2214:   GEN z,lo1,lo2,hi;
                   2215:
                   2216:   /* ensure that lg(y) >= lg(x) */
                   2217:   if (lx>ly) { lx=ly; z=x; x=y; y=z; flag=1; } else flag = (lx!=ly);
                   2218:   if (lx < MULRR_LIMIT) return mulrr(x,y);
                   2219:   sx=signe(x); sy=signe(y);
                   2220:   e = evalexpo(expo(x)+expo(y));
                   2221:   if (!sx || !sy) { z=cgetr(3); z[2]=0; z[1]=e; return z; }
                   2222:   if (sy<0) sx = -sx;
                   2223:   ly=lx+flag; z=cgetr(lx);
                   2224:   lz2 = (lx>>1); lz3 = lx-lz2;
                   2225:   x += 2; lx -= 2;
                   2226:   y += 2; ly -= 2;
                   2227:   hi = quickmulii(x,y,lz2,lz2);
                   2228:   i1=lz2; while (i1<lx && !x[i1]) i1++;
                   2229:   lo1 = quickmulii(y,x+i1,lz2,lx-i1);
                   2230:   i2=lz2; while (i2<ly && !y[i2]) i2++;
                   2231:   lo2 = quickmulii(x,y+i2,lz2,ly-i2);
                   2232:
                   2233:   if (signe(lo1))
                   2234:   {
                   2235:     if (flag) { lo2 = addshiftw(lo1,lo2,1); lz3++; } else lo2=addii(lo1,lo2);
                   2236:   }
                   2237:   lz4=lgefint(lo2)-lz3;
                   2238:   if (lz4>0) hi = addiispec(hi+2,lo2+2, lgefint(hi)-2,lz4);
                   2239:   if (hi[2] < 0)
                   2240:   {
                   2241:     e++; garde=hi[lx+2];
                   2242:     for (i=lx+1; i>=2 ; i--) z[i]=hi[i];
                   2243:   }
                   2244:   else
                   2245:   {
                   2246:     garde = (hi[lx+2] << 1);
                   2247:     shift_left(z,hi,2,lx+1, garde, 1);
                   2248:   }
                   2249:   z[1]=evalsigne(sx) | e;
                   2250:   if (garde < 0)
                   2251:   { /* round to nearest */
                   2252:     i=lx+2; do z[--i]++; while (z[i]==0);
                   2253:     if (i==1) z[2]=HIGHBIT;
                   2254:   }
                   2255:   avma=(long)z; return z;
                   2256: }
                   2257:
                   2258: GEN
                   2259: karamulrr2(GEN x, GEN y)
                   2260: {
                   2261:   long sx,sy,i,lx=lg(x),ly=lg(y),e,flag,garde;
                   2262:   GEN z,hi;
                   2263:
                   2264:   if (lx>ly) { lx=ly; z=x; x=y; y=z; flag=1; } else flag = (lx!=ly);
                   2265:   if (lx < MULRR2_LIMIT) return mulrr(x,y);
                   2266:   ly=lx+flag; sx=signe(x); sy=signe(y);
                   2267:   e = evalexpo(expo(x)+expo(y));
                   2268:   if (!sx || !sy) { z=cgetr(3); z[2]=0; z[1]=e; return z; }
                   2269:   if (sy<0) sx = -sx;
                   2270:   z=cgetr(lx);
                   2271:   hi=quickmulii(y+2,x+2,ly-2,lx-2);
                   2272:   if (hi[2] < 0)
                   2273:   {
                   2274:     e++; garde=hi[lx];
                   2275:     for (i=2; i<lx ; i++) z[i]=hi[i];
                   2276:   }
                   2277:   else
                   2278:   {
                   2279:     garde = (hi[lx] << 1);
                   2280:     shift_left(z,hi,2,lx-1, garde, 1);
                   2281:   }
                   2282:   z[1]=evalsigne(sx) | e;
                   2283:   if (garde < 0)
                   2284:   { /* round to nearest */
                   2285:     i=lx; do z[--i]++; while (z[i]==0);
                   2286:     if (i==1) z[2]=HIGHBIT;
                   2287:   }
                   2288:   avma=(long)z; return z;
                   2289: }
                   2290:
                   2291: GEN
                   2292: karamulrr(GEN x, GEN y, long flag)
                   2293: {
                   2294:   switch(flag)
                   2295:   {
                   2296:     case 1: return karamulrr1(x,y);
                   2297:     case 2: return karamulrr2(x,y);
                   2298:     default: err(flagerr,"karamulrr");
                   2299:   }
                   2300:   return NULL; /* not reached */
                   2301: }
                   2302:
                   2303: GEN
                   2304: karamulir(GEN x, GEN y, long flag)
                   2305: {
                   2306:   long sx=signe(x),lz,i;
                   2307:   GEN z,temp,z1;
                   2308:
                   2309:   if (!sx) return gzero;
                   2310:   lz=lg(y); z=cgetr(lz);
                   2311:   temp=cgetr(lz+1); affir(x,temp);
                   2312:   z1=karamulrr(temp,y,flag);
                   2313:   for (i=1; i<lz; i++) z[i]=z1[i];
                   2314:   avma=(long)z; return z;
                   2315: }
                   2316: #endif
                   2317:
                   2318: #ifdef LONG_IS_64BIT
                   2319:
                   2320: #if PARI_BYTE_ORDER == LITTLE_ENDIAN_64 || PARI_BYTE_ORDER == BIG_ENDIAN_64
                   2321: #else
                   2322:   error... unknown machine
                   2323: #endif
                   2324:
                   2325: GEN
                   2326: dbltor(double x)
                   2327: {
                   2328:   GEN z = cgetr(3);
                   2329:   long e;
                   2330:   union { double f; ulong i; } fi;
                   2331:   const int mant_len = 52;  /* mantissa bits (excl. hidden bit) */
                   2332:   const int exp_mid = 0x3ff;/* exponent bias */
                   2333:   const int expo_len = 11; /* number of bits of exponent */
                   2334:   LOCAL_HIREMAINDER;
                   2335:
                   2336:   if (x==0) { z[1]=evalexpo(-308); z[2]=0; return z; }
                   2337:   fi.f = x;
                   2338:   e = ((fi.i & (HIGHBIT-1)) >> mant_len) - exp_mid;
                   2339:   z[1] = evalexpo(e) | evalsigne(x<0? -1: 1);
                   2340:   z[2] = (fi.i << expo_len) | HIGHBIT;
                   2341:   return z;
                   2342: }
                   2343:
                   2344: double
                   2345: rtodbl(GEN x)
                   2346: {
                   2347:   long ex,s=signe(x);
                   2348:   ulong a;
                   2349:   union { double f; ulong i; } fi;
                   2350:   const int mant_len = 52;  /* mantissa bits (excl. hidden bit) */
                   2351:   const int exp_mid = 0x3ff;/* exponent bias */
                   2352:   const int expo_len = 11; /* number of bits of exponent */
                   2353:   LOCAL_HIREMAINDER;
                   2354:
                   2355:   if (typ(x)==t_INT && !s) return 0.0;
                   2356:   if (typ(x)!=t_REAL) err(typeer,"rtodbl");
                   2357:   if (!s || (ex=expo(x)) < - exp_mid) return 0.0;
                   2358:
                   2359:   /* start by rounding to closest */
                   2360:   a = (x[2] & (HIGHBIT-1)) + 0x400;
                   2361:   if (a & HIGHBIT) { ex++; a=0; }
                   2362:   if (ex >= exp_mid) err(rtodber);
                   2363:   fi.i = ((ex + exp_mid) << mant_len) | (a >> expo_len);
                   2364:   if (s<0) fi.i |= HIGHBIT;
                   2365:   return fi.f;
                   2366: }
                   2367:
                   2368: #else
                   2369:
                   2370: #if   PARI_BYTE_ORDER == LITTLE_ENDIAN
                   2371: #  define INDEX0 1
                   2372: #  define INDEX1 0
                   2373: #elif PARI_BYTE_ORDER == BIG_ENDIAN
                   2374: #  define INDEX0 0
                   2375: #  define INDEX1 1
                   2376: #else
                   2377:    error... unknown machine
                   2378: #endif
                   2379:
                   2380: GEN
                   2381: dbltor(double x)
                   2382: {
                   2383:   GEN z;
                   2384:   long e;
                   2385:   union { double f; ulong i[2]; } fi;
                   2386:   const int mant_len = 52;  /* mantissa bits (excl. hidden bit) */
                   2387:   const int exp_mid = 0x3ff;/* exponent bias */
                   2388:   const int shift = mant_len-32;
                   2389:   const int expo_len = 11; /* number of bits of exponent */
                   2390:
                   2391:   if (x==0) { z=cgetr(3); z[1]=evalexpo(-308); z[2]=0; return z; }
                   2392:   fi.f = x; z=cgetr(4);
                   2393:   {
                   2394:     const ulong a = fi.i[INDEX0];
                   2395:     const ulong b = fi.i[INDEX1];
                   2396:     e = ((a & (HIGHBIT-1)) >> shift) - exp_mid;
                   2397:     z[1] = evalexpo(e) | evalsigne(x<0? -1: 1);
                   2398:     z[3] = b << expo_len;
                   2399:     z[2] = HIGHBIT | b >> (BITS_IN_LONG-expo_len) | (a << expo_len);
                   2400:   }
                   2401:   return z;
                   2402: }
                   2403:
                   2404: double
                   2405: rtodbl(GEN x)
                   2406: {
                   2407:   long ex,s=signe(x),lx=lg(x);
                   2408:   ulong a,b,k;
                   2409:   union { double f; ulong i[2]; } fi;
                   2410:   const int mant_len = 52;  /* mantissa bits (excl. hidden bit) */
                   2411:   const int exp_mid = 0x3ff;/* exponent bias */
                   2412:   const int shift = mant_len-32;
                   2413:   const int expo_len = 11; /* number of bits of exponent */
                   2414:
                   2415:   if (typ(x)==t_INT && !s) return 0.0;
                   2416:   if (typ(x)!=t_REAL) err(typeer,"rtodbl");
                   2417:   if (!s || (ex=expo(x)) < - exp_mid) return 0.0;
                   2418:
                   2419:   /* start by rounding to closest */
                   2420:   a = x[2] & (HIGHBIT-1);
                   2421:   if (lx > 3)
                   2422:   {
                   2423:     b = x[3] + 0x400UL; if (b < 0x400UL) a++;
                   2424:     if (a & HIGHBIT) { ex++; a=0; }
                   2425:   }
                   2426:   else b = 0;
                   2427:   if (ex > exp_mid) err(rtodber);
                   2428:   ex += exp_mid;
                   2429:   k = (a >> expo_len) | (ex << shift);
                   2430:   if (s<0) k |= HIGHBIT;
                   2431:   fi.i[INDEX0] = k;
                   2432:   fi.i[INDEX1] = (a << (BITS_IN_LONG-expo_len)) | (b >> expo_len);
                   2433:   return fi.f;
                   2434: }
                   2435: #endif
                   2436:
                   2437: /* Old cgiv without reference count (which was not used anyway)
                   2438:  * Should be a macro.
                   2439:  */
                   2440: void
                   2441: cgiv(GEN x)
                   2442: {
                   2443:   if (x == (GEN) avma)
                   2444:     avma = (long) (x+lg(x));
                   2445: }
                   2446:
                   2447: /********************************************************************/
                   2448: /**                                                                **/
                   2449: /**               INTEGER EXTENDED GCD  (AND INVMOD)               **/
                   2450: /**                                                                **/
                   2451: /********************************************************************/
                   2452:
                   2453: /* GN 1998Oct25, originally developed in January 1998 under 2.0.4.alpha,
                   2454:  * in the context of trying to improve elliptic curve cryptosystem attacking
                   2455:  * algorithms.  2001Jan02 -- added bezout() functionality.
                   2456:  *
                   2457:  * Two basic ideas - (1) avoid many integer divisions, especially when the
                   2458:  * quotient is 1 (which happens more than 40% of the time).  (2) Use Lehmer's
                   2459:  * trick as modified by Jebelean of extracting a couple of words' worth of
                   2460:  * leading bits from both operands, and compute partial quotients from them
                   2461:  * as long as we can be sure of their values.  The Jebelean modifications
                   2462:  * consist in reliable inequalities from which we can decide fast whether
                   2463:  * to carry on or to return to the outer loop, and in re-shifting after the
                   2464:  * first word's worth of bits has been used up.  All of this is described
                   2465:  * in R. Lercier's these [pp148-153 & 163f.], except his outer loop isn't
                   2466:  * quite right  (the catch-up divisions needed when one partial quotient is
                   2467:  * larger than a word are missing).
                   2468:  *
                   2469:  * The API consists of invmod() and bezout() below;  the single-word routines
                   2470:  * xgcduu and xxgcduu may be called directly if desired;  lgcdii() probably
                   2471:  * doesn't make much sense out of context.
                   2472:  *
                   2473:  * The whole lot is a factor 6 .. 8 faster on word-sized operands, and asym-
                   2474:  * ptotically about a factor 2.5 .. 3, depending on processor architecture,
                   2475:  * than the naive continued-division code.  Unfortunately, thanks to the
                   2476:  * unrolled loops and all, the code is a bit lengthy.
                   2477:  */
                   2478:
                   2479: /*==================================
                   2480:  * xgcduu(d,d1,f,v,v1,s)
                   2481:  * xxgcduu(d,d1,f,u,u1,v,v1,s)
                   2482:  * rgcduu(d,d1,vmax,u,u1,v,v1,s)
                   2483:  *==================================*/
                   2484: /*
                   2485:  * Fast `final' extended gcd algorithm, acting on two ulongs.  Ideally this
                   2486:  * should be replaced with assembler versions wherever possible.  The present
                   2487:  * code essentially does `subtract, compare, and possibly divide' at each step,
                   2488:  * which is reasonable when hardware division (a) exists, (b) is a bit slowish
                   2489:  * and (c) does not depend a lot on the operand values (as on i486).  When
                   2490:  * wordsize division is in fact an assembler routine based on subtraction,
                   2491:  * this strategy may not be the most efficient one.
                   2492:  *
                   2493:  * xxgcduu() should be called with  d > d1 > 0, returns gcd(d,d1), and assigns
                   2494:  * the usual signless cont.frac. recurrence matrix to [u, u1; v, v1]  (i.e.,
                   2495:  * the product of all the [0, 1; 1 q_j] where the leftmost factor arises from
                   2496:  * the quotient of the first division step),  and the information about the
                   2497:  * implied signs to s  (-1 when an odd number of divisions has been done,
                   2498:  * 1 otherwise).  xgcduu() is exactly the same except that u,u1 are not com-
                   2499:  * puted (and not returned, of course).
                   2500:  *
                   2501:  * The input flag f should be set to 1 if we know in advance that gcd(d,d1)==1
                   2502:  * (so we can stop the chain division one step early:  as soon as the remainder
                   2503:  * equals 1).  Use this when you intend to use only what would be v, or only
                   2504:  * what would be u and v, after that final division step, but not u1 and v1.
                   2505:  * With the flag in force and thus without that final step, the interesting
                   2506:  * quantity/ies will still sit in [u1 and] v1, of course.
                   2507:  *
                   2508:  * For computing the inverse of a single-word INTMOD known to exist, pass f=1
                   2509:  * to xgcduu(), and obtain the result from s and v1.  (The routine does the
                   2510:  * right thing when d1==1 already.)  For finishing a multiword modinv known
                   2511:  * to exist, pass f=1 to xxgcduu(), and multiply the returned matrix  (with
                   2512:  * properly adjusted signs)  onto the values v' and v1' previously obtained
                   2513:  * from the multiword division steps.  Actually, just take the scalar product
                   2514:  * of [v',v1'] with [u1,-v1], and change the sign if s==-1.  (If the final
                   2515:  * step had been carried out, it would be [-u,v], and s would also change.)
                   2516:  * For reducing a rational number to lowest terms, pass f=0 to xgcduu().
                   2517:  * Finally, f=0 with xxgcduu() is useful for Bezout computations.
                   2518:  * [Harrumph.  In the above prescription, the sign turns out to be precisely
                   2519:  * wrong.]
                   2520:  * (It is safe for invmod() to call xgcduu() with f=1, because f&1 doesn't
                   2521:  * make a difference when gcd(d,d1)>1.  The speedup is negligible.)
                   2522:  *
                   2523:  * In principle, when gcd(d,d1) is known to be 1, it is straightforward to
                   2524:  * recover the final u,u1 given only v,v1 and s.  However, it probably isn't
                   2525:  * worthwhile, as it trades a few multiplications for a division.
                   2526:  *
                   2527:  * Note that these routines do not know and do not need to know about the
                   2528:  * PARI stack.
                   2529:  *
                   2530:  * Added 2001Jan15:
                   2531:  * rgcduu() is a variant of xxgcduu() which does not have f  (the effect is
                   2532:  * that of f=0),  but instead has a ulong vmax parameter, for use in rational
                   2533:  * reconstruction below.  It returns when v1 exceeds vmax;  v will never
                   2534:  * exceed vmax.  (vmax=0 is taken as a synonym of MAXULONG i.e. unlimited,
                   2535:  * in which case rgcduu behaves exactly like xxgcduu with f=0.)  The return
                   2536:  * value of rgcduu() is typically meaningless;  the interesting part is the
                   2537:  * matrix.
                   2538:  */
                   2539:
                   2540: ulong
                   2541: xgcduu(ulong d, ulong d1, int f, ulong* v, ulong* v1, long *s)
                   2542: {
                   2543:   ulong xv,xv1, xs, q,res;
                   2544:   LOCAL_HIREMAINDER;
                   2545:
                   2546:   /* The above blurb contained a lie.  The main loop always stops when d1
                   2547:    * has become equal to 1.  If (d1 == 1 && !(f&1)) after the loop, we do
                   2548:    * the final `division' of d by 1 `by hand' as it were.
                   2549:    *
                   2550:    * The loop has already been unrolled once.  Aggressive optimization could
                   2551:    * well lead to a totally unrolled assembler version...
                   2552:    *
                   2553:    * On modern x86 architectures, this loop is a pig anyway.  The division
                   2554:    * instruction always puts its result into the same pair of registers, and
                   2555:    * we always want to use one of them straight away, so pipeline performance
                   2556:    * will suck big time.  An assembler version should probably do a first loop
                   2557:    * computing and storing all the quotients -- their number is bounded in
                   2558:    * advance -- and then assembling the matrix in a second pass.  On other
                   2559:    * architectures where we can cycle through four or so groups of registers
                   2560:    * and exploit a fast ALU result-to-operand feedback path, this is much less
                   2561:    * of an issue.  (Intel sucks.  See http://www.x86.org/ ...)
                   2562:    */
                   2563:   xs = res = 0;
                   2564:   xv = 0UL; xv1 = 1UL;
                   2565:   while (d1 > 1UL)
                   2566:   {
                   2567:     d -= d1;                   /* no need to use subll */
                   2568:     if (d >= d1)
                   2569:     {
                   2570:       hiremainder = 0; q = 1 + divll(d,d1); d = hiremainder;
                   2571:       xv += q * xv1;
                   2572:     }
                   2573:     else
                   2574:       xv += xv1;
                   2575:                                /* possible loop exit */
                   2576:     if (d <= 1UL) { xs=1; break; }
                   2577:                                /* repeat with inverted roles */
                   2578:     d1 -= d;
                   2579:     if (d1 >= d)
                   2580:     {
                   2581:       hiremainder = 0; q = 1 + divll(d1,d); d1 = hiremainder;
                   2582:       xv1 += q * xv;
                   2583:     }
                   2584:     else
                   2585:       xv1 += xv;
                   2586:   } /* while */
                   2587:
                   2588:   if (!(f&1))                  /* division by 1 postprocessing if needed */
                   2589:   {
                   2590:     if (xs && d==1)
                   2591:     { xv1 += d1 * xv; xs = 0; res = 1UL; }
                   2592:     else if (!xs && d1==1)
                   2593:     { xv += d * xv1; xs = 1; res = 1UL; }
                   2594:   }
                   2595:
                   2596:   if (xs)
                   2597:   {
                   2598:     *s = -1; *v = xv1; *v1 = xv;
                   2599:     return (res ? res : (d==1 ? 1UL : d1));
                   2600:   }
                   2601:   else
                   2602:   {
                   2603:     *s = 1; *v = xv; *v1 = xv1;
                   2604:     return (res ? res : (d1==1 ? 1UL : d));
                   2605:   }
                   2606: }
                   2607:
                   2608:
                   2609: ulong
                   2610: xxgcduu(ulong d, ulong d1, int f,
                   2611:        ulong* u, ulong* u1, ulong* v, ulong* v1, long *s)
                   2612: {
                   2613:   ulong xu,xu1, xv,xv1, xs, q,res;
                   2614:   LOCAL_HIREMAINDER;
                   2615:
                   2616:   xs = res = 0;
                   2617:   xu = xv1 = 1UL;
                   2618:   xu1 = xv = 0UL;
                   2619:   while (d1 > 1UL)
                   2620:   {
                   2621:     d -= d1;                   /* no need to use subll */
                   2622:     if (d >= d1)
                   2623:     {
                   2624:       hiremainder = 0; q = 1 + divll(d,d1); d = hiremainder;
                   2625:       xv += q * xv1;
                   2626:       xu += q * xu1;
                   2627:     }
                   2628:     else
                   2629:     { xv += xv1; xu += xu1; }
                   2630:                                /* possible loop exit */
                   2631:     if (d <= 1UL) { xs=1; break; }
                   2632:                                /* repeat with inverted roles */
                   2633:     d1 -= d;
                   2634:     if (d1 >= d)
                   2635:     {
                   2636:       hiremainder = 0; q = 1 + divll(d1,d); d1 = hiremainder;
                   2637:       xv1 += q * xv;
                   2638:       xu1 += q * xu;
                   2639:     }
                   2640:     else
                   2641:     { xv1 += xv; xu1 += xu; }
                   2642:   } /* while */
                   2643:
                   2644:   if (!(f&1))                  /* division by 1 postprocessing if needed */
                   2645:   {
                   2646:     if (xs && d==1)
                   2647:     {
                   2648:       xv1 += d1 * xv;
                   2649:       xu1 += d1 * xu;
                   2650:       xs = 0; res = 1UL;
                   2651:     }
                   2652:     else if (!xs && d1==1)
                   2653:     {
                   2654:       xv += d * xv1;
                   2655:       xu += d * xu1;
                   2656:       xs = 1; res = 1UL;
                   2657:     }
                   2658:   }
                   2659:
                   2660:   if (xs)
                   2661:   {
                   2662:     *s = -1; *u = xu1; *u1 = xu; *v = xv1; *v1 = xv;
                   2663:     return (res ? res : (d==1 ? 1UL : d1));
                   2664:   }
                   2665:   else
                   2666:   {
                   2667:     *s = 1; *u = xu; *u1 = xu1; *v = xv; *v1 = xv1;
                   2668:     return (res ? res : (d1==1 ? 1UL : d));
                   2669:   }
                   2670: }
                   2671:
                   2672: ulong
                   2673: rgcduu(ulong d, ulong d1, ulong vmax,
                   2674:        ulong* u, ulong* u1, ulong* v, ulong* v1, long *s)
                   2675: {
                   2676:   ulong xu,xu1, xv,xv1, xs, q, res=0;
                   2677:   int f = 0;
                   2678:   LOCAL_HIREMAINDER;
                   2679:
                   2680:   if (vmax == 0) vmax = MAXULONG;
                   2681:   xs = res = 0;
                   2682:   xu = xv1 = 1UL;
                   2683:   xu1 = xv = 0UL;
                   2684:   while (d1 > 1UL)
                   2685:   {
                   2686:     d -= d1;                   /* no need to use subll */
                   2687:     if (d >= d1)
                   2688:     {
                   2689:       hiremainder = 0; q = 1 + divll(d,d1); d = hiremainder;
                   2690:       xv += q * xv1;
                   2691:       xu += q * xu1;
                   2692:     }
                   2693:     else
                   2694:     { xv += xv1; xu += xu1; }
                   2695:                                /* possible loop exit */
                   2696:     if (xv > vmax) { f=xs=1; break; }
                   2697:     if (d <= 1UL) { xs=1; break; }
                   2698:                                /* repeat with inverted roles */
                   2699:     d1 -= d;
                   2700:     if (d1 >= d)
                   2701:     {
                   2702:       hiremainder = 0; q = 1 + divll(d1,d); d1 = hiremainder;
                   2703:       xv1 += q * xv;
                   2704:       xu1 += q * xu;
                   2705:     }
                   2706:     else
                   2707:     { xv1 += xv; xu1 += xu; }
                   2708:                                /* possible loop exit */
                   2709:     if (xv1 > vmax) { f=1; break; }
                   2710:   } /* while */
                   2711:
                   2712:   if (!(f&1))                  /* division by 1 postprocessing if needed */
                   2713:   {
                   2714:     if (xs && d==1)
                   2715:     {
                   2716:       xv1 += d1 * xv;
                   2717:       xu1 += d1 * xu;
                   2718:       xs = 0; res = 1UL;
                   2719:     }
                   2720:     else if (!xs && d1==1)
                   2721:     {
                   2722:       xv += d * xv1;
                   2723:       xu += d * xu1;
                   2724:       xs = 1; res = 1UL;
                   2725:     }
                   2726:   }
                   2727:
                   2728:   if (xs)
                   2729:   {
                   2730:     *s = -1; *u = xu1; *u1 = xu; *v = xv1; *v1 = xv;
                   2731:     return (res ? res : (d==1 ? 1UL : d1));
                   2732:   }
                   2733:   else
                   2734:   {
                   2735:     *s = 1; *u = xu; *u1 = xu1; *v = xv; *v1 = xv1;
                   2736:     return (res ? res : (d1==1 ? 1UL : d));
                   2737:   }
                   2738: }
                   2739:
                   2740: /*==================================
                   2741:  * lgcdii(d,d1,u,u1,v,v1,vmax)
                   2742:  *==================================*/
                   2743: /* Lehmer's partial extended gcd algorithm, acting on two t_INT GENs.
                   2744:  *
                   2745:  * Tries to determine, using the leading 2*BITS_IN_LONG significant bits of d
                   2746:  * and a quantity of bits from d1 obtained by a shift of the same displacement,
                   2747:  * as many partial quotients of d/d1 as possible, and assigns to [u,u1;v,v1]
                   2748:  * the product of all the [0, 1; 1, q_j] thus obtained, where the leftmost
                   2749:  * factor arises from the quotient of the first division step.
                   2750:  *
                   2751:  * For use in rational reconstruction, input param vmax can be given a
                   2752:  * nonzero value.  In this case, we will return early as soon as v1 > vmax
                   2753:  * (i.e. it is guaranteed that v <= vmax). --2001Jan15
                   2754:  *
                   2755:  * MUST be called with  d > d1 > 0, and with  d  occupying more than one
                   2756:  * significant word  (if it doesn't, the caller has no business with us;
                   2757:  * he/she/it should use xgcduu() instead).  Returns the number of reduction/
                   2758:  * swap steps carried out, possibly zero, or under certain conditions minus
                   2759:  * that number.  When the return value is nonzero, the caller should use the
                   2760:  * returned recurrence matrix to update its own copies of d,d1.  When the
                   2761:  * return value is non-positive, and the latest remainder after updating
                   2762:  * turns out to be nonzero, the caller should at once attempt a full division,
                   2763:  * rather than first trying lgcdii() again -- this typically happens when we
                   2764:  * are about to encounter a quotient larger than half a word.  (This is not
                   2765:  * detected infallibly -- after a positive return value, it is perfectly
                   2766:  * possible that the next stage will end up needing a full division.  After
                   2767:  * a negative return value, however, this is certain, and should be acted
                   2768:  * upon.)
                   2769:  *
                   2770:  * (The sign information, for which xgcduu() has its return argument s, is now
                   2771:  * implicit in the LSB of our return value, and the caller may take advantage
                   2772:  * of the fact that a return value of +-1 implies u==0,u1==v==1  [only v1 pro-
                   2773:  * vides interesting information in this case].  One might also use the fact
                   2774:  * that if the return value is +-2, then u==1, but this is rather marginal.)
                   2775:  *
                   2776:  * If it was not possible to determine even the first quotient, either because
                   2777:  * we're too close to an integer quotient or because the quotient would be
                   2778:  * larger than one word  (if the `leading digit' of d1 after shifting is all
                   2779:  * zeros),  we return 0 and do not bother to assign anything to the last four
                   2780:  * args.
                   2781:  *
                   2782:  * The division chain might (sometimes) even run to completion.  It will be
                   2783:  * up to the caller to detect this case.
                   2784:  *
                   2785:  * This routine does _not_ change d or d1;  this will also be up to the caller.
                   2786:  *
                   2787:  * Note that this routine does not know and does not need to know about the
                   2788:  * PARI stack.
                   2789:  */
                   2790: /*#define DEBUG_LEHMER 1 */
                   2791: int
                   2792: lgcdii(ulong* d, ulong* d1,
                   2793:        ulong* u, ulong* u1, ulong* v, ulong* v1,
                   2794:        ulong vmax)
                   2795: {
                   2796:   /* Strategy:  (1) Extract/shift most significant bits.  We assume that d
                   2797:    * has at least two significant words, but we can cope with a one-word d1.
                   2798:    * Let dd,dd1 be the most significant dividend word and matching part of the
                   2799:    * divisor.
                   2800:    * (2) Check for overflow on the first division.  For our purposes, this
                   2801:    * happens when the upper half of dd1 is zero.  (Actually this is detected
                   2802:    * during extraction.)
                   2803:    * (3) Get a fix on the first quotient.  We compute q = floor(dd/dd1), which
                   2804:    * is an upper bound for floor(d/d1), and which gives the true value of the
                   2805:    * latter if (and-almost-only-if) the remainder dd' = dd-q*dd1 is >= q.
                   2806:    * (If it isn't, we give up.  This is annoying because the subsequent full
                   2807:    * division will repeat some work already done, but it happens very infre-
                   2808:    * quently.  Doing the extra-bit-fetch in this case would be awkward.)
                   2809:    * (4) Finish initializations.
                   2810:    *
                   2811:    * The remainder of the action is comparatively boring... The main loop has
                   2812:    * been unrolled once  (so we don't swap things and we can apply Jebelean's
                   2813:    * termination conditions which alternatingly take two different forms during
                   2814:    * successive iterations).  When we first run out of sufficient bits to form
                   2815:    * a quotient, and have an extra word of each operand, we pull out two whole
                   2816:    * word's worth of dividend bits, and divisor bits of matching significance;
                   2817:    * to these we apply our partial matrix (disregarding overflow because the
                   2818:    * result mod 2^(2*BITS_IN_LONG) will in fact give the correct values), and
                   2819:    * re-extract one word's worth of the current dividend and a matching amount
                   2820:    * of divisor bits.  The affair will normally terminate with matrix entries
                   2821:    * just short of a whole word.  (We terminate the inner loop before these can
                   2822:    * possibly overflow.)
                   2823:    */
                   2824:   ulong dd,dd1,ddlo,dd1lo, sh,shc;        /* `digits', shift count */
                   2825:   ulong xu,xu1, xv,xv1, q,res; /* recurrences, partial quotient, count */
                   2826:   ulong tmp0,tmp1,tmp2,tmpd,tmpu,tmpv; /* temps */
                   2827:   long ld, ld1, lz;            /* t_INT effective lengths */
                   2828:   int skip = 0;                        /* a boolean flag */
                   2829:   LOCAL_OVERFLOW;
                   2830:   LOCAL_HIREMAINDER;
                   2831:
                   2832: #ifdef DEBUG_LEHMER
                   2833:   voir(d, -1); voir(d1, -1);
                   2834: #endif
                   2835:   /* following is just for convenience: vmax==0 means no bound */
                   2836:   if (vmax == 0) vmax = MAXULONG;
                   2837:   ld = lgefint(d); ld1 = lgefint(d1); lz = ld - ld1; /* >= 0 */
                   2838:   if (lz > 1) return 0;                /* rare, quick and desperate exit */
                   2839:
                   2840:   d += 2; d1 += 2;             /* point at the leading `digits' */
                   2841:   dd1lo = 0;                   /* unless we find something better */
                   2842:   sh = bfffo(*d);              /* obtain dividend left shift count */
                   2843:
                   2844:   if (sh)
                   2845:   {                            /* do the shifting */
                   2846:     shc = BITS_IN_LONG - sh;
                   2847:     if (lz)
                   2848:     {                          /* dividend longer than divisor */
                   2849:       dd1 = (*d1 >> shc);
                   2850:       if (!(HIGHMASK & dd1)) return 0;  /* overflow detected */
                   2851:       if (ld1 > 3)
                   2852:         dd1lo = (*d1 << sh) + (d1[1] >> shc);
                   2853:       else
                   2854:         dd1lo = (*d1 << sh);
                   2855:     }
                   2856:     else
                   2857:     {                          /* dividend and divisor have the same length */
                   2858:       /* dd1 = shiftl(d1,sh) would have left hiremainder==0, and dd1 != 0. */
                   2859:       dd1 = (*d1 << sh);
                   2860:       if (!(HIGHMASK & dd1)) return 0;
                   2861:       if (ld1 > 3)
                   2862:       {
                   2863:         dd1 += (d1[1] >> shc);
                   2864:         if (ld1 > 4)
                   2865:           dd1lo = (d1[1] << sh) + (d1[2] >> shc);
                   2866:         else
                   2867:           dd1lo = (d1[1] << sh);
                   2868:       }
                   2869:     }
                   2870:     /* following lines assume d to have 2 or more significant words */
                   2871:     dd = (*d << sh) + (d[1] >> shc);
                   2872:     if (ld > 4)
                   2873:       ddlo = (d[1] << sh) + (d[2] >> shc);
                   2874:     else
                   2875:       ddlo = (d[1] << sh);
                   2876:   }
                   2877:   else
                   2878:   {                            /* no shift needed */
                   2879:     if (lz) return 0;          /* div'd longer than div'r: o'flow automatic */
                   2880:     dd1 = *d1;
                   2881:     if (!(HIGHMASK & dd1)) return 0;
                   2882:     if(ld1 > 3) dd1lo = d1[1];
                   2883:     /* assume again that d has another significant word */
                   2884:     dd = *d; ddlo = d[1];
                   2885:   }
                   2886: #ifdef DEBUG_LEHMER
                   2887:   fprintferr("  %lx:%lx, %lx:%lx\n", dd, ddlo, dd1, dd1lo);
                   2888: #endif
                   2889:
                   2890:   /* First subtraction/division stage.  (If a subtraction initially suffices,
                   2891:    * we don't divide at all.)  If a Jebelean condition is violated, and we
                   2892:    * can't fix it even by looking at the low-order bits in ddlo,dd1lo, we
                   2893:    * give up and ask for a full division.  Otherwise we commit the result,
                   2894:    * possibly deciding to re-shift immediately afterwards.
                   2895:    */
                   2896:   dd -= dd1;
                   2897:   if (dd < dd1)
                   2898:   {                            /* first quotient known to be == 1 */
                   2899:     xv1 = 1UL;
                   2900:     if (!dd)                   /* !(Jebelean condition), extraspecial case */
                   2901:     {                          /* note this can actually happen...  Now
                   2902:                                 * q==1 is known, but we underflow already.
                   2903:                                 * OTOH we've just shortened d by a whole word.
                   2904:                                 * Thus we feel pleased with ourselves and
                   2905:                                 * return.  (The re-shift code below would
                   2906:                                 * do so anyway.) */
                   2907:       *u = 0; *v = *u1 = *v1 = 1UL;
                   2908:       return -1;               /* Next step will be a full division. */
                   2909:     } /* if !(Jebelean) then */
                   2910:   }
                   2911:   else
                   2912:   {                            /* division indicated */
                   2913:     hiremainder = 0;
                   2914:     xv1 = 1 + divll(dd, dd1);  /* xv1: alternative spelling of `q', here ;) */
                   2915:     dd = hiremainder;
                   2916:     if (dd < xv1)              /* !(Jebelean cond'), non-extra special case */
                   2917:     {                          /* Attempt to complete the division using the
                   2918:                                 * less significant bits, before skipping right
                   2919:                                 * past the 1st loop to the reshift stage. */
                   2920:       ddlo = subll(ddlo, mulll(xv1, dd1lo));
                   2921:       dd = subllx(dd, hiremainder);
                   2922:
                   2923:       /* If we now have an overflow, q was _certainly_ too large.  Thanks to
                   2924:        * our decision not to get here unless the original dd1 had bits set in
                   2925:        * the upper half of the word, however, we now do know that the correct
                   2926:        * quotient is in fact q-1.  Adjust our data accordingly. */
                   2927:       if (overflow)
                   2928:       {
                   2929:        xv1--;
                   2930:        ddlo = addll(ddlo,dd1lo);
                   2931:        dd = addllx(dd,dd1);    /* overflows again which cancels the borrow */
                   2932:        /* ...and fall through to skip=1 below */
                   2933:       }
                   2934:       else
                   2935:       /* Test Jebelean condition anew, at this point using _all_ the extracted
                   2936:        * bits we have.  This is clutching at straws; we have a more or less
                   2937:        * even chance of succeeding this time.  Note that if we fail, we really
                   2938:        * do not know whether the correct quotient would have been q or some
                   2939:        * smaller value. */
                   2940:        if (!dd && ddlo < xv1) return 0;
                   2941:
                   2942:       /* Otherwise, we now know that q is correct, but we cannot go into the
                   2943:        * 1st loop.  Raise a flag so we'll remember to skip past the loop.
                   2944:        * Get here also after the q-1 adjustment case. */
                   2945:       skip = 1;
                   2946:     } /* if !(Jebelean) then */
                   2947:   }
                   2948:   res = 1;
                   2949: #ifdef DEBUG_LEHMER
                   2950:   fprintferr("  q = %ld, %lx, %lx\n", xv1, dd1, dd);
                   2951: #endif
                   2952:   if (xv1 > vmax)
                   2953:   {                            /* gone past the bound already */
                   2954:     *u = 0UL; *u1 = 1UL; *v = 1UL; *v1 = xv1;
                   2955:     return res;
                   2956:   }
                   2957:   xu = 0UL; xv = xu1 = 1UL;
                   2958:
                   2959:   /* Some invariants from here across the first loop:
                   2960:    *
                   2961:    * At this point, and again after we are finished with the first loop and
                   2962:    * subsequent conditional, a division and the associated update of the
                   2963:    * recurrence matrix have just been carried out completely.  The matrix
                   2964:    * xu,xu1;xv,xv1 has been initialized (or updated, possibly with permuted
                   2965:    * columns), and the current remainder == next divisor (dd at the moment)
                   2966:    * is nonzero (it might be zero here, but then skip will have been set).
                   2967:    *
                   2968:    * After the first loop, or when skip is set already, it will also be the
                   2969:    * case that there aren't sufficiently many bits to continue without re-
                   2970:    * shifting.  If the divisor after reshifting is zero, or indeed if it
                   2971:    * doesn't have more than half a word's worth of bits, we will have to
                   2972:    * return at that point.  Otherwise, we proceed into the second loop.
                   2973:    *
                   2974:    * Furthermore, when we reach the re-shift stage, dd:ddlo and dd1:dd1lo will
                   2975:    * already reflect the result of applying the current matrix to the old
                   2976:    * ddorig:ddlo and dd1orig:dd1lo.  (For the first iteration above, this
                   2977:    * was easy to achieve, and we didn't even need to peek into the (now
                   2978:    * no longer existent!) saved words.  After the loop, we'll stop for a
                   2979:    * moment to merge in the ddlo,dd1lo contributions.)
                   2980:    *
                   2981:    * Note that after the first division, even an a priori quotient of 1 cannot
                   2982:    * be trusted until we've checked Jebelean's condition -- it cannot be too
                   2983:    * large, of course, but it might be too small.
                   2984:    */
                   2985:
                   2986:   if (!skip)
                   2987:   {
                   2988:     for(;;)
                   2989:     {
                   2990:       /* First half of loop divides dd into dd1, and leaves the recurrence
                   2991:        * matrix xu,...,xv1 groomed the wrong way round (xu,xv will be the newer
                   2992:        * entries) when successful. */
                   2993:       tmpd = dd1 - dd;
                   2994:       if (tmpd < dd)
                   2995:       {                                /* quotient suspected to be 1 */
                   2996: #ifdef DEBUG_LEHMER
                   2997:        q = 1;
                   2998: #endif
                   2999:        tmpu = xu + xu1;        /* cannot overflow -- everything bounded by
                   3000:                                 * the original dd during first loop */
                   3001:        tmpv = xv + xv1;
                   3002:       }
                   3003:       else
                   3004:       {                                /* division indicated */
                   3005:        hiremainder = 0;
                   3006:        q = 1 + divll(tmpd, dd);
                   3007:        tmpd = hiremainder;
                   3008:        tmpu = xu + q*xu1;      /* can't overflow, but may need to be undone */
                   3009:        tmpv = xv + q*xv1;
                   3010:       }
                   3011:
                   3012:       tmp0 = addll(tmpv, xv1);
                   3013:       if ((tmpd < tmpu) || overflow ||
                   3014:          (dd - tmpd < tmp0))   /* !(Jebelean cond.) */
                   3015:        break;                  /* skip ahead to reshift stage */
                   3016:       else
                   3017:       {                                /* commit dd1, xu, xv */
                   3018:        res++;
                   3019:        dd1 = tmpd; xu = tmpu; xv = tmpv;
                   3020: #ifdef DEBUG_LEHMER
                   3021:        fprintferr("  q = %ld, %lx, %lx [%lu,%lu;%lu,%lu]\n",
                   3022:                   q, dd, dd1, xu1, xu, xv1, xv);
                   3023: #endif
                   3024:        if (xv > vmax)
                   3025:        {                       /* time to return */
                   3026:          *u = xu1; *u1 = xu; *v = xv1; *v1 = xv;
                   3027:          return res;
                   3028:        }
                   3029:       }
                   3030:
                   3031:       /* Second half of loop divides dd1 into dd, and the matrix returns to its
                   3032:        * normal arrangement. */
                   3033:       tmpd = dd - dd1;
                   3034:       if (tmpd < dd1)
                   3035:       {                                /* quotient suspected to be 1 */
                   3036: #ifdef DEBUG_LEHMER
                   3037:        q = 1;
                   3038: #endif
                   3039:        tmpu = xu1 + xu;        /* cannot overflow */
                   3040:        tmpv = xv1 + xv;
                   3041:       }
                   3042:       else
                   3043:       {                                /* division indicated */
                   3044:        hiremainder = 0;
                   3045:        q = 1 + divll(tmpd, dd1);
                   3046:        tmpd = hiremainder;
                   3047:        tmpu = xu1 + q*xu;
                   3048:        tmpv = xv1 + q*xv;
                   3049:       }
                   3050:
                   3051:       tmp0 = addll(tmpu, xu);
                   3052:       if ((tmpd < tmpv) || overflow ||
                   3053:          (dd1 - tmpd < tmp0))  /* !(Jebelean cond.) */
                   3054:        break;                  /* skip ahead to reshift stage */
                   3055:       else
                   3056:       {                                /* commit dd, xu1, xv1 */
                   3057:        res++;
                   3058:        dd = tmpd; xu1 = tmpu; xv1 = tmpv;
                   3059: #ifdef DEBUG_LEHMER
                   3060:        fprintferr("  q = %ld, %lx, %lx [%lu,%lu;%lu,%lu]\n",
                   3061:                q, dd1, dd, xu, xu1, xv, xv1);
                   3062: #endif
                   3063:        if (xv1 > vmax)
                   3064:        {                       /* time to return */
                   3065:          *u = xu; *u1 = xu1; *v = xv; *v1 = xv1;
                   3066:          return res;
                   3067:        }
                   3068:       }
                   3069:
                   3070:     } /* end of first loop */
                   3071:
                   3072:     /* Intermezzo: update dd:ddlo, dd1:dd1lo.  (But not if skip is set.) */
                   3073:
                   3074:     if (res&1)
                   3075:     {
                   3076:       /* after failed division in 1st half of loop:
                   3077:        * [dd1:dd1lo,dd:ddlo] = [ddorig:ddlo,dd1orig:dd1lo]
                   3078:        *                       * [ -xu, xu1 ; xv, -xv1 ]
                   3079:        * (Actually, we only multiply [ddlo,dd1lo] onto the matrix and
                   3080:        * add the high-order remainders + overflows onto [dd1,dd].)
                   3081:        */
                   3082:       tmp1 = mulll(ddlo, xu); tmp0 = hiremainder;
                   3083:       tmp1 = subll(mulll(dd1lo,xv), tmp1);
                   3084:       dd1 += subllx(hiremainder, tmp0);
                   3085:       tmp2 = mulll(ddlo, xu1); tmp0 = hiremainder;
                   3086:       ddlo = subll(tmp2, mulll(dd1lo,xv1));
                   3087:       dd += subllx(tmp0, hiremainder);
                   3088:       dd1lo = tmp1;
                   3089:     }
                   3090:     else
                   3091:     {
                   3092:       /* after failed division in 2nd half of loop:
                   3093:        * [dd:ddlo,dd1:dd1lo] = [ddorig:ddlo,dd1orig:dd1lo]
                   3094:        *                       * [ xu1, -xu ; -xv1, xv ]
                   3095:        * (Actually, we only multiply [ddlo,dd1lo] onto the matrix and
                   3096:        * add the high-order remainders + overflows onto [dd,dd1].)
                   3097:        */
                   3098:       tmp1 = mulll(ddlo, xu1); tmp0 = hiremainder;
                   3099:       tmp1 = subll(tmp1, mulll(dd1lo,xv1));
                   3100:       dd += subllx(tmp0, hiremainder);
                   3101:       tmp2 = mulll(ddlo, xu); tmp0 = hiremainder;
                   3102:       dd1lo = subll(mulll(dd1lo,xv), tmp2);
                   3103:       dd1 += subllx(hiremainder, tmp0);
                   3104:       ddlo = tmp1;
                   3105:     }
                   3106: #ifdef DEBUG_LEHMER
                   3107:     fprintferr("  %lx:%lx, %lx:%lx\n", dd, ddlo, dd1, dd1lo);
                   3108: #endif
                   3109:   } /* end of skip-pable section:  get here also, with res==1, when there
                   3110:      * was a problem immediately after the very first division. */
                   3111:
                   3112:   /* Re-shift.  Note:  the shift count _can_ be zero, viz. under the following
                   3113:    * precise conditions:  The original dd1 had its topmost bit set, so the 1st
                   3114:    * q was 1, and after subtraction, dd had its topmost bit unset.  If now
                   3115:    * dd==0, we'd have taken the return exit already, so we couldn't have got
                   3116:    * here.  If not, then it must have been the second division which has gone
                   3117:    * amiss  (because dd1 was very close to an exact multiple of the remainder
                   3118:    * dd value, so this will be very rare).  At this point, we'd have a fairly
                   3119:    * slim chance of fixing things by re-examining dd1:dd1lo vs. dd:ddlo, but
                   3120:    * this is not guaranteed to work.  Instead of trying, we return at once.
                   3121:    * The caller will see to it that the initial subtraction is re-done using
                   3122:    * _all_ the bits of both operands, which already helps, and the next round
                   3123:    * will either be a full division  (if dd occupied a halfword or less),  or
                   3124:    * another llgcdii() first step.  In the latter case, since we try a little
                   3125:    * harder during our first step, we may actually be able to fix the problem,
                   3126:    * and get here again with improved low-order bits and with another step
                   3127:    * under our belt.  Otherwise we'll have given up above and forced a full-
                   3128:    * blown division.
                   3129:    *
                   3130:    * If res is even, the shift count _cannot_ be zero.  (The first step forces
                   3131:    * a zero into the remainder's MSB, and all subsequent remainders will have
                   3132:    * inherited it.)
                   3133:    *
                   3134:    * The re-shift stage exits if the next divisor has at most half a word's
                   3135:    * worth of bits.
                   3136:    *
                   3137:    * For didactic reasons, the second loop will be arranged in the same way
                   3138:    * as the first -- beginning with the division of dd into dd1, as if res
                   3139:    * was odd.  To cater for this, if res is actually even, we swap things
                   3140:    * around during reshifting.  (During the second loop, the parity of res
                   3141:    * does not matter;  we know in which half of the loop we are when we decide
                   3142:    * to return.)
                   3143:    */
                   3144: #ifdef DEBUG_LEHMER
                   3145:   fprintferr("(sh)");
                   3146: #endif
                   3147:
                   3148:   if (res&1)
                   3149:   {                            /* after odd number of division(s) */
                   3150:     if (dd1 && (sh = bfffo(dd1)))
                   3151:     {
                   3152:       shc = BITS_IN_LONG - sh;
                   3153:       dd = (ddlo >> shc) + (dd << sh);
                   3154:       if (!(HIGHMASK & dd))
                   3155:       {
                   3156:        *u = xu; *u1 = xu1; *v = xv; *v1 = xv1;
                   3157:        return -res;            /* full division asked for */
                   3158:       }
                   3159:       dd1 = (dd1lo >> shc) + (dd1 << sh);
                   3160:     }
                   3161:     else
                   3162:     {                          /* time to return: <= 1 word left, or sh==0 */
                   3163:       *u = xu; *u1 = xu1; *v = xv; *v1 = xv1;
                   3164:       return res;
                   3165:     }
                   3166:   }
                   3167:   else
                   3168:   {                            /* after even number of divisions */
                   3169:     if (dd)
                   3170:     {
                   3171:       sh = bfffo(dd);          /* Known to be positive. */
                   3172:       shc = BITS_IN_LONG - sh;
                   3173:                                /* dd:ddlo will become the new dd1, and v.v. */
                   3174:       tmpd = (ddlo >> shc) + (dd << sh);
                   3175:       dd = (dd1lo >> shc) + (dd1 << sh);
                   3176:       dd1 = tmpd;
                   3177:       /* This has completed the swap;  now dd is again the current divisor.
                   3178:        * The following test originally inspected dd1 -- a most subtle and
                   3179:        * most annoying bug. The Management. */
                   3180:       if (HIGHMASK & dd)
                   3181:       {
                   3182:        /* recurrence matrix is the wrong way round;  swap it. */
                   3183:        tmp0 = xu; xu = xu1; xu1 = tmp0;
                   3184:        tmp0 = xv; xv = xv1; xv1 = tmp0;
                   3185:       }
                   3186:       else
                   3187:       {
                   3188:        /* recurrence matrix is the wrong way round;  fix this. */
                   3189:        *u = xu1; *u1 = xu; *v = xv1; *v1 = xv;
                   3190:        return -res;            /* full division asked for */
                   3191:       }
                   3192:     }
                   3193:     else
                   3194:     {                          /* time to return: <= 1 word left */
                   3195:       *u = xu1; *u1 = xu; *v = xv1; *v1 = xv;
                   3196:       return res;
                   3197:     }
                   3198:   } /* end reshift */
                   3199:
                   3200: #ifdef DEBUG_LEHMER
                   3201:   fprintferr("  %lx:%lx, %lx:%lx\n", dd, ddlo, dd1, dd1lo);
                   3202: #endif
                   3203:
                   3204:   /* The Second Loop.  Rip-off of the first, but we now check for overflow
                   3205:    * in the recurrences.  Returns instead of breaking when we cannot fix the
                   3206:    * quotient any longer.
                   3207:    */
                   3208:
                   3209:   for(;;)
                   3210:   {
                   3211:     /* First half of loop divides dd into dd1, and leaves the recurrence
                   3212:      * matrix xu,...,xv1 groomed the wrong way round (xu,xv will be the newer
                   3213:      * entries) when successful. */
                   3214:     tmpd = dd1 - dd;
                   3215:     if (tmpd < dd)
                   3216:     {                          /* quotient suspected to be 1 */
                   3217: #ifdef DEBUG_LEHMER
                   3218:       q = 1;
                   3219: #endif
                   3220:       tmpu = xu + xu1;
                   3221:       tmpv = addll(xv, xv1);   /* xv,xv1 will overflow first */
                   3222:       tmp1 = overflow;
                   3223:     }
                   3224:     else
                   3225:     {                          /* division indicated */
                   3226:       hiremainder = 0;
                   3227:       q = 1 + divll(tmpd, dd);
                   3228:       tmpd = hiremainder;
                   3229:       tmpu = xu + q*xu1;
                   3230:       tmpv = addll(xv, mulll(q,xv1));
                   3231:       tmp1 = overflow | hiremainder;
                   3232:     }
                   3233:
                   3234:     tmp0 = addll(tmpv, xv1);
                   3235:     if ((tmpd < tmpu) || overflow || tmp1 ||
                   3236:        (dd - tmpd < tmp0))     /* !(Jebelean cond.) */
                   3237:     {
                   3238:       /* The recurrence matrix has not yet been warped... */
                   3239:       *u = xu; *u1 = xu1; *v = xv; *v1 = xv1;
                   3240:       break;
                   3241:     }
                   3242:     /* commit dd1, xu, xv */
                   3243:     res++;
                   3244:     dd1 = tmpd; xu = tmpu; xv = tmpv;
                   3245: #ifdef DEBUG_LEHMER
                   3246:     fprintferr("  q = %ld, %lx, %lx\n", q, dd, dd1);
                   3247: #endif
                   3248:     if (xv > vmax)
                   3249:     {                          /* time to return */
                   3250:       *u = xu1; *u1 = xu; *v = xv1; *v1 = xv;
                   3251:       return res;
                   3252:     }
                   3253:
                   3254:     /* Second half of loop divides dd1 into dd, and the matrix returns to its
                   3255:      * normal arrangement. */
                   3256:     tmpd = dd - dd1;
                   3257:     if (tmpd < dd1)
                   3258:     {                          /* quotient suspected to be 1 */
                   3259: #ifdef DEBUG_LEHMER
                   3260:       q = 1;
                   3261: #endif
                   3262:       tmpu = xu1 + xu;
                   3263:       tmpv = addll(xv1, xv);
                   3264:       tmp1 = overflow;
                   3265:     }
                   3266:     else
                   3267:     {                          /* division indicated */
                   3268:       hiremainder = 0;
                   3269:       q = 1 + divll(tmpd, dd1);
                   3270:       tmpd = hiremainder;
                   3271:       tmpu = xu1 + q*xu;
                   3272:       tmpv = addll(xv1, mulll(q, xv));
                   3273:       tmp1 = overflow | hiremainder;
                   3274:     }
                   3275:
                   3276:     tmp0 = addll(tmpu, xu);
                   3277:     if ((tmpd < tmpv) || overflow || tmp1 ||
                   3278:        (dd1 - tmpd < tmp0))    /* !(Jebelean cond.) */
                   3279:     {
                   3280:       /* The recurrence matrix has not yet been unwarped, so it is
                   3281:        * the wrong way round;  fix this. */
                   3282:       *u = xu1; *u1 = xu; *v = xv1; *v1 = xv;
                   3283:       break;
                   3284:     }
                   3285:
                   3286:     res++; /* commit dd, xu1, xv1 */
                   3287:     dd = tmpd; xu1 = tmpu; xv1 = tmpv;
                   3288: #ifdef DEBUG_LEHMER
                   3289:     fprintferr("  q = %ld, %lx, %lx\n", q, dd1, dd);
                   3290: #endif
                   3291:     if (xv1 > vmax)
                   3292:     {                          /* time to return */
                   3293:       *u = xu; *u1 = xu1; *v = xv; *v1 = xv1;
                   3294:       return res;
                   3295:     }
                   3296:   } /* end of second loop */
                   3297:
                   3298:   return res;
                   3299: }
                   3300:
                   3301: /*==================================
                   3302:  * invmod(a,b,res)
                   3303:  *==================================
                   3304:  *    If a is invertible, return 1, and set res  = a^{ -1 }
                   3305:  *    Otherwise, return 0, and set res = gcd(a,b)
                   3306:  *
                   3307:  * This is sufficiently different from bezout() to be implemented separately
                   3308:  * instead of having a bunch of extra conditionals in a single function body
                   3309:  * to meet both purposes.
                   3310:  */
                   3311:
                   3312: int
                   3313: invmod(GEN a, GEN b, GEN *res)
                   3314: {
                   3315:   GEN v,v1,d,d1,q,r;
                   3316:   long av,av1,lim;
                   3317:   long s;
                   3318:   ulong g;
                   3319:   ulong xu,xu1,xv,xv1;         /* Lehmer stage recurrence matrix */
                   3320:   int lhmres;                  /* Lehmer stage return value */
                   3321:
                   3322:   if (typ(a) != t_INT || typ(b) != t_INT) err(arither1);
                   3323:   if (!signe(b)) { *res=absi(a); return 0; }
                   3324:   av = avma;
                   3325:   if (lgefint(b) == 3) /* single-word affair */
                   3326:   {
                   3327:     d1 = modiu(a, (ulong)(b[2]));
                   3328:     if (d1 == gzero)
                   3329:     {
                   3330:       if (b[2] == 1L)
                   3331:         { *res = gzero; return 1; }
                   3332:       else
                   3333:         { *res = absi(b); return 0; }
                   3334:     }
                   3335:     g = xgcduu((ulong)(b[2]), (ulong)(d1[2]), 1, &xv, &xv1, &s);
                   3336: #ifdef DEBUG_LEHMER
                   3337:     fprintferr(" <- %lu,%lu\n", (ulong)(b[2]), (ulong)(d1[2]));
                   3338:     fprintferr(" -> %lu,%ld,%lu; %lx\n", g,s,xv1,avma);
                   3339: #endif
                   3340:     avma = av;
                   3341:     if (g != 1UL) { *res = utoi(g); return 0; }
                   3342:     xv = xv1 % (ulong)(b[2]); if (s < 0) xv = ((ulong)(b[2])) - xv;
                   3343:     *res = utoi(xv); return 1;
                   3344:   }
                   3345:
                   3346:   (void)new_chunk(lgefint(b));
                   3347:   d = absi(b); d1 = modii(a,d);
                   3348:
                   3349:   v=gzero; v1=gun;     /* general case */
                   3350: #ifdef DEBUG_LEHMER
                   3351:   fprintferr("INVERT: -------------------------\n");
                   3352:   output(d1);
                   3353: #endif
                   3354:   av1 = avma; lim = stack_lim(av,1);
                   3355:
                   3356:   while (lgefint(d) > 3 && signe(d1))
                   3357:   {
                   3358: #ifdef DEBUG_LEHMER
                   3359:     fprintferr("Calling Lehmer:\n");
                   3360: #endif
                   3361:     lhmres = lgcdii((ulong*)d, (ulong*)d1, &xu, &xu1, &xv, &xv1, MAXULONG);
                   3362:     if (lhmres != 0)           /* check progress */
                   3363:     {                          /* apply matrix */
                   3364: #ifdef DEBUG_LEHMER
                   3365:       fprintferr("Lehmer returned %d [%lu,%lu;%lu,%lu].\n",
                   3366:              lhmres, xu, xu1, xv, xv1);
                   3367: #endif
                   3368:       if ((lhmres == 1) || (lhmres == -1))
                   3369:       {
                   3370:        if (xv1 == 1)
                   3371:        {
                   3372:          r = subii(d,d1); d=d1; d1=r;
                   3373:          a = subii(v,v1); v=v1; v1=a;
                   3374:        }
                   3375:        else
                   3376:        {
                   3377:          r = subii(d, mului(xv1,d1)); d=d1; d1=r;
                   3378:          a = subii(v, mului(xv1,v1)); v=v1; v1=a;
                   3379:        }
                   3380:       }
                   3381:       else
                   3382:       {
                   3383:        r  = subii(muliu(d,xu),  muliu(d1,xv));
                   3384:        a  = subii(muliu(v,xu),  muliu(v1,xv));
                   3385:        d1 = subii(muliu(d,xu1), muliu(d1,xv1)); d = r;
                   3386:        v1 = subii(muliu(v,xu1), muliu(v1,xv1)); v = a;
                   3387:         if (lhmres&1)
                   3388:        {
                   3389:           setsigne(d,-signe(d));
                   3390:           setsigne(v,-signe(v));
                   3391:         }
                   3392:         else
                   3393:        {
                   3394:           if (signe(d1)) { setsigne(d1,-signe(d1)); }
                   3395:           setsigne(v1,-signe(v1));
                   3396:         }
                   3397:       }
                   3398:     }
                   3399: #ifdef DEBUG_LEHMER
                   3400:     else
                   3401:       fprintferr("Lehmer returned 0.\n");
                   3402:     output(d); output(d1); output(v); output(v1);
                   3403:     sleep(1);
                   3404: #endif
                   3405:
                   3406:     if (lhmres <= 0 && signe(d1))
                   3407:     {
                   3408:       q = dvmdii(d,d1,&r);
                   3409: #ifdef DEBUG_LEHMER
                   3410:       fprintferr("Full division:\n");
                   3411:       printf("  q = "); output(q); sleep (1);
                   3412: #endif
                   3413:       a = subii(v,mulii(q,v1));
                   3414:       v=v1; v1=a;
                   3415:       d=d1; d1=r;
                   3416:     }
                   3417:     if (low_stack(lim, stack_lim(av,1)))
                   3418:     {
                   3419:       GEN *gptr[4]; gptr[0]=&d; gptr[1]=&d1; gptr[2]=&v; gptr[3]=&v1;
                   3420:       if(DEBUGMEM>1) err(warnmem,"invmod");
                   3421:       gerepilemany(av1,gptr,4);
                   3422:     }
                   3423:   } /* end while */
                   3424:
                   3425:   /* Postprocessing - final sprint */
                   3426:   if (signe(d1))
                   3427:   {
                   3428:     /* Assertions: lgefint(d)==lgefint(d1)==3, and
                   3429:      * gcd(d,d1) is nonzero and fits into one word
                   3430:      */
                   3431:     g = xxgcduu((ulong)(d[2]), (ulong)(d1[2]), 1, &xu, &xu1, &xv, &xv1, &s);
                   3432: #ifdef DEBUG_LEHMER
                   3433:     output(d);output(d1);output(v);output(v1);
                   3434:     fprintferr(" <- %lu,%lu\n", (ulong)(d[2]), (ulong)(d1[2]));
                   3435:     fprintferr(" -> %lu,%ld,%lu; %lx\n", g,s,xv1,avma);
                   3436: #endif
                   3437:     if (g != 1UL) { avma = av; *res = utoi(g); return 0; }
                   3438:     /* (From the xgcduu() blurb:)
                   3439:      * For finishing the multiword modinv, we now have to multiply the
                   3440:      * returned matrix  (with properly adjusted signs)  onto the values
                   3441:      * v' and v1' previously obtained from the multiword division steps.
                   3442:      * Actually, it is sufficient to take the scalar product of [v',v1']
                   3443:      * with [u1,-v1], and change the sign if s==1.
                   3444:      */
                   3445:     v = subii(muliu(v,xu1),muliu(v1,xv1));
                   3446:     if (s > 0) setsigne(v,-signe(v));
                   3447:     avma = av; *res = modii(v,b);
                   3448: #ifdef DEBUG_LEHMER
                   3449:     output(*res); fprintfderr("============================Done.\n");
                   3450:     sleep(1);
                   3451: #endif
                   3452:     return 1;
                   3453:   }
                   3454:   /* get here when the final sprint was skipped (d1 was zero already) */
                   3455:   avma = av;
                   3456:   if (!egalii(d,gun)) { *res = icopy(d); return 0; }
                   3457:   *res = modii(v,b);
                   3458: #ifdef DEBUG_LEHMER
                   3459:   output(*res); fprintferr("============================Done.\n");
                   3460:   sleep(1);
                   3461: #endif
                   3462:   return 1;
                   3463: }
                   3464:
                   3465: /*==================================
                   3466:  * bezout(a,b,pu,pv)
                   3467:  *==================================
                   3468:  *    Return g = gcd(a,b) >= 0, and assign GENs u,v through pointers pu,pv
                   3469:  *    such that g = u*a + v*b.
                   3470:  * Special cases:
                   3471:  *    a == b == 0 ==> pick u=1, v=0
                   3472:  *    a != 0 == b ==> keep v=0
                   3473:  *    a == 0 != b ==> keep u=0
                   3474:  *    |a| == |b| != 0 ==> keep u=0, set v=+-1
                   3475:  * Assignments through pu,pv will be suppressed when the corresponding
                   3476:  * pointer is NULL  (but the computations will happen nonetheless).
                   3477:  */
                   3478:
                   3479: GEN
                   3480: bezout(GEN a, GEN b, GEN *pu, GEN *pv)
                   3481: {
                   3482:   GEN t,u,u1,v,v1,d,d1,q,r;
                   3483:   GEN *pt;
                   3484:   long av,av1,lim;
                   3485:   long s;
                   3486:   int sa, sb;
                   3487:   ulong g;
                   3488:   ulong xu,xu1,xv,xv1;         /* Lehmer stage recurrence matrix */
                   3489:   int lhmres;                  /* Lehmer stage return value */
                   3490:
                   3491:   if (typ(a) != t_INT || typ(b) != t_INT) err(arither1);
                   3492:   s = absi_cmp(a,b);
                   3493:   if (s < 0)
                   3494:   {
                   3495:     t=b; b=a; a=t;
                   3496:     pt=pu; pu=pv; pv=pt;
                   3497:   }
                   3498:   /* now |a| >= |b| */
                   3499:
                   3500:   sa = signe(a); sb = signe(b);
                   3501:   if (!sb)
                   3502:   {
                   3503:     if (pv != NULL) *pv = gzero;
                   3504:     switch(sa)
                   3505:     {
                   3506:     case  0:
                   3507:       if (pu != NULL) *pu = gun; return gzero;
                   3508:     case  1:
                   3509:       if (pu != NULL) *pu = gun; return icopy(a);
                   3510:     case -1:
                   3511:       if (pu != NULL) *pu = negi(gun); return(negi(a));
                   3512:     }
                   3513:   }
                   3514:   if (s == 0)                  /* |a| == |b| != 0 */
                   3515:   {
                   3516:     if (pu != NULL) *pu = gzero;
                   3517:     if (sb > 0)
                   3518:     {
                   3519:       if (pv != NULL) *pv = gun; return icopy(b);
                   3520:     }
                   3521:     else
                   3522:     {
                   3523:       if (pv != NULL) *pv = negi(gun); return(negi(b));
                   3524:     }
                   3525:   }
                   3526:   /* now |a| > |b| > 0 */
                   3527:
                   3528:   if (lgefint(a) == 3)         /* single-word affair */
                   3529:   {
                   3530:     g = xxgcduu((ulong)(a[2]), (ulong)(b[2]), 0, &xu, &xu1, &xv, &xv1, &s);
                   3531:     sa = s > 0 ? sa : -sa;
                   3532:     sb = s > 0 ? -sb : sb;
                   3533:     if (pu != NULL)
                   3534:     {
                   3535:       if (xu == 0) *pu = gzero; /* can happen when b divides a */
                   3536:       else if (xu == 1) *pu = sa < 0 ? negi(gun) : gun;
                   3537:       else if (xu == 2) *pu = sa < 0 ? negi(gdeux) : gdeux;
                   3538:       else
                   3539:       {
                   3540:        *pu = cgeti(3);
                   3541:        (*pu)[1] = evalsigne(sa)|evallgefint(3);
                   3542:        (*pu)[2] = xu;
                   3543:       }
                   3544:     }
                   3545:     if (pv != NULL)
                   3546:     {
                   3547:       if (xv == 1) *pv = sb < 0 ? negi(gun) : gun;
                   3548:       else if (xv == 2) *pv = sb < 0 ? negi(gdeux) : gdeux;
                   3549:       else
                   3550:       {
                   3551:        *pv = cgeti(3);
                   3552:        (*pv)[1] = evalsigne(sb)|evallgefint(3);
                   3553:        (*pv)[2] = xv;
                   3554:       }
                   3555:     }
                   3556:     if (g == 1) return gun;
                   3557:     else if (g == 2) return gdeux;
                   3558:     else
                   3559:     {
                   3560:       r = cgeti(3);
                   3561:       r[1] = evalsigne(1)|evallgefint(3);
                   3562:       r[2] = g;
                   3563:       return r;
                   3564:     }
                   3565:   }
                   3566:
                   3567:   /* general case */
                   3568:   av = avma;
                   3569:   (void)new_chunk(lgefint(b) + (lgefint(a)<<1)); /* room for u,v,gcd */
                   3570:   /* if a is significantly larger than b, calling lgcdii() is not the best
                   3571:    * way to start -- reduce a mod b first
                   3572:    */
                   3573:   if (lgefint(a) > lgefint(b))
                   3574:   {
                   3575:     d = absi(b), q = dvmdii(absi(a), d, &d1);
                   3576:     if (!signe(d1))            /* a == qb */
                   3577:     {
                   3578:       avma = av;
                   3579:       if (pu != NULL) *pu = gzero;
                   3580:       if (pv != NULL) *pv = sb < 0 ? negi(gun) : gun;
                   3581:       return (icopy(d));
                   3582:     }
                   3583:     else
                   3584:     {
                   3585:       u = gzero;
                   3586:       u1 = v = gun;
                   3587:       v1 = negi(q);
                   3588:     }
                   3589:     /* if this results in lgefint(d) == 3, will fall past main loop */
                   3590:   }
                   3591:   else
                   3592:   {
                   3593:     d = absi(a); d1 = absi(b);
                   3594:     u = v1 = gun; u1 = v = gzero;
                   3595:   }
                   3596:   av1 = avma; lim = stack_lim(av, 1);
                   3597:
                   3598:   /* main loop is almost identical to that of invmod() */
                   3599:   while (lgefint(d) > 3 && signe(d1))
                   3600:   {
                   3601:     lhmres = lgcdii((ulong *)d, (ulong *)d1, &xu, &xu1, &xv, &xv1, MAXULONG);
                   3602:     if (lhmres != 0)           /* check progress */
                   3603:     {                          /* apply matrix */
                   3604:       if ((lhmres == 1) || (lhmres == -1))
                   3605:       {
                   3606:        if (xv1 == 1)
                   3607:        {
                   3608:          r = subii(d,d1); d=d1; d1=r;
                   3609:          a = subii(u,u1); u=u1; u1=a;
                   3610:          a = subii(v,v1); v=v1; v1=a;
                   3611:        }
                   3612:        else
                   3613:        {
                   3614:          r = subii(d, mului(xv1,d1)); d=d1; d1=r;
                   3615:          a = subii(u, mului(xv1,u1)); u=u1; u1=a;
                   3616:          a = subii(v, mului(xv1,v1)); v=v1; v1=a;
                   3617:        }
                   3618:       }
                   3619:       else
                   3620:       {
                   3621:        r  = subii(muliu(d,xu),  muliu(d1,xv));
                   3622:        d1 = subii(muliu(d,xu1), muliu(d1,xv1)); d = r;
                   3623:        a  = subii(muliu(u,xu),  muliu(u1,xv));
                   3624:        u1 = subii(muliu(u,xu1), muliu(u1,xv1)); u = a;
                   3625:        a  = subii(muliu(v,xu),  muliu(v1,xv));
                   3626:        v1 = subii(muliu(v,xu1), muliu(v1,xv1)); v = a;
                   3627:         if (lhmres&1)
                   3628:        {
                   3629:           setsigne(d,-signe(d));
                   3630:           setsigne(u,-signe(u));
                   3631:           setsigne(v,-signe(v));
                   3632:         }
                   3633:         else
                   3634:        {
                   3635:           if (signe(d1)) { setsigne(d1,-signe(d1)); }
                   3636:           setsigne(u1,-signe(u1));
                   3637:           setsigne(v1,-signe(v1));
                   3638:         }
                   3639:       }
                   3640:     }
                   3641:     if (lhmres <= 0 && signe(d1))
                   3642:     {
                   3643:       q = dvmdii(d,d1,&r);
                   3644: #ifdef DEBUG_LEHMER
                   3645:       fprintferr("Full division:\n");
                   3646:       printf("  q = "); output(q); sleep (1);
                   3647: #endif
                   3648:       a = subii(u,mulii(q,u1));
                   3649:       u=u1; u1=a;
                   3650:       a = subii(v,mulii(q,v1));
                   3651:       v=v1; v1=a;
                   3652:       d=d1; d1=r;
                   3653:     }
                   3654:     if (low_stack(lim, stack_lim(av,1)))
                   3655:     {
                   3656:       GEN *gptr[6]; gptr[0]=&d; gptr[1]=&d1; gptr[2]=&u; gptr[3]=&u1;
                   3657:       gptr[4]=&v; gptr[5]=&v1;
                   3658:       if(DEBUGMEM>1) err(warnmem,"bezout");
                   3659:       gerepilemany(av1,gptr,6);
                   3660:     }
                   3661:   } /* end while */
                   3662:
                   3663:   /* Postprocessing - final sprint */
                   3664:   if (signe(d1))
                   3665:   {
                   3666:     /* Assertions: lgefint(d)==lgefint(d1)==3, and
                   3667:      * gcd(d,d1) is nonzero and fits into one word
                   3668:      */
                   3669:     g = xxgcduu((ulong)(d[2]), (ulong)(d1[2]), 0, &xu, &xu1, &xv, &xv1, &s);
                   3670:     u = subii(muliu(u,xu), muliu(u1, xv));
                   3671:     v = subii(muliu(v,xu), muliu(v1, xv));
                   3672:     if (s < 0) { sa = -sa; sb = -sb; }
                   3673:     avma = av;
                   3674:     if (pu != NULL) *pu = sa < 0 ? negi(u) : icopy(u);
                   3675:     if (pv != NULL) *pv = sb < 0 ? negi(v) : icopy(v);
                   3676:     if (g == 1) return gun;
                   3677:     else if (g == 2) return gdeux;
                   3678:     else
                   3679:     {
                   3680:       r = cgeti(3);
                   3681:       r[1] = evalsigne(1)|evallgefint(3);
                   3682:       r[2] = g;
                   3683:       return r;
                   3684:     }
                   3685:   }
                   3686:   /* get here when the final sprint was skipped (d1 was zero already).
                   3687:    * Now the matrix is final, and d contains the gcd.
                   3688:    */
                   3689:   avma = av;
                   3690:   if (pu != NULL) *pu = sa < 0 ? negi(u) : icopy(u);
                   3691:   if (pv != NULL) *pv = sb < 0 ? negi(v) : icopy(v);
                   3692:   return icopy(d);
                   3693: }
                   3694:
                   3695: /*==================================
                   3696:  * cbezout(a,b,uu,vv)
                   3697:  *==================================
                   3698:  * Same as bezout() but for C longs.
                   3699:  *    Return g = gcd(a,b) >= 0, and assign longs u,v through pointers uu,vv
                   3700:  *    such that g = u*a + v*b.
                   3701:  * Special cases:
                   3702:  *    a == b == 0 ==> pick u=1, v=0 (and return 1, surprisingly)
                   3703:  *    a != 0 == b ==> keep v=0
                   3704:  *    a == 0 != b ==> keep u=0
                   3705:  *    |a| == |b| != 0 ==> keep u=0, set v=+-1
                   3706:  * Assignments through uu,vv happen unconditionally;  non-NULL pointers
                   3707:  * _must_ be used.
                   3708:  */
                   3709: long
                   3710: cbezout(long a,long b,long *uu,long *vv)
                   3711: {
                   3712:   long s,*t;
                   3713:   ulong d = labs(a), d1 = labs(b);
                   3714:   ulong r,u,u1,v,v1;
                   3715:
                   3716: #ifdef DEBUG_CBEZOUT
                   3717:   fprintferr("> cbezout(%ld,%ld,%p,%p)\n", a, b, (void *)uu, (void *)vv);
                   3718: #endif
                   3719:   if (!b)
                   3720:   {
                   3721:     *vv=0L;
                   3722:     if (!a)
                   3723:     {
                   3724:       *uu=1L;
                   3725: #ifdef DEBUG_CBEZOUT
                   3726:       fprintferr("< %ld (%ld, %ld)\n", 1L, *uu, *vv);
                   3727: #endif
                   3728:       return 0L;
                   3729:     }
                   3730:     *uu = a < 0 ? -1L : 1L;
                   3731: #ifdef DEBUG_CBEZOUT
                   3732:     fprintferr("< %ld (%ld, %ld)\n", (long)d, *uu, *vv);
                   3733: #endif
                   3734:     return (long)d;
                   3735:   }
                   3736:   else if (!a || (d == d1))
                   3737:   {
                   3738:     *uu = 0L; *vv = b < 0 ? -1L : 1L;
                   3739: #ifdef DEBUG_CBEZOUT
                   3740:     fprintferr("< %ld (%ld, %ld)\n", (long)d1, *uu, *vv);
                   3741: #endif
                   3742:     return (long)d1;
                   3743:   }
                   3744:   else if (d == 1)             /* frequently used by nfinit */
                   3745:   {
                   3746:     *uu = a; *vv = 0L;
                   3747: #ifdef DEBUG_CBEZOUT
                   3748:     fprintferr("< %ld (%ld, %ld)\n", 1L, *uu, *vv);
                   3749: #endif
                   3750:     return 1L;
                   3751:   }
                   3752:   else if (d < d1)
                   3753:   {
                   3754: /* bug in gcc-2.95.3:
                   3755:  * s = a; a = b; b = s; produces wrong result a = b. This is OK:  */
                   3756:     { long _x = a; a = b; b = _x; }    /* in order to keep the right signs */
                   3757:     r = d; d = d1; d1 = r;
                   3758:     t = uu; uu = vv; vv = t;
                   3759: #ifdef DEBUG_CBEZOUT
                   3760:     fprintferr("  swapping\n");
                   3761: #endif
                   3762:   }
                   3763:   /* d > d1 > 0 */
                   3764:   r = xxgcduu(d, d1, 0, &u, &u1, &v, &v1, &s);
                   3765:   if (s < 0)
                   3766:   {
                   3767:     *uu = a < 0 ? u : -(long)u;
                   3768:     *vv = b < 0 ? -(long)v : v;
                   3769:   }
                   3770:   else
                   3771:   {
                   3772:     *uu = a < 0 ? -(long)u : u;
                   3773:     *vv = b < 0 ? v : -(long)v;
                   3774:   }
                   3775: #ifdef DEBUG_CBEZOUT
                   3776:   fprintferr("< %ld (%ld, %ld)\n", (long)r, *uu, *vv);
                   3777: #endif
                   3778:   return (long)r;
                   3779: }
                   3780:
                   3781: /*==========================================================
                   3782:  * ratlift(GEN x, GEN m, GEN *a, GEN *b, GEN amax, GEN bmax)
                   3783:  *==========================================================
                   3784:  * Reconstruct rational number from its residue x mod m
                   3785:  *    Given t_INT x, m, amax>=0, bmax>0 such that
                   3786:  *     0 <= x < m;  2*amax*bmax < m
                   3787:  *    attempts to find t_INT a, b such that
                   3788:  *     (1) a = b*x (mod m)
                   3789:  *     (2) |a| <= amax, 0 < b <= bmax
                   3790:  *     (3) gcd(m, b) = gcd(a, b)
                   3791:  *    If unsuccessful, it will return 0 and leave a,b unchanged  (and
                   3792:  *    caller may deduce no such a,b exist).  If successful, sets a,b
                   3793:  *    and returns 1.  If there exist a,b satisfying (1), (2), and
                   3794:  *     (3') gcd(m, b) = 1
                   3795:  *    then they are uniquely determined subject to (1),(2) and
                   3796:  *     (3'') gcd(a, b) = 1,
                   3797:  *    and will be returned by the routine.  (The caller may wish to
                   3798:  *    check gcd(a,b)==1, either directly or based on known prime
                   3799:  *    divisors of m, depending on the application.)
                   3800:  * Reference:
                   3801:  @article {MR97c:11116,
                   3802:      AUTHOR = {Collins, George E. and Encarnaci{\'o}n, Mark J.},
                   3803:       TITLE = {Efficient rational number reconstruction},
                   3804:     JOURNAL = {J. Symbolic Comput.},
                   3805:    FJOURNAL = {Journal of Symbolic Computation},
                   3806:      VOLUME = {20},
                   3807:        YEAR = {1995},
                   3808:      NUMBER = {3},
                   3809:       PAGES = {287--297},
                   3810:        ISSN = {0747-7171},
                   3811:     MRCLASS = {11Y16 (68Q40)},
                   3812:    MRNUMBER = {97c:11116},
                   3813:  MRREVIEWER = {Maurice Mignotte},
                   3814:  }
                   3815:  *    Preprint available from:
                   3816:  *    ftp://ftp.risc.uni-linz.ac.at/pub/techreports/1994/94-64.ps.gz
                   3817:  */
                   3818:
                   3819: /* #define DEBUG_RATLIFT */
                   3820:
                   3821: int
                   3822: ratlift(GEN x, GEN m, GEN *a, GEN *b, GEN amax, GEN bmax)
                   3823: {
                   3824:   GEN d,d1,v,v1,q,r;
                   3825:   ulong av = avma, av1, lim;
                   3826:   long lb,lr,lbb,lbr,s,s0;
                   3827:   ulong vmax;
                   3828:   ulong xu,xu1,xv,xv1;         /* Lehmer stage recurrence matrix */
                   3829:   int lhmres;                  /* Lehmer stage return value */
                   3830:
                   3831:   if ((typ(x) | typ(m) | typ(amax) | typ(bmax)) != t_INT) err(arither1);
                   3832:   if (signe(bmax) <= 0)
                   3833:     err(talker, "ratlift: bmax must be > 0, found\n\tbmax=%Z\n", bmax);
                   3834:   if (signe(amax) < 0)
                   3835:     err(talker, "ratilft: amax must be >= 0, found\n\tamax=%Z\n", amax);
                   3836:   /* check 2*amax*bmax < m */
                   3837:   if (cmpii(shifti(mulii(amax, bmax), 1), m) >= 0)
                   3838:     err(talker, "ratlift: must have 2*amax*bmax < m, found\n\tamax=%Z\n\tbmax=%Z\n\tm=%Z\n", amax,bmax,m);
                   3839:   /* we _could_ silently replace x with modii(x,m) instead of the following,
                   3840:    * but let's leave this up to the caller
                   3841:    */
                   3842:   avma = av; s = signe(x);
                   3843:   if (s < 0 || cmpii(x,m) >= 0)
                   3844:     err(talker, "ratlift: must have 0 <= x < m, found\n\tx=%Z\n\tm=%Z\n", x,m);
                   3845:
                   3846:   /* special cases x=0 and/or amax=0 */
                   3847:   if (s == 0)
                   3848:   {
                   3849:     if (a != NULL) *a = gzero;
                   3850:     if (b != NULL) *b = gun;
                   3851:     return 1;
                   3852:   }
                   3853:   else if (signe(amax)==0)
                   3854:     return 0;
                   3855:   /* assert: m > x > 0, amax > 0 */
                   3856:
                   3857:   /* check here whether a=x, b=1 is a solution */
                   3858:   if (cmpii(x,amax) <= 0)
                   3859:   {
                   3860:     if (a != NULL) *a = icopy(x);
                   3861:     if (b != NULL) *b = gun;
                   3862:     return 1;
                   3863:   }
                   3864:
                   3865:   /* There is no special case for single-word numbers since this is
                   3866:    * mainly meant to be used with large moduli.
                   3867:    */
                   3868:   (void)new_chunk(lgefint(bmax) + lgefint(amax)); /* room for a,b */
                   3869:   d = m; d1 = x;
                   3870:   v = gzero; v1 = gun;
                   3871:   /* assert d1 > amax, v1 <= bmax here */
                   3872:   lb = lgefint(bmax);
                   3873:   lbb = bfffo(bmax[2]);
                   3874:   s = 1;
                   3875:   av1 = avma; lim = stack_lim(av, 1);
                   3876:
                   3877:   /* general case: Euclidean division chain starting with m div x, and
                   3878:    * with bounds on the sequence of convergents' denoms v_j.
                   3879:    * Just to be different from what invmod and bezout are doing, we work
                   3880:    * here with the all-nonnegative matrices [u,u1;v,v1]=prod_j([0,1;1,q_j]).
                   3881:    * Loop invariants:
                   3882:    * (a) (sign)*[-v,v1]*x = [d,d1] (mod m)  (componentwise)
                   3883:    * (sign initially +1, changes with each Euclidean step)
                   3884:    * so [a,b] will be obtained in the form [-+d,v] or [+-d1,v1];
                   3885:    * this congruence is a consequence of
                   3886:    * (b) [x,m]~ = [u,u1;v,v1]*[d1,d]~,
                   3887:    * where u,u1 is the usual numerator sequence starting with 1,0
                   3888:    * instead of 0,1  (just multiply the eqn on the left by the inverse
                   3889:    * matrix, which is det*[v1,-u1;-v,u], where "det" is the same as the
                   3890:    * "(sign)" in (a)).  From m = v*d1 + v1*d and
                   3891:    * (c) d > d1 >= 0, 0 <= v < v1,
                   3892:    * we have d >= m/(2*v1), so while v1 remains smaller than m/(2*amax),
                   3893:    * the pair [-(sign)*d,v] satisfies (1) but violates (2) (d > amax).
                   3894:    * Conversely, v1 > bmax indicates that no further solutions will be
                   3895:    * forthcoming;  [-(sign)*d,v] will be the last, and first, candidate.
                   3896:    * Thus there's at most one point in the chain division where a solution
                   3897:    * can live:  v < bmax, v1 >= m/(2*amax) > bmax,  and this is acceptable
                   3898:    * iff in fact d <= amax  (e.g. m=221, x=34 or 35, amax=bmax=10 fail on
                   3899:    * this count while x=32,33,36,37 succeed).  However, a division may leave
                   3900:    * a zero residue before we ever reach this point  (consider m=210, x=35,
                   3901:    * amax=bmax=10),  and our caller may find that gcd(d,v) > 1  (numerous
                   3902:    * examples -- keep m=210 and consider any of x=29,31,32,33,34,36,37,38,
                   3903:    * 39,40,41).
                   3904:    * Furthermore, at the start of the loop body we have in fact
                   3905:    * (c') 0 <= v < v1 <= bmax, d > d1 > amax >= 0,
                   3906:    * (and are never done already).
                   3907:    *
                   3908:    * Main loop is similar to those of invmod() and bezout(), except for
                   3909:    * having to determine appropriate vmax bounds, and checking termination
                   3910:    * conditions.  The signe(d1) condition is only for paranoia
                   3911:    */
                   3912:   while (lgefint(d) > 3 && signe(d1))
                   3913:   {
                   3914:     /* determine vmax for lgcdii so as to ensure v won't overshoot.
                   3915:      * If v+v1 > bmax, the next step would take v1 beyond the limit, so
                   3916:      * since [+-d1,v1] is not a solution, we give up.  Otherwise if v+v1
                   3917:      * is way shorter than bmax, use vmax=MAXULUNG.  Otherwise, set vmax
                   3918:      * to a crude lower approximation of bmax/(v+v1), or to 1, which will
                   3919:      * allow the inner loop to do one step
                   3920:      */
                   3921:     r = addii(v,v1);
                   3922:     lr = lb - lgefint(r);
                   3923:     lbr = bfffo(r[2]);
                   3924:     if (cmpii(r,bmax) > 0)     /* done, not found */
                   3925:     {
                   3926:       avma = av;
                   3927:       return 0;
                   3928:     }
                   3929:     else if (lr > 1)           /* still more than a word's worth to go */
                   3930:     {
                   3931:       vmax = MAXULONG;
                   3932:     }
                   3933:     else                       /* take difference of bit lengths */
                   3934:     {
                   3935:       lr = (lr << TWOPOTBITS_IN_LONG) - lbb + lbr;
                   3936:       if (lr > BITS_IN_LONG)
                   3937:        vmax = MAXULONG;
                   3938:       else if (lr == 0)
                   3939:        vmax = 1UL;
                   3940:       else
                   3941:        vmax = 1UL << (lr-1);
                   3942:       /* the latter is pessimistic but faster than a division */
                   3943:     }
                   3944:     /* do a Lehmer-Jebelean round */
                   3945:     lhmres = lgcdii((ulong *)d, (ulong *)d1, &xu, &xu1, &xv, &xv1, vmax);
                   3946:     if (lhmres != 0)           /* check progress */
                   3947:     {                          /* apply matrix */
                   3948:       if ((lhmres == 1) || (lhmres == -1))
                   3949:       {
                   3950:        s = -s;
                   3951:        if (xv1 == 1)
                   3952:        {
                   3953:          /* re-use v+v1 computed above */
                   3954:          v=v1; v1=r;
                   3955:          r = subii(d,d1); d=d1; d1=r;
                   3956:        }
                   3957:        else
                   3958:        {
                   3959:          r = subii(d, mului(xv1,d1)); d=d1; d1=r;
                   3960:          r = addii(v, mului(xv1,v1)); v=v1; v1=r;
                   3961:        }
                   3962:       }
                   3963:       else
                   3964:       {
                   3965:        r  = subii(muliu(d,xu),  muliu(d1,xv));
                   3966:        d1 = subii(muliu(d,xu1), muliu(d1,xv1)); d = r;
                   3967:        r  = addii(muliu(v,xu),  muliu(v1,xv));
                   3968:        v1 = addii(muliu(v,xu1), muliu(v1,xv1)); v = r;
                   3969:         if (lhmres&1)
                   3970:        {
                   3971:           setsigne(d,-signe(d));
                   3972:          s = -s;
                   3973:         }
                   3974:         else if (signe(d1))
                   3975:        {
                   3976:           setsigne(d1,-signe(d1));
                   3977:         }
                   3978:       }
                   3979:       /* check whether we're done.  Assert v <= bmax here.  Examine v1:
                   3980:        * if v1 > bmax, check d and return 0 or 1 depending on the outcome;
                   3981:        * if v1 <= bmax, check d1 and return 1 if d1 <= amax, otherwise
                   3982:        * proceed.
                   3983:        */
                   3984:       if (cmpii(v1,bmax) > 0) /* certainly done */
                   3985:       {
                   3986:        avma = av;
                   3987:        if (cmpii(d,amax) <= 0) /* done, found */
                   3988:        {
                   3989:          if (a != NULL)
                   3990:          {
                   3991:            *a = icopy(d);
                   3992:            setsigne(*a,-s);    /* sign opposite to s */
                   3993:          }
                   3994:          if (b != NULL) *b = icopy(v);
                   3995:          return 1;
                   3996:        }
                   3997:        else                    /* done, not found */
                   3998:          return 0;
                   3999:       }
                   4000:       else if (cmpii(d1,amax) <= 0) /* also done, found */
                   4001:       {
                   4002:        avma = av;
                   4003:        if (a != NULL)
                   4004:        {
                   4005:          if (signe(d1))
                   4006:          {
                   4007:            *a = icopy(d1);
                   4008:            setsigne(*a,s);     /* same sign as s */
                   4009:          }
                   4010:          else
                   4011:            *a = gzero;
                   4012:        }
                   4013:        if (b != NULL) *b = icopy(v1);
                   4014:        return 1;
                   4015:       }
                   4016:     } /* lhmres != 0 */
                   4017:
                   4018:     if (lhmres <= 0 && signe(d1))
                   4019:     {
                   4020:       q = dvmdii(d,d1,&r);
                   4021: #ifdef DEBUG_LEHMER
                   4022:       fprintferr("Full division:\n");
                   4023:       printf("  q = "); output(q); sleep (1);
                   4024: #endif
                   4025:       d=d1; d1=r;
                   4026:       r = addii(v,mulii(q,v1));
                   4027:       v=v1; v1=r;
                   4028:       s = -s;
                   4029:       /* check whether we are done now.  Since we weren't before the div, it
                   4030:        * suffices to examine v1 and d1 -- the new d (former d1) cannot cut it
                   4031:        */
                   4032:       if (cmpii(v1,bmax) > 0) /* done, not found */
                   4033:       {
                   4034:        avma = av;
                   4035:        return 0;
                   4036:       }
                   4037:       else if (cmpii(d1,amax) <= 0) /* done, found */
                   4038:       {
                   4039:        avma = av;
                   4040:        if (a != NULL)
                   4041:        {
                   4042:          if (signe(d1))
                   4043:          {
                   4044:            *a = icopy(d1);
                   4045:            setsigne(*a,s);     /* same sign as s */
                   4046:          }
                   4047:          else
                   4048:            *a = gzero;
                   4049:        }
                   4050:        if (b != NULL) *b = icopy(v1);
                   4051:        return 1;
                   4052:       }
                   4053:     }
                   4054:
                   4055:     if (low_stack(lim, stack_lim(av,1)))
                   4056:     {
                   4057:       GEN *gptr[4]; gptr[0]=&d; gptr[1]=&d1; gptr[2]=&v; gptr[3]=&v1;
                   4058:       if(DEBUGMEM>1) err(warnmem,"ratlift");
                   4059:       gerepilemany(av1,gptr,4);
                   4060:     }
                   4061:   } /* end while */
                   4062:
                   4063:   /* Postprocessing - final sprint.  Since we usually underestimate vmax,
                   4064:    * this function needs a loop here instead of a simple conditional.
                   4065:    * Note we can only get here when amax fits into one word  (which will
                   4066:    * typically not be the case!).  The condition is bogus -- d1 is never
                   4067:    * zero at the start of the loop.  There will be at most a few iterations,
                   4068:    * so we don't bother collecting garbage
                   4069:    */
                   4070:   while (signe(d1))
                   4071:   {
                   4072:     /* Assertions: lgefint(d)==lgefint(d1)==3.
                   4073:      * Moreover, we aren't done already, or we would have returned by now.
                   4074:      * Recompute vmax...
                   4075:      */
                   4076: #ifdef DEBUG_RATLIFT
                   4077:     fprintferr("rl-fs: d,d1=%Z,%Z\n", d, d1);
                   4078:     fprintferr("rl-fs: v,v1=%Z,%Z\n", v, v1);
                   4079: #endif
                   4080:     r = addii(v,v1);
                   4081:     lr = lb - lgefint(r);
                   4082:     lbr = bfffo(r[2]);
                   4083:     if (cmpii(r,bmax) > 0)     /* done, not found */
                   4084:     {
                   4085:       avma = av;
                   4086:       return 0;
                   4087:     }
                   4088:     else if (lr > 1)           /* still more than a word's worth to go */
                   4089:     {
                   4090:       vmax = MAXULONG;         /* (cannot in fact happen) */
                   4091:     }
                   4092:     else                       /* take difference of bit lengths */
                   4093:     {
                   4094:       lr = (lr << TWOPOTBITS_IN_LONG) - lbb + lbr;
                   4095:       if (lr > BITS_IN_LONG)
                   4096:        vmax = MAXULONG;
                   4097:       else if (lr == 0)
                   4098:        vmax = 1UL;
                   4099:       else
                   4100:        vmax = 1UL << (lr-1);   /* as above */
                   4101:     }
                   4102: #ifdef DEBUG_RATLIFT
                   4103:     fprintferr("rl-fs: vmax=%lu\n", vmax);
                   4104: #endif
                   4105:     /* single-word "Lehmer", discarding the gcd or whatever it returns */
                   4106:     (void)rgcduu((ulong)d[2], (ulong)d1[2], vmax, &xu, &xu1, &xv, &xv1, &s0);
                   4107: #ifdef DEBUG_RATLIFT
                   4108:     fprintferr("rl-fs: [%lu,%lu; %lu,%lu] %s\n",
                   4109:               xu, xu1, xv, xv1,
                   4110:               s0 < 0 ? "-" : "+");
                   4111: #endif
                   4112:     if (xv1 == 1)              /* avoid multiplications */
                   4113:     {
                   4114:       /* re-use v+v1 computed above */
                   4115:       v=v1; v1=r;
                   4116:       r = subii(d,d1); d=d1; d1=r;
                   4117:       s = -s;
                   4118:     }
                   4119:     else if (xu == 0)          /* and xv==1, xu1==1, xv1 > 1 */
                   4120:     {
                   4121:       r = subii(d, mului(xv1,d1)); d=d1; d1=r;
                   4122:       r = addii(v, mului(xv1,v1)); v=v1; v1=r;
                   4123:       s = -s;
                   4124:     }
                   4125:     else
                   4126:     {
                   4127:       r  = subii(muliu(d,xu),  muliu(d1,xv));
                   4128:       d1 = subii(muliu(d,xu1), muliu(d1,xv1)); d = r;
                   4129:       r  = addii(muliu(v,xu),  muliu(v1,xv));
                   4130:       v1 = addii(muliu(v,xu1), muliu(v1,xv1)); v = r;
                   4131:       if (s0 < 0)
                   4132:       {
                   4133:        setsigne(d,-signe(d));
                   4134:        s = -s;
                   4135:       }
                   4136:       else if (signe(d1))              /* sic: might vanish now */
                   4137:       {
                   4138:        setsigne(d1,-signe(d1));
                   4139:       }
                   4140:     }
                   4141:     /* check whether we're done, as above.  Assert v <= bmax.  Examine v1:
                   4142:      * if v1 > bmax, check d and return 0 or 1 depending on the outcome;
                   4143:      * if v1 <= bmax, check d1 and return 1 if d1 <= amax, otherwise proceed.
                   4144:      */
                   4145:     if (cmpii(v1,bmax) > 0) /* certainly done */
                   4146:     {
                   4147:       avma = av;
                   4148:       if (cmpii(d,amax) <= 0) /* done, found */
                   4149:       {
                   4150:        if (a != NULL)
                   4151:        {
                   4152:          *a = icopy(d);
                   4153:          setsigne(*a,-s);      /* sign opposite to s */
                   4154:        }
                   4155:        if (b != NULL) *b = icopy(v);
                   4156:        return 1;
                   4157:       }
                   4158:       else                     /* done, not found */
                   4159:        return 0;
                   4160:     }
                   4161:     else if (cmpii(d1,amax) <= 0) /* also done, found */
                   4162:     {
                   4163:       avma = av;
                   4164:       if (a != NULL)
                   4165:       {
                   4166:        if (signe(d1))
                   4167:        {
                   4168:          *a = icopy(d1);
                   4169:          setsigne(*a,s);       /* same sign as s */
                   4170:        }
                   4171:        else
                   4172:          *a = gzero;
                   4173:       }
                   4174:       if (b != NULL) *b = icopy(v1);
                   4175:       return 1;
                   4176:     }
                   4177:   } /* while */
                   4178:
                   4179:   /* get here when we have run into d1 == 0 before returning... in fact,
                   4180:    * this cannot happen.
                   4181:    */
                   4182:   err(talker, "ratlift failed to catch d1 == 0\n");
                   4183:   /* NOTREACHED */
                   4184:   return 0;
                   4185: }
                   4186:
                   4187: /********************************************************************/
                   4188: /**                                                                **/
                   4189: /**                      INTEGER SQUARE ROOT                       **/
                   4190: /**                                                                **/
                   4191: /********************************************************************/
                   4192:
                   4193: /* sqrt()'s result may be off by 1 when a is not representable exactly as a
                   4194:  * double [64bit machine] */
                   4195: ulong
                   4196: usqrtsafe(ulong a)
                   4197: {
                   4198:   ulong x = (ulong)sqrt((double)a);
                   4199: #ifdef LONG_IS_64BIT
                   4200:   ulong y = x+1; if (y <= MAXHALFULONG && y*y <= a) x = y;
                   4201: #endif
                   4202:   return x;
                   4203: }
                   4204:
                   4205: /* Assume a >= 0 has <= 4 words, return trunc[sqrt(a)] */
                   4206: ulong
                   4207: mpsqrtl(GEN a)
                   4208: {
                   4209:   long l = lgefint(a);
                   4210:   ulong x,y,z,k,m;
                   4211:   int L, s;
                   4212:
                   4213:   if (l <= 3) return l==2? 0: usqrtsafe((ulong)a[2]);
                   4214:   s = bfffo(a[2]);
                   4215:   if (s > 1)
                   4216:   {
                   4217:     s &= ~1UL; /* make it even */
                   4218:     z = BITS_IN_LONG - s;
                   4219:     m = (ulong)(a[2] << s) | (a[3] >> z);
                   4220:     L = z>>1;
                   4221:   }
                   4222:   else
                   4223:   {
                   4224:     m = (ulong)a[2];
                   4225:     L = BITS_IN_LONG/2;
                   4226:   }
                   4227:   /* m = BIL-1 (bffo odd) or BIL first bits of a */
                   4228:   k = (long) sqrt((double)m);
                   4229:   if (L == BITS_IN_LONG/2 && k == MAXHALFULONG)
                   4230:     x = MAXULONG;
                   4231:   else
                   4232:     x = (k+1) << L;
                   4233:   do
                   4234:   {
                   4235:     LOCAL_HIREMAINDER;
                   4236:     LOCAL_OVERFLOW;
                   4237:     hiremainder = a[2];
                   4238:     if (hiremainder >= x) return x;
                   4239:     z = addll(x, divll(a[3],x));
                   4240:     z >>= 1; if (overflow) z |= HIGHBIT;
                   4241:     y = x; x = z;
                   4242:   }
                   4243:   while (x < y);
                   4244:   return y;
                   4245: }

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