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

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

1.1       maekawa     1: /***********************************************************************/
                      2: /**                                                                  **/
                      3: /**                     MULTIPRECISION KERNEL                        **/
                      4: /**                                                                   **/
                      5: /***********************************************************************/
                      6: /* $Id: mp.c,v 1.1.1.1 1999/09/16 13:47:57 karim Exp $ */
                      7: /* most of the routines in this file are commented out in 68k */
                      8: /* version (#ifdef __M68K__) since they are defined in mp.s   */
                      9: #include "pari.h"
                     10:
                     11: /* z2 := z1[imin..imax].f shifted left sh bits (feeding f from the right) */
                     12: #define shift_left2(z2,z1,imin,imax,f, sh,m) {\
                     13:   register ulong _i,_l,_k = ((ulong)f)>>m;\
                     14:   for (_i=imax; _i>imin; _i--) {\
                     15:     _l = z1[_i];\
                     16:     z2[_i] = (_l<<(ulong)sh) | _k;\
                     17:     _k = _l>>(ulong)m;\
                     18:   }\
                     19:   z2[imin]=(z1[imin]<<(ulong)sh) | _k;\
                     20: }
                     21: #define shift_left(z2,z1,imin,imax,f, sh) {\
                     22:   register const ulong _m = BITS_IN_LONG - sh;\
                     23:   shift_left2((z2),(z1),(imin),(imax),(f),(sh),(_m));\
                     24: }
                     25:
                     26: /* z2 := f.z1[imin..imax-1] shifted right sh bits (feeding f from the left) */
                     27: #define shift_right2(z2,z1,imin,imax,f, sh,m) {\
                     28:   register ulong _i,_k,_l = z1[2];\
                     29:   z2[imin] = (_l>>(ulong)sh) | ((ulong)f<<(ulong)m);\
                     30:   for (_i=imin+1; _i<imax; _i++) {\
                     31:     _k = _l<<(ulong)m; _l = z1[_i];\
                     32:     z2[_i] = (_l>>(ulong)sh) | _k;\
                     33:   }\
                     34: }
                     35: #define shift_right(z2,z1,imin,imax,f, sh) {\
                     36:   register const ulong _m = BITS_IN_LONG - sh;\
                     37:   shift_right2((z2),(z1),(imin),(imax),(f),(sh),(_m));\
                     38: }
                     39:
                     40: #ifdef INLINE
                     41: INLINE
                     42: #endif
                     43: GEN
                     44: addsispec(long s, GEN x, long nx)
                     45: {
                     46:   GEN xd, zd = (GEN)avma;
                     47:   long lz;
                     48:   LOCAL_OVERFLOW;
                     49:
                     50:   lz = nx+3; (void)new_chunk(lz);
                     51:   xd = x + nx;
                     52:   *--zd = addll(*--xd, s);
                     53:   if (overflow)
                     54:     for(;;)
                     55:     {
                     56:       if (xd == x) { *--zd = 1; break; } /* enlarge z */
                     57:       *--zd = ((ulong)*--xd) + 1;
                     58:       if (*zd) { lz--; break; }
                     59:     }
                     60:   else lz--;
                     61:   while (xd > x) *--zd = *--xd;
                     62:   *--zd = evalsigne(1) | evallgefint(lz);
                     63:   *--zd = evaltyp(t_INT) | evallg(lz);
                     64:   avma=(long)zd; return zd;
                     65: }
                     66:
                     67: #define swapspec(x,y, nx,ny) {long _a=nx;GEN _z=x; nx=ny; ny=_a; x=y; y=_z;}
                     68:
                     69: #ifdef INLINE
                     70: INLINE
                     71: #endif
                     72: GEN
                     73: addiispec(GEN x, GEN y, long nx, long ny)
                     74: {
                     75:   GEN xd,yd,zd;
                     76:   long lz;
                     77:   LOCAL_OVERFLOW;
                     78:
                     79:   if (nx < ny) swapspec(x,y, nx,ny);
                     80:   if (ny == 1) return addsispec(*y,x,nx);
                     81:   zd = (GEN)avma;
                     82:   lz = nx+3; (void)new_chunk(lz);
                     83:   xd = x + nx;
                     84:   yd = y + ny;
                     85:   *--zd = addll(*--xd, *--yd);
                     86:   while (yd > y) *--zd = addllx(*--xd, *--yd);
                     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: /* assume x >= y */
                    102: #ifdef INLINE
                    103: INLINE
                    104: #endif
                    105: GEN
                    106: subisspec(GEN x, long s, long nx)
                    107: {
                    108:   GEN xd, zd = (GEN)avma;
                    109:   long lz;
                    110:   LOCAL_OVERFLOW;
                    111:
                    112:   lz = nx+2; (void)new_chunk(lz);
                    113:   xd = x + nx;
                    114:   *--zd = subll(*--xd, s);
                    115:   if (overflow)
                    116:     for(;;)
                    117:     {
                    118:       *--zd = ((ulong)*--xd) - 1;
                    119:       if (*xd) break;
                    120:     }
                    121:   if (xd == x)
                    122:     while (*zd == 0) { zd++; lz--; } /* shorten z */
                    123:   else
                    124:     do  *--zd = *--xd; while (xd > x);
                    125:   *--zd = evalsigne(1) | evallgefint(lz);
                    126:   *--zd = evaltyp(t_INT) | evallg(lz);
                    127:   avma=(long)zd; return zd;
                    128: }
                    129:
                    130: /* assume x >= y */
                    131: #ifdef INLINE
                    132: INLINE
                    133: #endif
                    134: GEN
                    135: subiispec(GEN x, GEN y, long nx, long ny)
                    136: {
                    137:   GEN xd,yd,zd;
                    138:   long lz;
                    139:   LOCAL_OVERFLOW;
                    140:
                    141:   if (ny==1) return subisspec(x,*y,nx);
                    142:   zd = (GEN)avma;
                    143:   lz = nx+2; (void)new_chunk(lz);
                    144:   xd = x + nx;
                    145:   yd = y + ny;
                    146:   *--zd = subll(*--xd, *--yd);
                    147:   while (yd > y) *--zd = subllx(*--xd, *--yd);
                    148:   if (overflow)
                    149:     for(;;)
                    150:     {
                    151:       *--zd = ((ulong)*--xd) - 1;
                    152:       if (*xd) break;
                    153:     }
                    154:   if (xd == x)
                    155:     while (*zd == 0) { zd++; lz--; } /* shorten z */
                    156:   else
                    157:     do  *--zd = *--xd; while (xd > x);
                    158:   *--zd = evalsigne(1) | evallgefint(lz);
                    159:   *--zd = evaltyp(t_INT) | evallg(lz);
                    160:   avma=(long)zd; return zd;
                    161: }
                    162:
                    163: #ifndef __M68K__
                    164:
                    165: /* prototype of positive small ints */
                    166: static long pos_s[] = {
                    167:   evaltyp(t_INT) | m_evallg(3), evalsigne(1) | evallgefint(3), 0 };
                    168:
                    169: /* prototype of negative small ints */
                    170: static long neg_s[] = {
                    171:   evaltyp(t_INT) | m_evallg(3), evalsigne(-1) | evallgefint(3), 0 };
                    172:
                    173: void
                    174: affir(GEN x, GEN y)
                    175: {
                    176:   const long s=signe(x),ly=lg(y);
                    177:   long lx,sh,i;
                    178:
                    179:   if (!s)
                    180:   {
                    181:     y[1] = evalexpo(-bit_accuracy(ly));
                    182:     y[2] = 0; return;
                    183:   }
                    184:
                    185:   lx=lgefint(x); sh=bfffo(x[2]);
                    186:   y[1] = evalsigne(s) | evalexpo(bit_accuracy(lx)-sh-1);
                    187:   if (sh)
                    188:   {
                    189:     if (lx>ly)
                    190:     { shift_left(y,x,2,ly-1, x[ly],sh); }
                    191:     else
                    192:     {
                    193:       for (i=lx; i<ly; i++) y[i]=0;
                    194:       shift_left(y,x,2,lx-1, 0,sh);
                    195:     }
                    196:     return;
                    197:   }
                    198:
                    199:   if (lx>=ly)
                    200:     for (i=2; i<ly; i++) y[i]=x[i];
                    201:   else
                    202:   {
                    203:     for (i=2; i<lx; i++) y[i]=x[i];
                    204:     for (   ; i<ly; i++) y[i]=0;
                    205:   }
                    206: }
                    207:
                    208: void
                    209: affrr(GEN x, GEN y)
                    210: {
                    211:   long lx,ly,i;
                    212:
                    213:   y[1] = x[1]; if (!signe(x)) { y[2]=0; return; }
                    214:
                    215:   lx=lg(x); ly=lg(y);
                    216:   if (lx>=ly)
                    217:     for (i=2; i<ly; i++) y[i]=x[i];
                    218:   else
                    219:   {
                    220:     for (i=2; i<lx; i++) y[i]=x[i];
                    221:     for (   ; i<ly; i++) y[i]=0;
                    222:   }
                    223: }
                    224:
                    225: GEN
                    226: shifti(GEN x, long n)
                    227: {
                    228:   const long s=signe(x);
                    229:   long lx,ly,i,m;
                    230:   GEN y;
                    231:
                    232:   if (!s) return gzero;
                    233:   if (!n) return icopy(x);
                    234:   lx = lgefint(x);
                    235:   if (n > 0)
                    236:   {
                    237:     GEN z = (GEN)avma;
                    238:     long d = n>>TWOPOTBITS_IN_LONG;
                    239:
                    240:     ly = lx+d; y = new_chunk(ly);
                    241:     for ( ; d; d--) *--z = 0;
                    242:     m = n & (BITS_IN_LONG-1);
                    243:     if (!m) for (i=2; i<lx; i++) y[i]=x[i];
                    244:     else
                    245:     {
                    246:       register const ulong sh = BITS_IN_LONG - m;
                    247:       shift_left2(y,x, 2,lx-1, 0,m,sh);
                    248:       i = ((ulong)x[2]) >> sh;
                    249:       if (i) { ly++; y = new_chunk(1); y[2] = i; }
                    250:     }
                    251:   }
                    252:   else
                    253:   {
                    254:     n = -n;
                    255:     ly = lx - (n>>TWOPOTBITS_IN_LONG);
                    256:     if (ly<3) return gzero;
                    257:     y = new_chunk(ly);
                    258:     m = n & (BITS_IN_LONG-1);
                    259:     if (!m) for (i=2; i<ly; i++) y[i]=x[i];
                    260:     else
                    261:     {
                    262:       shift_right(y,x, 2,ly, 0,m);
                    263:       if (y[2] == 0)
                    264:       {
                    265:         if (ly==3) { avma = (long)(y+3); return gzero; }
                    266:         ly--; avma = (long)(++y);
                    267:       }
                    268:     }
                    269:   }
                    270:   y[1] = evalsigne(s)|evallgefint(ly);
                    271:   y[0] = evaltyp(t_INT)|evallg(ly); return y;
                    272: }
                    273:
                    274: GEN
                    275: mptrunc(GEN x)
                    276: {
                    277:   long d,e,i,s,m;
                    278:   GEN y;
                    279:
                    280:   if (typ(x)==t_INT) return icopy(x);
                    281:   if ((s=signe(x)) == 0 || (e=expo(x)) < 0) return gzero;
                    282:   d = (e>>TWOPOTBITS_IN_LONG) + 3;
                    283:   m = e & (BITS_IN_LONG-1);
                    284:   if (d > lg(x)) err(truer2);
                    285:
                    286:   y=cgeti(d); y[1] = evalsigne(s) | evallgefint(d);
                    287:   if (++m == BITS_IN_LONG)
                    288:     for (i=2; i<d; i++) y[i]=x[i];
                    289:   else
                    290:   {
                    291:     const register ulong sh = BITS_IN_LONG - m;
                    292:     shift_right2(y,x, 2,d,0, sh,m);
                    293:   }
                    294:   return y;
                    295: }
                    296:
                    297: /* integral part */
                    298: GEN
                    299: mpent(GEN x)
                    300: {
                    301:   long d,e,i,lx,m;
                    302:   GEN y;
                    303:
                    304:   if (typ(x)==t_INT) return icopy(x);
                    305:   if (signe(x) >= 0) return mptrunc(x);
                    306:   if ((e=expo(x)) < 0) return stoi(-1);
                    307:   d = (e>>TWOPOTBITS_IN_LONG) + 3;
                    308:   m = e & (BITS_IN_LONG-1);
                    309:   lx=lg(x); if (d>lx) err(truer2);
                    310:   y = new_chunk(d);
                    311:   if (++m == BITS_IN_LONG)
                    312:   {
                    313:     for (i=2; i<d; i++) y[i]=x[i];
                    314:     i=d; while (i<lx && !x[i]) i++;
                    315:     if (i==lx) goto END;
                    316:   }
                    317:   else
                    318:   {
                    319:     const register ulong sh = BITS_IN_LONG - m;
                    320:     shift_right2(y,x, 2,d,0, sh,m);
                    321:     if (x[d-1]<<m == 0)
                    322:     {
                    323:       i=d; while (i<lx && !x[i]) i++;
                    324:       if (i==lx) goto END;
                    325:     }
                    326:   }
                    327:   /* set y:=y+1 */
                    328:   for (i=d-1; i>=2; i--) { y[i]++; if (y[i]) goto END; }
                    329:   y=new_chunk(1); y[2]=1; d++;
                    330: END:
                    331:   y[1] = evalsigne(-1) | evallgefint(d);
                    332:   y[0] = evaltyp(t_INT) | evallg(d); return y;
                    333: }
                    334:
                    335: int
                    336: cmpsi(long x, GEN y)
                    337: {
                    338:   ulong p;
                    339:
                    340:   if (!x) return -signe(y);
                    341:
                    342:   if (x>0)
                    343:   {
                    344:     if (signe(y)<=0) return 1;
                    345:     if (lgefint(y)>3) return -1;
                    346:     p=y[2]; if (p == (ulong)x) return 0;
                    347:     return p < (ulong)x ? 1 : -1;
                    348:   }
                    349:
                    350:   if (signe(y)>=0) return -1;
                    351:   if (lgefint(y)>3) return 1;
                    352:   p=y[2]; if (p == (ulong)-x) return 0;
                    353:   return p < (ulong)(-x) ? -1 : 1;
                    354: }
                    355:
                    356: int
                    357: cmpii(GEN x, GEN y)
                    358: {
                    359:   const long sx = signe(x), sy = signe(y);
                    360:   long lx,ly,i;
                    361:
                    362:   if (sx<sy) return -1;
                    363:   if (sx>sy) return 1;
                    364:   if (!sx) return 0;
                    365:
                    366:   lx=lgefint(x); ly=lgefint(y);
                    367:   if (lx>ly) return sx;
                    368:   if (lx<ly) return -sx;
                    369:   i=2; while (i<lx && x[i]==y[i]) i++;
                    370:   if (i==lx) return 0;
                    371:   return ((ulong)x[i] > (ulong)y[i]) ? sx : -sx;
                    372: }
                    373:
                    374: int
                    375: cmprr(GEN x, GEN y)
                    376: {
                    377:   const long sx = signe(x), sy = signe(y);
                    378:   long ex,ey,lx,ly,lz,i;
                    379:
                    380:   if (sx<sy) return -1;
                    381:   if (sx>sy) return 1;
                    382:   if (!sx) return 0;
                    383:
                    384:   ex=expo(x); ey=expo(y);
                    385:   if (ex>ey) return sx;
                    386:   if (ex<ey) return -sx;
                    387:
                    388:   lx=lg(x); ly=lg(y); lz = (lx<ly)?lx:ly;
                    389:   i=2; while (i<lz && x[i]==y[i]) i++;
                    390:   if (i<lz) return ((ulong)x[i] > (ulong)y[i]) ? sx : -sx;
                    391:   if (lx>=ly)
                    392:   {
                    393:     while (i<lx && !x[i]) i++;
                    394:     return (i==lx) ? 0 : sx;
                    395:   }
                    396:   while (i<ly && !y[i]) i++;
                    397:   return (i==ly) ? 0 : -sx;
                    398: }
                    399:
                    400: GEN
                    401: addss(long x, long y)
                    402: {
                    403:   if (!x) return stoi(y);
                    404:   if (x>0) { pos_s[2] = x; return addsi(y,pos_s); }
                    405:   neg_s[2] = -x; return addsi(y,neg_s);
                    406: }
                    407:
                    408: GEN
                    409: addsi(long x, GEN y)
                    410: {
                    411:   long sx,sy,ly;
                    412:   GEN z;
                    413:
                    414:   if (!x) return icopy(y);
                    415:   sy=signe(y); if (!sy) return stoi(x);
                    416:   if (x<0) { sx=-1; x=-x; } else sx=1;
                    417:   if (sx==sy)
                    418:   {
                    419:     z = addsispec(x,y+2, lgefint(y)-2);
                    420:     setsigne(z,sy); return z;
                    421:   }
                    422:   ly=lgefint(y);
                    423:   if (ly==3)
                    424:   {
                    425:     const long d = y[2] - x;
                    426:     if (!d) return gzero;
                    427:     z=cgeti(3);
                    428:     if (y[2] < 0 || d > 0) {
                    429:       z[1] = evalsigne(sy) | evallgefint(3);
                    430:       z[2] = d;
                    431:     }
                    432:     else {
                    433:       z[1] = evalsigne(-sy) | evallgefint(3);
                    434:       z[2] =-d;
                    435:     }
                    436:     return z;
                    437:   }
                    438:   z = subisspec(y+2,x, ly-2);
                    439:   setsigne(z,sy); return z;
                    440: }
                    441:
                    442: GEN
                    443: addii(GEN x, GEN y)
                    444: {
                    445:   long sx = signe(x);
                    446:   long sy = signe(y);
                    447:   long lx,ly;
                    448:   GEN z;
                    449:
                    450:   if (!sx) return sy? icopy(y): gzero;
                    451:   if (!sy) return icopy(x);
                    452:   lx=lgefint(x); ly=lgefint(y);
                    453:
                    454:   if (sx==sy)
                    455:     z = addiispec(x+2,y+2,lx-2,ly-2);
                    456:   else
                    457:   { /* sx != sy */
                    458:     long i = lx - ly;
                    459:     if (i==0)
                    460:     {
                    461:       i = absi_cmp(x,y);
                    462:       if (!i) return gzero;
                    463:     }
                    464:     if (i<0) { sx=sy; swapspec(x,y, lx,ly); } /* ensure |x| >= |y| */
                    465:     z = subiispec(x+2,y+2,lx-2,ly-2);
                    466:   }
                    467:   setsigne(z,sx); return z;
                    468: }
                    469:
                    470: GEN
                    471: addsr(long x, GEN y)
                    472: {
                    473:   if (!x) return rcopy(y);
                    474:   if (x>0) { pos_s[2]=x; return addir(pos_s,y); }
                    475:   neg_s[2] = -x; return addir(neg_s,y);
                    476: }
                    477:
                    478: GEN
                    479: addir(GEN x, GEN y)
                    480: {
                    481:   long e,l,ly;
                    482:   GEN z;
                    483:
                    484:   if (!signe(x)) return rcopy(y);
                    485:   if (!signe(y))
                    486:   {
                    487:     l=lgefint(x)-(expo(y)>>TWOPOTBITS_IN_LONG);
                    488:     if (l<3) err(adder3);
                    489:     z=cgetr(l); affir(x,z); return z;
                    490:   }
                    491:
                    492:   e = expo(y)-expi(x); ly=lg(y);
                    493:   if (e>0)
                    494:   {
                    495:     l = ly - (e>>TWOPOTBITS_IN_LONG);
                    496:     if (l<3) return rcopy(y);
                    497:   }
                    498:   else l = ly + ((-e)>>TWOPOTBITS_IN_LONG)+1;
                    499:   z=cgetr(l); affir(x,z); y=addrr(z,y);
                    500:   z = y+l; ly = lg(y); while (ly--) z[ly] = y[ly];
                    501:   avma=(long)z; return z;
                    502: }
                    503:
                    504: GEN
                    505: addrr(GEN x, GEN y)
                    506: {
                    507:   long sx=signe(x),sy=signe(y),ex=expo(x),ey=expo(y);
                    508:   long e,m,flag,i,j,f2,lx,ly,lz;
                    509:   GEN z;
                    510:   LOCAL_OVERFLOW;
                    511:
                    512:   e = ey-ex;
                    513:   if (!sy)
                    514:   {
                    515:     if (!sx)
                    516:     {
                    517:       if (e > 0) ex=ey;
                    518:       z=cgetr(3); z[1]=evalexpo(ex); z[2]=0; return z;
                    519:     }
                    520:     if (e > 0) { z=cgetr(3); z[1]=evalexpo(ey); z[2]=0; return z; }
                    521:     lz = 3 + ((-e)>>TWOPOTBITS_IN_LONG);
                    522:     lx = lg(x); if (lz>lx) lz=lx;
                    523:     z = cgetr(lz); while(--lz) z[lz]=x[lz];
                    524:     return z;
                    525:   }
                    526:   if (!sx)
                    527:   {
                    528:     if (e < 0) { z=cgetr(3); z[1]=evalexpo(ex); z[2]=0; return z; }
                    529:     lz = 3 + (e>>TWOPOTBITS_IN_LONG);
                    530:     ly = lg(y); if (lz>ly) lz=ly;
                    531:     z = cgetr(lz); while (--lz) z[lz]=y[lz];
                    532:     return z;
                    533:   }
                    534:
                    535:   if (e < 0) { z=x; x=y; y=z; ey=ex; i=sx; sx=sy; sy=i; e=-e; }
                    536:   /* now ey >= ex */
                    537:   lx=lg(x); ly=lg(y);
                    538:   if (e)
                    539:   {
                    540:     long d = e >> TWOPOTBITS_IN_LONG, l = ly-d;
                    541:     if (l > lx)     { flag=0; lz=lx+d+1; }
                    542:     else if (l > 2) { flag=1; lz=ly; lx=l; }
                    543:     else return rcopy(y);
                    544:     m = e & (BITS_IN_LONG-1);
                    545:   }
                    546:   else
                    547:   {
                    548:     if (lx > ly) lx = ly;
                    549:     flag=2; lz=lx; m=0;
                    550:   }
                    551:   z = cgetr(lz);
                    552:   if (m)
                    553:   { /* shift right x m bits */
                    554:     const ulong sh = BITS_IN_LONG-m;
                    555:     GEN p1 = x; x = new_chunk(lx+1);
                    556:     shift_right2(x,p1,2,lx, 0,m,sh);
                    557:     if (flag==0)
                    558:     {
                    559:       x[lx] = p1[lx-1] << sh;
                    560:       if (x[lx]) { flag = 3; lx++; }
                    561:     }
                    562:   }
                    563:
                    564:   if (sx==sy)
                    565:   { /* addition */
                    566:     i=lz-1; avma = (long)z;
                    567:     if (flag==0) { z[i] = y[i]; i--; }
                    568:     overflow=0;
                    569:     for (j=lx-1; j>=2; i--,j--) z[i] = addllx(x[j],y[i]);
                    570:
                    571:     if (overflow)
                    572:       for (;;)
                    573:       {
                    574:         if (i==1)
                    575:         {
                    576:           shift_right(z,z, 2,lz, 1,1);
                    577:           ey=evalexpo(ey+1); if (ey & ~EXPOBITS) err(adder4);
                    578:           z[1] = evalsigne(sx) | ey; return z;
                    579:         }
                    580:         z[i] = y[i]+1; if (z[i--]) break;
                    581:       }
                    582:     for (; i>=2; i--) z[i]=y[i];
                    583:     z[1] = evalsigne(sx) | evalexpo(ey); return z;
                    584:   }
                    585:
                    586:   /* subtraction */
                    587:   if (e) f2 = 1;
                    588:   else
                    589:   {
                    590:     i=2; while (i<lx && x[i]==y[i]) i++;
                    591:     if (i==lx)
                    592:     {
                    593:       avma = (long)(z+lz);
                    594:       e = evalexpo(ey - bit_accuracy(lx));
                    595:       if (e & ~EXPOBITS) err(adder4);
                    596:       z=cgetr(3); z[1]=e; z[2]=0; return z;
                    597:     }
                    598:     f2 = ((ulong)y[i] > (ulong)x[i]);
                    599:   }
                    600:
                    601:   /* result is non-zero. f2 = (y > x) */
                    602:   i=lz-1;
                    603:   if (f2)
                    604:   {
                    605:     if (flag==0) { z[i] = y[i]; i--; }
                    606:     j=lx-1; z[i] = subll(y[i],x[j]); i--; j--;
                    607:     for (; j>=2; i--,j--) z[i] = subllx(y[i],x[j]);
                    608:     if (overflow)
                    609:       for (;;) { z[i] = y[i]-1; if (y[i--]) break; }
                    610:     for (; i>=2; i--) z[i]=y[i];
                    611:     sx = sy;
                    612:   }
                    613:   else
                    614:   {
                    615:     if (flag==0) { z[i] = -y[i]; i--; overflow=1; } else overflow=0;
                    616:     for (; i>=2; i--) z[i]=subllx(x[i],y[i]);
                    617:   }
                    618:
                    619:   x = z+2; i=0; while (!x[i]) i++;
                    620:   lz -= i; z += i; m = bfffo(z[2]);
                    621:   e = evalexpo(ey - (m | (i<<TWOPOTBITS_IN_LONG)));
                    622:   if (e & ~EXPOBITS) err(adder5);
                    623:   if (m) shift_left(z,z,2,lz-1, 0,m);
                    624:   z[1] = evalsigne(sx) | e;
                    625:   z[0] = evaltyp(t_REAL) | evallg(lz);
                    626:   avma = (long)z; return z;
                    627: }
                    628:
                    629: GEN
                    630: mulss(long x, long y)
                    631: {
                    632:   long s,p1;
                    633:   GEN z;
                    634:   LOCAL_HIREMAINDER;
                    635:
                    636:   if (!x || !y) return gzero;
                    637:   if (x<0) { s = -1; x = -x; } else s=1;
                    638:   if (y<0) { s = -s; y = -y; }
                    639:   p1 = mulll(x,y);
                    640:   if (hiremainder)
                    641:   {
                    642:     z=cgeti(4); z[1] = evalsigne(s) | evallgefint(4);
                    643:     z[2]=hiremainder; z[3]=p1; return z;
                    644:   }
                    645:   z=cgeti(3); z[1] = evalsigne(s) | evallgefint(3);
                    646:   z[2]=p1; return z;
                    647: }
                    648: #endif
                    649:
                    650: GEN
                    651: muluu(ulong x, ulong y)
                    652: {
                    653:   long p1;
                    654:   GEN z;
                    655:   LOCAL_HIREMAINDER;
                    656:
                    657:   if (!x || !y) return gzero;
                    658:   p1 = mulll(x,y);
                    659:   if (hiremainder)
                    660:   {
                    661:     z=cgeti(4); z[1] = evalsigne(1) | evallgefint(4);
                    662:     z[2]=hiremainder; z[3]=p1; return z;
                    663:   }
                    664:   z=cgeti(3); z[1] = evalsigne(1) | evallgefint(3);
                    665:   z[2]=p1; return z;
                    666: }
                    667:
                    668: /* assume ny > 0 */
                    669: #ifdef INLINE
                    670: INLINE
                    671: #endif
                    672: GEN
                    673: mulsispec(long x, GEN y, long ny)
                    674: {
                    675:   GEN yd, z = (GEN)avma;
                    676:   long lz = ny+3;
                    677:   LOCAL_HIREMAINDER;
                    678:
                    679:   (void)new_chunk(lz);
                    680:   yd = y + ny; *--z = mulll(x, *--yd);
                    681:   while (yd > y) *--z = addmul(x,*--yd);
                    682:   if (hiremainder) *--z = hiremainder; else lz--;
                    683:   *--z = evalsigne(1) | evallgefint(lz);
                    684:   *--z = evaltyp(t_INT) | evallg(lz);
                    685:   avma=(long)z; return z;
                    686: }
                    687:
                    688: GEN
                    689: mului(ulong x, GEN y)
                    690: {
                    691:   long s = signe(y);
                    692:   GEN z;
                    693:
                    694:   if (!s || !x) return gzero;
                    695:   z = mulsispec(x, y+2, lgefint(y)-2);
                    696:   setsigne(z,s); return z;
                    697: }
                    698:
                    699: #ifndef __M68K__
                    700:
                    701: GEN
                    702: mulsi(long x, GEN y)
                    703: {
                    704:   long s = signe(y);
                    705:   GEN z;
                    706:
                    707:   if (!s || !x) return gzero;
                    708:   if (x<0) { s = -s; x = -x; }
                    709:   z = mulsispec(x, y+2, lgefint(y)-2);
                    710:   setsigne(z,s); return z;
                    711: }
                    712:
                    713: GEN
                    714: mulsr(long x, GEN y)
                    715: {
                    716:   long lx,i,s,garde,e,sh,m;
                    717:   GEN z;
                    718:   LOCAL_HIREMAINDER;
                    719:
                    720:   if (!x) return gzero;
                    721:   s = signe(y);
                    722:   if (!s)
                    723:   {
                    724:     if (x<0) x = -x;
                    725:     e = y[1] + (BITS_IN_LONG-1)-bfffo(x);
                    726:     if (e & ~EXPOBITS) err(muler2);
                    727:     z=cgetr(3); z[1]=e; z[2]=0; return z;
                    728:   }
                    729:   if (x<0) { s = -s; x = -x; }
                    730:   if (x==1) { z=rcopy(y); setsigne(z,s); return z; }
                    731:
                    732:   lx = lg(y); e = expo(y);
                    733:   z=cgetr(lx); y--; garde=mulll(x,y[lx]);
                    734:   for (i=lx-1; i>=3; i--) z[i]=addmul(x,y[i]);
                    735:   z[2]=hiremainder;
                    736:
                    737:   sh = bfffo(hiremainder); m = BITS_IN_LONG-sh;
                    738:   if (sh) shift_left2(z,z, 2,lx-1, garde,sh,m);
                    739:   e = evalexpo(m+e); if (e & ~EXPOBITS) err(muler2);
                    740:   z[1] = evalsigne(s) | e; return z;
                    741: }
                    742:
                    743: GEN
                    744: mulrr(GEN x, GEN y)
                    745: {
                    746:   long sx = signe(x), sy = signe(y);
                    747:   long i,j,ly,lz,lzz,e,flag,p1;
                    748:   ulong garde;
                    749:   GEN z, y1;
                    750:   LOCAL_HIREMAINDER;
                    751:   LOCAL_OVERFLOW;
                    752:
                    753:   e = evalexpo(expo(x)+expo(y)); if (e & ~EXPOBITS) err(muler4);
                    754:   if (!sx || !sy) { z=cgetr(3); z[1]=e; z[2]=0; return z; }
                    755:   if (sy<0) sx = -sx;
                    756:   lz=lg(x); ly=lg(y);
                    757:   if (lz>ly) { lz=ly; z=x; x=y; y=z; flag=1; } else flag = (lz!=ly);
                    758:   z=cgetr(lz); z[1] = evalsigne(sx) | e;
                    759:   if (lz==3)
                    760:   {
                    761:     if (flag)
                    762:     {
                    763:       (void)mulll(x[2],y[3]);
                    764:       garde = addmul(x[2],y[2]);
                    765:     }
                    766:     else
                    767:       garde = mulll(x[2],y[2]);
                    768:     if ((long)hiremainder<0) { z[2]=hiremainder; z[1]++; }
                    769:     else z[2]=(hiremainder<<1) | (garde>>(BITS_IN_LONG-1));
                    770:     return z;
                    771:   }
                    772:
                    773:   if (flag) { (void)mulll(x[2],y[lz]); garde = hiremainder; } else garde=0;
                    774:   lzz=lz-1; p1=x[lzz];
                    775:   if (p1)
                    776:   {
                    777:     (void)mulll(p1,y[3]);
                    778:     garde = addll(addmul(p1,y[2]), garde);
                    779:     z[lzz] = overflow+hiremainder;
                    780:   }
                    781:   else z[lzz]=0;
                    782:   for (j=lz-2, y1=y-j; j>=3; j--)
                    783:   {
                    784:     p1 = x[j]; y1++;
                    785:     if (p1)
                    786:     {
                    787:       (void)mulll(p1,y1[lz+1]);
                    788:       garde = addll(addmul(p1,y1[lz]), garde);
                    789:       for (i=lzz; i>j; i--)
                    790:       {
                    791:         hiremainder += overflow;
                    792:        z[i] = addll(addmul(p1,y1[i]), z[i]);
                    793:       }
                    794:       z[j] = hiremainder+overflow;
                    795:     }
                    796:     else z[j]=0;
                    797:   }
                    798:   p1=x[2]; y1++;
                    799:   garde = addll(mulll(p1,y1[lz]), garde);
                    800:   for (i=lzz; i>2; i--)
                    801:   {
                    802:     hiremainder += overflow;
                    803:     z[i] = addll(addmul(p1,y1[i]), z[i]);
                    804:   }
                    805:   z[2] = hiremainder+overflow;
                    806:   if (z[2] < 0) z[1]++;
                    807:   else
                    808:     shift_left(z,z,2,lzz,garde, 1);
                    809:   return z;
                    810: }
                    811:
                    812: GEN
                    813: mulir(GEN x, GEN y)
                    814: {
                    815:   long sx=signe(x),sy,lz,lzz,ey,e,p1,i,j;
                    816:   ulong garde;
                    817:   GEN z,y1;
                    818:   LOCAL_HIREMAINDER;
                    819:   LOCAL_OVERFLOW;
                    820:
                    821:   if (!sx) return gzero;
                    822:   if (!is_bigint(x)) return mulsr(itos(x),y);
                    823:   sy=signe(y); ey=expo(y);
                    824:   if (!sy)
                    825:   {
                    826:     e = evalexpo(expi(x)+ey);
                    827:     if (e & ~EXPOBITS) err(muler6);
                    828:     z=cgetr(3); z[1]=e; z[2]=0; return z;
                    829:   }
                    830:
                    831:   if (sy<0) sx = -sx;
                    832:   lz=lg(y); z=cgetr(lz);
                    833:   y1=cgetr(lz+1);
                    834:   affir(x,y1); x=y; y=y1;
                    835:   e = evalexpo(expo(y)+ey);
                    836:   if (e & ~EXPOBITS) err(muler4);
                    837:   z[1] = evalsigne(sx) | e;
                    838:   if (lz==3)
                    839:   {
                    840:     (void)mulll(x[2],y[3]);
                    841:     garde=addmul(x[2],y[2]);
                    842:     if ((long)hiremainder < 0) { z[2]=hiremainder; z[1]++; }
                    843:     else z[2]=(hiremainder<<1) | (garde>>(BITS_IN_LONG-1));
                    844:     avma=(long)z; return z;
                    845:   }
                    846:
                    847:   (void)mulll(x[2],y[lz]); garde=hiremainder;
                    848:   lzz=lz-1; p1=x[lzz];
                    849:   if (p1)
                    850:   {
                    851:     (void)mulll(p1,y[3]);
                    852:     garde=addll(addmul(p1,y[2]),garde);
                    853:     z[lzz] = overflow+hiremainder;
                    854:   }
                    855:   else z[lzz]=0;
                    856:   for (j=lz-2, y1=y-j; j>=3; j--)
                    857:   {
                    858:     p1=x[j]; y1++;
                    859:     if (p1)
                    860:     {
                    861:       (void)mulll(p1,y1[lz+1]);
                    862:       garde = addll(addmul(p1,y1[lz]), garde);
                    863:       for (i=lzz; i>j; i--)
                    864:       {
                    865:         hiremainder += overflow;
                    866:         z[i] = addll(addmul(p1,y1[i]), z[i]);
                    867:       }
                    868:       z[j] = hiremainder+overflow;
                    869:     }
                    870:     else z[j]=0;
                    871:   }
                    872:   p1=x[2]; y1++;
                    873:   garde = addll(mulll(p1,y1[lz]), garde);
                    874:   for (i=lzz; i>2; i--)
                    875:   {
                    876:     hiremainder += overflow;
                    877:     z[i] = addll(addmul(p1,y1[i]), z[i]);
                    878:   }
                    879:   z[2] = hiremainder+overflow;
                    880:   if (z[2] < 0) z[1]++;
                    881:   else
                    882:     shift_left(z,z,2,lzz,garde, 1);
                    883:   avma=(long)z; return z;
                    884: }
                    885:
                    886: /* written by Bruno Haible following an idea of Robert Harley */
                    887: long
                    888: vals(ulong z)
                    889: {
                    890:   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};
                    891: #ifdef LONG_IS_64BIT
                    892:   long s;
                    893: #endif
                    894:
                    895:   if (!z) return -1;
                    896: #ifdef LONG_IS_64BIT
                    897:   if (! (z&0xffffffff)) { s = 32; z >>=32; } else s = 0;
                    898: #endif
                    899:   z |= ~z + 1;
                    900:   z += z << 4;
                    901:   z += z << 6;
                    902:   z ^= z << 16; /* or  z -= z<<16 */
                    903: #ifdef LONG_IS_64BIT
                    904:   return s + tab[(z&0xffffffff)>>26];
                    905: #else
                    906:   return tab[z>>26];
                    907: #endif
                    908: }
                    909:
                    910: GEN
                    911: modss(long x, long y)
                    912: {
                    913:   LOCAL_HIREMAINDER;
                    914:
                    915:   if (!y) err(moder1);
                    916:   if (y<0) y=-y;
                    917:   hiremainder=0; divll(labs(x),y);
                    918:   if (!hiremainder) return gzero;
                    919:   return (x < 0) ? stoi(y-hiremainder) : stoi(hiremainder);
                    920: }
                    921:
                    922: GEN
                    923: resss(long x, long y)
                    924: {
                    925:   LOCAL_HIREMAINDER;
                    926:
                    927:   if (!y) err(reser1);
                    928:   hiremainder=0; divll(labs(x),labs(y));
                    929:   return (x < 0) ? stoi(-((long)hiremainder)) : stoi(hiremainder);
                    930: }
                    931:
                    932: GEN
                    933: divsi(long x, GEN y)
                    934: {
                    935:   long p1, s = signe(y);
                    936:   LOCAL_HIREMAINDER;
                    937:
                    938:   if (!s) err(diver2);
                    939:   if (!x || lgefint(y)>3 || ((long)y[2])<0)
                    940:   {
                    941:     hiremainder=x; SAVE_HIREMAINDER; return gzero;
                    942:   }
                    943:   hiremainder=0; p1=divll(labs(x),y[2]);
                    944:   if (x<0) { hiremainder = -((long)hiremainder); p1 = -p1; }
                    945:   if (s<0) p1 = -p1;
                    946:   SAVE_HIREMAINDER; return stoi(p1);
                    947: }
                    948: #endif
                    949:
                    950: GEN
                    951: modui(ulong x, GEN y)
                    952: {
                    953:   LOCAL_HIREMAINDER;
                    954:
                    955:   if (!signe(y)) err(diver2);
                    956:   if (!x || lgefint(y)>3) hiremainder=x;
                    957:   else
                    958:   {
                    959:     hiremainder=0; (void)divll(x,y[2]);
                    960:   }
                    961:   return utoi(hiremainder);
                    962: }
                    963:
                    964: GEN
                    965: modiu(GEN y, ulong x)
                    966: {
                    967:   long sy=signe(y),ly,i;
                    968:   LOCAL_HIREMAINDER;
                    969:
                    970:   if (!x) err(diver4);
                    971:   if (!sy) return gzero;
                    972:   ly = lgefint(y);
                    973:   if (x <= (ulong)y[2]) hiremainder=0;
                    974:   else
                    975:   {
                    976:     if (ly==3) return utoi((sy > 0)? (ulong)y[2]: x - (ulong)y[2]);
                    977:     hiremainder=y[2]; ly--; y++;
                    978:   }
                    979:   for (i=2; i<ly; i++) (void)divll(y[i],x);
                    980:   return utoi((sy > 0)? hiremainder: x - hiremainder);
                    981: }
                    982:
                    983: #ifndef __M68K__
                    984:
                    985: GEN
                    986: modsi(long x, GEN y)
                    987: {
                    988:   long s = signe(y);
                    989:   GEN p1;
                    990:   LOCAL_HIREMAINDER;
                    991:
                    992:   if (!s) err(diver2);
                    993:   if (!x || lgefint(y)>3 || ((long)y[2])<0) hiremainder=x;
                    994:   else
                    995:   {
                    996:     hiremainder=0; (void)divll(labs(x),y[2]);
                    997:     if (x<0) hiremainder = -((long)hiremainder);
                    998:   }
                    999:   if (!hiremainder) return gzero;
                   1000:   if (x>0) return stoi(hiremainder);
                   1001:   if (s<0)
                   1002:     { setsigne(y,1); p1=addsi(hiremainder,y); setsigne(y,-1); }
                   1003:   else
                   1004:     p1=addsi(hiremainder,y);
                   1005:   return p1;
                   1006: }
                   1007:
                   1008: GEN
                   1009: divis(GEN y, long x)
                   1010: {
                   1011:   long sy=signe(y),ly,s,i;
                   1012:   GEN z;
                   1013:   LOCAL_HIREMAINDER;
                   1014:
                   1015:   if (!x) err(diver4);
                   1016:   if (!sy) { hiremainder=0; SAVE_HIREMAINDER; return gzero; }
                   1017:   if (x<0) { s = -sy; x = -x; } else s=sy;
                   1018:
                   1019:   ly = lgefint(y);
                   1020:   if ((ulong)x <= (ulong)y[2]) hiremainder=0;
                   1021:   else
                   1022:   {
                   1023:     if (ly==3) { hiremainder=itos(y); SAVE_HIREMAINDER; return gzero; }
                   1024:     hiremainder=y[2]; ly--; y++;
                   1025:   }
                   1026:   z = cgeti(ly); z[1] = evallgefint(ly) | evalsigne(s);
                   1027:   for (i=2; i<ly; i++) z[i]=divll(y[i],x);
                   1028:   if (sy<0) hiremainder = - ((long)hiremainder);
                   1029:   SAVE_HIREMAINDER; return z;
                   1030: }
                   1031:
                   1032: GEN
                   1033: divir(GEN x, GEN y)
                   1034: {
                   1035:   GEN xr,z;
                   1036:   long av,ly;
                   1037:
                   1038:   if (!signe(y)) err(diver5);
                   1039:   if (!signe(x)) return gzero;
                   1040:   ly=lg(y); z=cgetr(ly); av=avma; xr=cgetr(ly+1); affir(x,xr);
                   1041:   affrr(divrr(xr,y),z); avma=av; return z;
                   1042: }
                   1043:
                   1044: GEN
                   1045: divri(GEN x, GEN y)
                   1046: {
                   1047:   GEN yr,z;
                   1048:   long av,lx,s=signe(y);
                   1049:
                   1050:   if (!s) err(diver8);
                   1051:   if (!signe(x))
                   1052:   {
                   1053:     const long ex = evalexpo(expo(x) - expi(y));
                   1054:
                   1055:     if (ex<0) err(diver12);
                   1056:     z=cgetr(3); z[1]=ex; z[2]=0; return z;
                   1057:   }
                   1058:   if (!is_bigint(y)) return divrs(x, s>0? y[2]: -y[2]);
                   1059:
                   1060:   lx=lg(x); z=cgetr(lx);
                   1061:   av=avma; yr=cgetr(lx+1); affir(y,yr);
                   1062:   affrr(divrr(x,yr),z); avma=av; return z;
                   1063: }
                   1064:
                   1065: void
                   1066: diviiz(GEN x, GEN y, GEN z)
                   1067: {
                   1068:   long av=avma,lz;
                   1069:   GEN xr,yr;
                   1070:
                   1071:   if (typ(z)==t_INT) { affii(divii(x,y),z); avma=av; return; }
                   1072:   lz=lg(z); xr=cgetr(lz); affir(x,xr); yr=cgetr(lz); affir(y,yr);
                   1073:   affrr(divrr(xr,yr),z); avma=av;
                   1074: }
                   1075:
                   1076: void
                   1077: mpdivz(GEN x, GEN y, GEN z)
                   1078: {
                   1079:   long av=avma;
                   1080:
                   1081:   if (typ(z)==t_INT)
                   1082:   {
                   1083:     if (typ(x)==t_REAL || typ(y)==t_REAL) err(divzer1);
                   1084:     affii(divii(x,y),z); avma=av; return;
                   1085:   }
                   1086:   if (typ(x)==t_INT)
                   1087:   {
                   1088:     GEN xr,yr;
                   1089:     long lz;
                   1090:
                   1091:     if (typ(y)==t_REAL) { affrr(divir(x,y),z); avma=av; return; }
                   1092:     lz=lg(z); xr=cgetr(lz); affir(x,xr); yr=cgetr(lz); affir(y,yr);
                   1093:     affrr(divrr(xr,yr),z); avma=av; return;
                   1094:   }
                   1095:   if (typ(y)==t_REAL) { affrr(divrr(x,y),z); avma=av; return; }
                   1096:   affrr(divri(x,y),z); avma=av;
                   1097: }
                   1098:
                   1099: GEN
                   1100: divsr(long x, GEN y)
                   1101: {
                   1102:   long av,ly;
                   1103:   GEN p1,z;
                   1104:
                   1105:   if (!signe(y)) err(diver3);
                   1106:   if (!x) return gzero;
                   1107:   ly=lg(y); z=cgetr(ly); av=avma;
                   1108:   p1=cgetr(ly+1); affsr(x,p1); affrr(divrr(p1,y),z);
                   1109:   avma=av; return z;
                   1110: }
                   1111:
                   1112: GEN
                   1113: modii(GEN x, GEN y)
                   1114: {
                   1115:   switch(signe(x))
                   1116:   {
                   1117:     case 0: return gzero;
                   1118:     case 1: return resii(x,y);
                   1119:     default:
                   1120:     {
                   1121:       long av = avma;
                   1122:       (void)new_chunk(lgefint(y));
                   1123:       x = resii(x,y); avma=av;
                   1124:       if (x==gzero) return x;
                   1125:       return subiispec(y+2,x+2,lgefint(y)-2,lgefint(x)-2);
                   1126:     }
                   1127:   }
                   1128: }
                   1129:
                   1130: void
                   1131: modiiz(GEN x, GEN y, GEN z)
                   1132: {
                   1133:   const long av = avma;
                   1134:   affii(modii(x,y),z); avma=av;
                   1135: }
                   1136:
                   1137: GEN
                   1138: divrs(GEN x, long y)
                   1139: {
                   1140:   long i,lx,ex,garde,sh,s=signe(x);
                   1141:   GEN z;
                   1142:   LOCAL_HIREMAINDER;
                   1143:
                   1144:   if (!y) err(diver6);
                   1145:   if (!s)
                   1146:   {
                   1147:     z=cgetr(3); z[1] = x[1] - (BITS_IN_LONG-1) + bfffo(y);
                   1148:     if (z[1]<0) err(diver7);
                   1149:     z[2]=0; return z;
                   1150:   }
                   1151:   if (y<0) { s = -s; y = -y; }
                   1152:   if (y==1) { z=rcopy(x); setsigne(z,s); return z; }
                   1153:
                   1154:   z=cgetr(lx=lg(x)); hiremainder=0;
                   1155:   for (i=2; i<lx; i++) z[i]=divll(x[i],y);
                   1156:
                   1157:   /* we may have hiremainder != 0 ==> garde */
                   1158:   garde=divll(0,y); sh=bfffo(z[2]); ex=evalexpo(expo(x)-sh);
                   1159:   if (ex & ~EXPOBITS) err(diver7);
                   1160:   if (sh) shift_left(z,z, 2,lx-1, garde,sh);
                   1161:   z[1] = evalsigne(s) | ex;
                   1162:   return z;
                   1163: }
                   1164:
                   1165: GEN
                   1166: divrr(GEN x, GEN y)
                   1167: {
                   1168:   long sx=signe(x), sy=signe(y), lx,ly,lz,e,i,j;
                   1169:   ulong si,saux;
                   1170:   GEN z,x1;
                   1171:
                   1172:   if (!sy) err(diver9);
                   1173:   e = evalexpo(expo(x) - expo(y));
                   1174:   if (e & ~EXPOBITS) err(diver11);
                   1175:   if (!sx) { z=cgetr(3); z[1]=e; z[2]=0; return z; }
                   1176:   if (sy<0) sx = -sx;
                   1177:   e = evalsigne(sx) | e;
                   1178:   lx=lg(x); ly=lg(y);
                   1179:   if (ly==3)
                   1180:   {
                   1181:     ulong k = x[2], l = (lx>3)? x[3]: 0;
                   1182:     LOCAL_HIREMAINDER;
                   1183:     if (k < (ulong)y[2]) e--;
                   1184:     else
                   1185:     {
                   1186:       l >>= 1; if (k&1) l |= HIGHBIT;
                   1187:       k >>= 1;
                   1188:     }
                   1189:     z=cgetr(3); z[1]=e;
                   1190:     hiremainder=k; z[2]=divll(l,y[2]); return z;
                   1191:   }
                   1192:
                   1193:   lz = (lx<=ly)? lx: ly;
                   1194:   x1 = (z=new_chunk(lz))-1;
                   1195:   x1[1]=0; for (i=2; i<lz; i++) x1[i]=x[i];
                   1196:   x1[lz] = (lx>lz)? x[lz]: 0;
                   1197:   x=z; si=y[2]; saux=y[3];
                   1198:   for (i=0; i<lz-1; i++)
                   1199:   { /* x1 = x + (i-1) */
                   1200:     ulong k,qp;
                   1201:     LOCAL_HIREMAINDER;
                   1202:     LOCAL_OVERFLOW;
                   1203:     if ((ulong)x1[1] == si)
                   1204:     {
                   1205:       qp = MAXULONG; k=addll(si,x1[2]);
                   1206:     }
                   1207:     else
                   1208:     {
                   1209:       if ((ulong)x1[1] > si) /* can't happen if i=0 */
                   1210:       {
                   1211:         GEN y1 = y+1;
                   1212:        overflow=0;
                   1213:        for (j=lz-i; j>0; j--) x1[j] = subllx(x1[j],y1[j]);
                   1214:        j=i; do x[--j]++; while (j && !x[j]);
                   1215:       }
                   1216:       hiremainder=x1[1]; overflow=0;
                   1217:       qp=divll(x1[2],si); k=hiremainder;
                   1218:     }
                   1219:     if (!overflow)
                   1220:     {
                   1221:       long k3 = subll(mulll(qp,saux), x1[3]);
                   1222:       long k4 = subllx(hiremainder,k);
                   1223:       while (!overflow && k4) { qp--; k3=subll(k3,saux); k4=subllx(k4,si); }
                   1224:     }
                   1225:     j = lz-i+1;
                   1226:     if (j<ly) (void)mulll(qp,y[j]); else { hiremainder=0 ; j=ly; }
                   1227:     for (j--; j>1; j--)
                   1228:     {
                   1229:       x1[j] = subll(x1[j], addmul(qp,y[j]));
                   1230:       hiremainder += overflow;
                   1231:     }
                   1232:     if (x1[1] != hiremainder)
                   1233:     {
                   1234:       if ((ulong)x1[1] < hiremainder)
                   1235:       {
                   1236:         qp--;
                   1237:         overflow=0; for (j=lz-i; j>1; j--) x1[j]=addllx(x1[j], y[j]);
                   1238:       }
                   1239:       else
                   1240:       {
                   1241:        x1[1] -= hiremainder;
                   1242:        while (x1[1])
                   1243:        {
                   1244:          qp++; if (!qp) { j=i; do x[--j]++; while (j && !x[j]); }
                   1245:           overflow=0; for (j=lz-i; j>1; j--) x1[j]=subllx(x1[j],y[j]);
                   1246:          x1[1] -= overflow;
                   1247:        }
                   1248:       }
                   1249:     }
                   1250:     x1[1]=qp; x1++;
                   1251:   }
                   1252:   x1 = x-1; for (j=lz-1; j>=2; j--) x[j]=x1[j];
                   1253:   if (*x) { shift_right(x,x, 2,lz, 1,1); } else e--;
                   1254:   x[0]=evaltyp(t_REAL)|evallg(lz);
                   1255:   x[1]=e; return x;
                   1256: }
                   1257: #endif /* !defined(__M68K__) */
                   1258: /* The following ones are not in mp.s (mulii is, with a different algorithm) */
                   1259:
                   1260: /* Integer division x / y:
                   1261:  *   if z = ONLY_REM return remainder, otherwise return quotient
                   1262:  *   if z != NULL set *z to remainder
                   1263:  *   *z is the last object on stack (and thus can be disposed of with cgiv
                   1264:  *   instead of gerepile)
                   1265:  * If *z is zero, we put gzero here and no copy.
                   1266:  * space needed: lx + ly
                   1267:  */
                   1268: GEN
                   1269: dvmdii(GEN x, GEN y, GEN *z)
                   1270: {
                   1271:   long sx=signe(x),sy=signe(y);
                   1272:   long av,lx,ly,lz,i,j,sh,k,lq,lr;
                   1273:   ulong si,qp,saux, *xd,*rd,*qd;
                   1274:   GEN r,q,x1;
                   1275:
                   1276:   if (!sy) err(dvmer1);
                   1277:   if (!sx)
                   1278:   {
                   1279:     if (!z || z == ONLY_REM) return gzero;
                   1280:     *z=gzero; return gzero;
                   1281:   }
                   1282:   lx=lgefint(x);
                   1283:   ly=lgefint(y); lz=lx-ly;
                   1284:   if (lz <= 0)
                   1285:   {
                   1286:     if (lz == 0)
                   1287:     {
                   1288:       for (i=2; i<lx; i++)
                   1289:         if (x[i] != y[i])
                   1290:         {
                   1291:           if ((ulong)x[i] > (ulong)y[i]) goto DIVIDE;
                   1292:           goto TRIVIAL;
                   1293:         }
                   1294:       if (z == ONLY_REM) return gzero;
                   1295:       if (z) *z = gzero;
                   1296:       if (sx < 0) sy = -sy;
                   1297:       return stoi(sy);
                   1298:     }
                   1299: TRIVIAL:
                   1300:     if (z == ONLY_REM) return icopy(x);
                   1301:     if (z) *z = icopy(x);
                   1302:     return gzero;
                   1303:   }
                   1304: DIVIDE: /* quotient is non-zero */
                   1305:   av=avma; if (sx<0) sy = -sy;
                   1306:   if (ly==3)
                   1307:   {
                   1308:     LOCAL_HIREMAINDER;
                   1309:     si = y[2];
                   1310:     if (si <= (ulong)x[2]) hiremainder=0;
                   1311:     else
                   1312:     {
                   1313:       hiremainder = x[2]; lx--; x++;
                   1314:     }
                   1315:     q = new_chunk(lx); for (i=2; i<lx; i++) q[i]=divll(x[i],si);
                   1316:     if (z == ONLY_REM)
                   1317:     {
                   1318:       avma=av; if (!hiremainder) return gzero;
                   1319:       r=cgeti(3);
                   1320:       r[1] = evalsigne(sx) | evallgefint(3);
                   1321:       r[2]=hiremainder; return r;
                   1322:     }
                   1323:     q[1] = evalsigne(sy) | evallgefint(lx);
                   1324:     q[0] = evaltyp(t_INT) | evallg(lx);
                   1325:     if (!z) return q;
                   1326:     if (!hiremainder) { *z=gzero; return q; }
                   1327:     r=cgeti(3);
                   1328:     r[1] = evalsigne(sx) | evallgefint(3);
                   1329:     r[2] = hiremainder; *z=r; return q;
                   1330:   }
                   1331:
                   1332:   x1 = new_chunk(lx); sh = bfffo(y[2]);
                   1333:   if (sh)
                   1334:   { /* normalize so that highbit(y) = 1 (shift left x and y by sh bits)*/
                   1335:     register const ulong m = BITS_IN_LONG - sh;
                   1336:     r = new_chunk(ly);
                   1337:     shift_left2(r, y,2,ly-1, 0,sh,m); y = r;
                   1338:     shift_left2(x1,x,2,lx-1, 0,sh,m);
                   1339:     x1[1] = ((ulong)x[2]) >> m;
                   1340:   }
                   1341:   else
                   1342:   {
                   1343:     x1[1]=0; for (j=2; j<lx; j++) x1[j]=x[j];
                   1344:   }
                   1345:   x=x1; si=y[2]; saux=y[3];
                   1346:   for (i=0; i<=lz; i++)
                   1347:   { /* x1 = x + i */
                   1348:     LOCAL_HIREMAINDER;
                   1349:     LOCAL_OVERFLOW;
                   1350:     if ((ulong)x1[1] == si)
                   1351:     {
                   1352:       qp = MAXULONG; k=addll(si,x1[2]);
                   1353:     }
                   1354:     else
                   1355:     {
                   1356:       hiremainder=x1[1]; overflow=0;
                   1357:       qp=divll(x1[2],si); k=hiremainder;
                   1358:     }
                   1359:     if (!overflow)
                   1360:     {
                   1361:       long k3 = subll(mulll(qp,saux), x1[3]);
                   1362:       long k4 = subllx(hiremainder,k);
                   1363:       while (!overflow && k4) { qp--; k3=subll(k3,saux); k4=subllx(k4,si); }
                   1364:     }
                   1365:     hiremainder=0;
                   1366:     for (j=ly-1; j>1; j--)
                   1367:     {
                   1368:       x1[j] = subll(x1[j], addmul(qp,y[j]));
                   1369:       hiremainder+=overflow;
                   1370:     }
                   1371:     if ((ulong)x1[1] < hiremainder)
                   1372:     {
                   1373:       overflow=0; qp--;
                   1374:       for (j=ly-1; j>1; j--) x1[j] = addllx(x1[j],y[j]);
                   1375:     }
                   1376:     x1[1]=qp; x1++;
                   1377:   }
                   1378:
                   1379:   lq = lz+2;
                   1380:   if (!z)
                   1381:   {
                   1382:     qd = (ulong*)av;
                   1383:     xd = (ulong*)(x + lq);
                   1384:     if (x[1]) { lz++; lq++; }
                   1385:     while (lz--) *--qd = *--xd;
                   1386:     *--qd = evalsigne(sy) | evallgefint(lq);
                   1387:     *--qd = evaltyp(t_INT) | evallg(lq);
                   1388:     avma = (long)qd; return (GEN)qd;
                   1389:   }
                   1390:
                   1391:   j=lq; while (j<lx && !x[j]) j++;
                   1392:   if (z == ONLY_REM)
                   1393:   {
                   1394:     lz = lx-j; if (lz==0) { avma = av; return gzero; }
                   1395:     rd = (ulong*)av; lr = lz+2;
                   1396:     xd = (ulong*)(x + lx);
                   1397:     if (!sh) while (lz--) *--rd = *--xd;
                   1398:     else
                   1399:     { /* shift remainder right by sh bits */
                   1400:       const ulong shl = BITS_IN_LONG - sh;
                   1401:       ulong l;
                   1402:       xd--;
                   1403:       while (--lz) /* fill r[3..] */
                   1404:       {
                   1405:         l = *xd >> sh;
                   1406:         *--rd = l | (*--xd << shl);
                   1407:       }
                   1408:       l = *xd >> sh;
                   1409:       if (l) *--rd = l; else lr--;
                   1410:     }
                   1411:     *--rd = evalsigne(sx) | evallgefint(lr);
                   1412:     *--rd = evaltyp(t_INT) | evallg(lr);
                   1413:     avma = (long)rd; return (GEN)rd;
                   1414:   }
                   1415:
                   1416:   lz = lx-j; lr = lz+2;
                   1417:   if (lz)
                   1418:   {
                   1419:     xd = (ulong*)(x + lx);
                   1420:     if (!sh)
                   1421:     {
                   1422:       rd = (ulong*)avma; r = new_chunk(lr);
                   1423:       while (lz--) *--rd = *--xd;
                   1424:     }
                   1425:     else
                   1426:     { /* shift remainder right by sh bits */
                   1427:       const ulong shl = BITS_IN_LONG - sh;
                   1428:       ulong l;
                   1429:       rd = (ulong*)x; /* overwrite shifted y */
                   1430:       xd--;
                   1431:       while (--lz)
                   1432:       {
                   1433:         l = *xd >> sh;
                   1434:         *--rd = l | (*--xd << shl);
                   1435:       }
                   1436:       l = *xd >> sh;
                   1437:       if (l) *--rd = l; else lr--;
                   1438:     }
                   1439:     *--rd = evalsigne(sx) | evallgefint(lr);
                   1440:     *--rd = evaltyp(t_INT) | evallg(lr);
                   1441:     rd += lr;
                   1442:   }
                   1443:   qd = (ulong*)av;
                   1444:   xd = (ulong*)(x + lq);
                   1445:   if (x[1]) lq++;
                   1446:   j = lq-2; while (j--) *--qd = *--xd;
                   1447:   *--qd = evalsigne(sy) | evallgefint(lq);
                   1448:   *--qd = evaltyp(t_INT) | evallg(lq);
                   1449:   q = (GEN)qd;
                   1450:   if (lr==2) *z = gzero;
                   1451:   else
                   1452:   {
                   1453:     while (lr--) *--qd = *--rd;
                   1454:     *z = (GEN)qd;
                   1455:   }
                   1456:   avma = (long)qd; return q;
                   1457: }
                   1458:
                   1459: /* assume y > x > 0. return y mod x */
                   1460: ulong
                   1461: mppgcd_resiu(GEN y, ulong x)
                   1462: {
                   1463:   long i, ly = lgefint(y);
                   1464:   LOCAL_HIREMAINDER;
                   1465:
                   1466:   hiremainder = 0;
                   1467:   for (i=2; i<ly; i++) (void)divll(y[i],x);
                   1468:   return hiremainder;
                   1469: }
                   1470:
                   1471: /* Assume x>y>0, both of them odd. return x-y if x=y mod 4, x+y otherwise */
                   1472: void
                   1473: mppgcd_plus_minus(GEN x, GEN y, GEN res)
                   1474: {
                   1475:   long av = avma;
                   1476:   long lx = lgefint(x)-1;
                   1477:   long ly = lgefint(y)-1, lt,m,i;
                   1478:   GEN t;
                   1479:
                   1480:   if ((x[lx]^y[ly]) & 3) /* x != y mod 4*/
                   1481:     t = addiispec(x+2,y+2,lx-1,ly-1);
                   1482:   else
                   1483:     t = subiispec(x+2,y+2,lx-1,ly-1);
                   1484:
                   1485:   lt = lgefint(t)-1; while (!t[lt]) lt--;
                   1486:   m = vals(t[lt]); lt++;
                   1487:   if (m == 0) /* 2^32 | t */
                   1488:   {
                   1489:     for (i = 2; i < lt; i++) res[i] = t[i];
                   1490:   }
                   1491:   else if (t[2] >> m)
                   1492:   {
                   1493:     shift_right(res,t, 2,lt, 0,m);
                   1494:   }
                   1495:   else
                   1496:   {
                   1497:     lt--; t++;
                   1498:     shift_right(res,t, 2,lt, t[1],m);
                   1499:   }
                   1500:   res[1] = evalsigne(1)|evallgefint(lt);
                   1501:   avma = av;
                   1502: }
                   1503:
                   1504: /* private version of mulss */
                   1505: ulong
                   1506: smulss(ulong x, ulong y, ulong *rem)
                   1507: {
                   1508:   LOCAL_HIREMAINDER;
                   1509:   x=mulll(x,y); *rem=hiremainder; return x;
                   1510: }
                   1511:
                   1512: #ifdef LONG_IS_64BIT
                   1513: #  define DIVCONVI 7
                   1514: #else
                   1515: #  define DIVCONVI 14
                   1516: #endif
                   1517:
                   1518: /* Conversion entier --> base 10^9. Assume x > 0 */
                   1519: GEN
                   1520: convi(GEN x)
                   1521: {
                   1522:   ulong av=avma, lim;
                   1523:   long lz;
                   1524:   GEN z,p1;
                   1525:
                   1526:   lz = 3 + ((lgefint(x)-2)*15)/DIVCONVI;
                   1527:   z=new_chunk(lz); z[1] = -1; p1 = z+2;
                   1528:   lim = stack_lim(av,1);
                   1529:   for(;;)
                   1530:   {
                   1531:     x = divis(x,1000000000); *p1++ = hiremainder;
                   1532:     if (!signe(x)) { avma=av; return p1; }
                   1533:     if (low_stack(lim, stack_lim(av,1))) x = gerepileuptoint((long)z,x);
                   1534:   }
                   1535: }
                   1536: #undef DIVCONVI
                   1537:
                   1538: /* Conversion partie fractionnaire --> base 10^9 (expo(x)<0) */
                   1539: GEN
                   1540: confrac(GEN x)
                   1541: {
                   1542:   long lx=lg(x), ex = -expo(x)-1, d,m,ly,ey,lr,nbdec,i,j;
                   1543:   GEN y,y1;
                   1544:
                   1545:   ey = ex + bit_accuracy(lx);
                   1546:   ly = 1 + ((ey-1) >> TWOPOTBITS_IN_LONG);
                   1547:   d = ex >> TWOPOTBITS_IN_LONG;
                   1548:   m = ex & (BITS_IN_LONG-1);
                   1549:   y = new_chunk(ly); y1 = y + (d-2);
                   1550:   while (d--) y[d]=0;
                   1551:   if (!m)
                   1552:     for (i=2; i<lx; i++) y1[i] = x[i];
                   1553:   else
                   1554:   { /* shift x left sh bits */
                   1555:     const ulong sh=BITS_IN_LONG-m;
                   1556:     ulong k=0, l;
                   1557:     for (i=2; i<lx; i++)
                   1558:     {
                   1559:       l = x[i];
                   1560:       y1[i] = (l>>m)|k;
                   1561:       k = l<<sh;
                   1562:     }
                   1563:     y1[i] = k;
                   1564:   }
                   1565:   nbdec = (long) (ey*L2SL10)+1; lr=(nbdec+17)/9;
                   1566:   y1=new_chunk(lr); *y1=nbdec;
                   1567:   for (j=1; j<lr; j++)
                   1568:   {
                   1569:     LOCAL_HIREMAINDER;
                   1570:     hiremainder=0;
                   1571:     for (i=ly-1; i>=0; i--) y[i]=addmul(y[i],1000000000);
                   1572:     y1[j]=hiremainder;
                   1573:   }
                   1574:   return y1;
                   1575: }
                   1576:
                   1577: GEN
                   1578: truedvmdii(GEN x, GEN y, GEN *z)
                   1579: {
                   1580:   long av=avma,tetpil;
                   1581:   GEN res, qu = dvmdii(x,y,&res);
                   1582:   GEN *gptr[2];
                   1583:
                   1584:   if (signe(res)>=0)
                   1585:   {
                   1586:     if (z == ONLY_REM) return gerepileuptoint(av,res);
                   1587:     if (z) *z = res; else cgiv(res);
                   1588:     return qu;
                   1589:   }
                   1590:
                   1591:   tetpil=avma;
                   1592:   if (z == ONLY_REM)
                   1593:   {
                   1594:     res = subiispec(y+2,res+2, lgefint(y)-2,lgefint(res)-2);
                   1595:     return gerepile(av,tetpil,res);
                   1596:   }
                   1597:   qu = addsi(-signe(y),qu);
                   1598:   if (!z) return gerepile(av,tetpil,qu);
                   1599:
                   1600:   *z = subiispec(y+2,res+2, lgefint(y)-2,lgefint(res)-2);
                   1601:   gptr[0]=&qu; gptr[1]=z; gerepilemanysp(av,tetpil,gptr,2);
                   1602:   return qu;
                   1603: }
                   1604:
                   1605: #if 0
                   1606: /* Exact integer division */
                   1607:
                   1608: static ulong
                   1609: invrev(ulong b)
                   1610: /* Find c such that 1=c*b mod B (where B = 2^32 or 2^64), assuming b odd,
                   1611:    which is not checked */
                   1612: {
                   1613:   int r;
                   1614:   ulong x;
                   1615:
                   1616:   r=b&7; x=(r==3 || r==5)? b+8: b; /* x=b^(-1) mod 2^4 */
                   1617:   x=x*(2-b*x); x=x*(2-b*x); x=x*(2-b*x); /* x=b^(-1) mod 2^32 */
                   1618: #ifdef LONG_IS_64BIT
                   1619:   x=x*(2-b*x); /* x=b^(-1) mod 2^64 */
                   1620: #endif
                   1621:   return x;
                   1622: }
                   1623:
                   1624: #define divllrev(a,b) (((ulong)a)*invrev(b))
                   1625:
                   1626: /* 2-adic division */
                   1627: GEN
                   1628: diviirev(GEN x, GEN y, long a)
                   1629: /* Find z such that |x|=|y|*z mod B^a, where a<=lgefint(x)-2 */
                   1630: {
                   1631:   long lx,lgx,ly,vy,av=avma,tetpil,i,j,ii;
                   1632:   ulong binv,q;
                   1633:   GEN z;
                   1634:
                   1635:   if (!signe(y)) err(dvmer1);
                   1636:   if (!signe(x)) return gzero;
                   1637: /* make y odd */
                   1638:   vy=vali(y);
                   1639:   if (vy)
                   1640:   {
                   1641:     if (vali(x)<vy) err(talker,"impossible division in diviirev");
                   1642:     y=shifti(y,-vy); x=shifti(x,-vy); a-=(vy>>TWOPOTBITS_IN_LONG);
                   1643:   }
                   1644:   else x=icopy(x); /* necessary because we destroy x */
                   1645: /* improve the above by touching only a words */
                   1646:   if (a<=0) {avma=a;return gzero;}
                   1647: /* now y is odd */
                   1648:   lx=a+2; ly=lgefint(y); lgx=lgefint(x);
                   1649:   if (lx>lgx) err(talker,"3rd parameter too large in diviirev");
                   1650:   binv=invrev(y[ly-1]);
                   1651:   z=cgeti(lx);
                   1652:   for (ii=lgx-1,i=lx-1; i>=2; i--,ii--)
                   1653:   {
                   1654:     long limj;
                   1655:     LOCAL_HIREMAINDER;
                   1656:     LOCAL_OVERFLOW;
                   1657:
                   1658:     z[i]=q=binv*((ulong)x[ii]); /* this is the i-th quotient */
                   1659:     limj=max(lgx-a,3+ii-ly);
                   1660:     mulll(q,y[ly-1]); overflow=0;
                   1661:     for (j=ii-1; j>=limj; j--)
                   1662:       x[j]=subllx(x[j],addmul(q,y[j+ly-ii-1]));
                   1663:   }
                   1664:   tetpil=avma; i=2; while((i<lx)&&(!z[i])) i++;
                   1665:   if (i==lx) {avma=av; return gzero;}
                   1666:   y=cgeti(lx-i+2); y[1]=evalsigne(1)|evallgefint(lx-i+2); j=2;
                   1667:   for ( ; i<lx; i++) y[j++]=z[i];
                   1668:   return gerepile(av,tetpil,y);
                   1669: }
                   1670:
                   1671: GEN
                   1672: diviiexactfullrev(GEN x, GEN y)
                   1673: /* Find z such that x=y*z knowing that y divides x */
                   1674: {
                   1675:   long lx,lz,ly,vy,av=avma,tetpil,i,j,ii,sx=signe(x),sy=signe(y);
                   1676:   ulong binv,q;
                   1677:   GEN z;
                   1678:
                   1679:   if (!sy) err(dvmer1);
                   1680:   if (!sx) return gzero;
                   1681: /* make y odd */
                   1682:   vy=vali(y);
                   1683:   if (vy)
                   1684:   {
                   1685:     if (vali(x)<vy) err(talker,"impossible division in diviirev");
                   1686:     y=shifti(y,-vy); x=shifti(x,-vy);
                   1687:   }
                   1688:   else x=icopy(x); /* necessary because we destroy x */
                   1689: /* now y is odd */
                   1690:   ly=lgefint(y); lx=lgefint(x);
                   1691:   if (ly>lx) err(talker,"impossible division in diviirev");
                   1692:   binv=invrev(y[ly-1]);
                   1693:   i=2; while (i<ly && y[i]==x[i]) i++;
                   1694:   lz=(i==ly || y[i]<x[i]) ? lx-ly+3 : lx-ly+2;
                   1695:   z=cgeti(lz);
                   1696:   for (ii=lx-1,i=lz-1; i>=2; i--,ii--)
                   1697:   {
                   1698:     long limj;
                   1699:     LOCAL_HIREMAINDER;
                   1700:     LOCAL_OVERFLOW;
                   1701:
                   1702:     z[i]=q=binv*((ulong)x[ii]); /* this is the i-th quotient */
                   1703:     limj=max(lx-lz+2,3+ii-ly);
                   1704:     mulll(q,y[ly-1]); overflow=0;
                   1705:     for (j=ii-1; j>=limj; j--)
                   1706:       x[j]=subllx(x[j],addmul(q,y[j+ly-ii-1]));
                   1707:   }
                   1708:   tetpil=avma; i=2; while((i<lz)&&(!z[i])) i++;
                   1709:   if (i==lz) err(talker,"bug in diviiexact");
                   1710:   y=cgeti(lz-i+2); y[1]=evalsigne(sx*sy) | evallgefint(lz-i+2); j=2;
                   1711:   for ( ; i<lz; i++) y[j++]=z[i];
                   1712:   return gerepile(av,tetpil,y);
                   1713: }
                   1714:
                   1715: GEN
                   1716: diviiexact2(GEN x, GEN y)
                   1717: /* Find z such that x=y*z assuming y divides x (which is not checked) */
                   1718: {
                   1719:   long sx=signe(x),sy=signe(y),av=avma,tetpil,lyinv,lpr,a,lx,ly,lz,lzs,lp1;
                   1720:   long i,j,vy;
                   1721:   ulong aux;
                   1722:   GEN yinv,p1,z,xinit,yinit;
                   1723:
                   1724:   if (!sy) err(dvmer1);
                   1725:   if (!sx) return gzero;
                   1726:   xinit=x; yinit=y;
                   1727:   setsigne(y,1);setsigne(x,1);
                   1728: /* make y odd */
                   1729:   vy=vali(y);
                   1730:   if (vy)
                   1731:   {
                   1732:     if (vali(x)<vy) err(talker,"impossible division in diviirev");
                   1733:     y=shifti(y,-vy); x=shifti(x,-vy);
                   1734:   }
                   1735: /* now y is odd */
                   1736:   ly=lgefint(y); lx=lgefint(x);
                   1737:   if (lx<ly) err(talker,"not an exact division in diviiexact");
                   1738:   a=lx-ly+1; lz=a+2;
                   1739:   aux=invrev(y[ly-1]);
                   1740:   if (aux & HIGHBIT) {yinv=stoi(aux^HIGHBIT);yinv[2]|=HIGHBIT;}
                   1741:   else yinv=stoi(aux); /* inverse of y mod 2^32 (or 2^64) */
                   1742:   lpr=1; /* current accuracy */
                   1743:   while(lpr<a)
                   1744:   {
                   1745:     long lycut;
                   1746:     GEN ycut;
                   1747:
                   1748:     lyinv=lgefint(yinv);
                   1749:     lycut=min(2*lpr+2,ly);
                   1750:     ycut=cgeti(lycut); ycut[1]=evalsigne(1) | evallgefint(lycut);
                   1751:     for(i=2; i<lycut; i++) ycut[i]=y[ly+i-lycut];
                   1752:     p1=mulii(yinv,ycut); lp1=lgefint(p1);
                   1753:     if (lp1>lpr+2)
                   1754:     {
                   1755:       long lp1cut,lynew,lp2;
                   1756:       GEN p1cut,p2,ynew;
                   1757:       LOCAL_OVERFLOW;
                   1758:
                   1759:       lp1cut=min(lp1-lpr,lpr+2);
                   1760:       p1cut=cgeti(lp1cut); p1cut[1]=evalsigne(1) | evallgefint(lp1cut);
                   1761:       overflow=0;
                   1762:       for (i=lp1cut-1; i>=2; i--) p1cut[i]=subllx(0,p1[i+lp1-lpr-lp1cut]);
                   1763:       p2=mulii(p1cut,yinv); lp2=lgefint(p2);
                   1764:       lynew=(lp2<=lpr+2) ? lpr+lp2 : 2*lpr+2;
                   1765:       ynew=cgeti(lynew); ynew[1]=evalsigne(1) | evallgefint(lynew);
                   1766:       for (i=lynew-1; i>=lynew-lpr; i--) ynew[i]=yinv[i+lyinv-lynew];
                   1767:       for (i=lynew-lpr-1; i>=2; i--) ynew[i]=p2[i+lp2+lpr-lynew];
                   1768:       yinv=ynew;
                   1769:     }
                   1770:     lpr<<=1;
                   1771:   }
                   1772:   lyinv=lgefint(yinv); lzs=min(lz,lyinv);
                   1773:   z=cgeti(lzs); z[1]=evalsigne(1) | evallgefint(lzs);
                   1774:   for(i=2; i<lzs; i++) z[i]=yinv[i+lyinv-lzs];
                   1775:   p1=mulii(z,x); lp1=lgefint(p1); lzs=min(lz,lp1);
                   1776:   z=cgeti(lzs);
                   1777:   for (i=2; i<lzs; i++) z[i]=p1[i+lp1-lzs];
                   1778:   i=2; while (i<lzs && !z[i]) i++;
                   1779:   if (i==lzs) err(talker,"bug in diviiexact");
                   1780:   tetpil=avma; p1=cgeti(lzs-i+2);
                   1781:   p1[1]=evalsigne(sx*sy) | evallgefint(lzs-i+2);
                   1782:   for (j=2; j<=lzs-i+1; j++) p1[j]=z[j+i-2];
                   1783:   setsigne(xinit,sx);setsigne(yinit,sy);
                   1784:   return gerepile(av,tetpil,p1);
                   1785: }
                   1786: #endif
                   1787:
                   1788: long
                   1789: smodsi(long x, GEN y)
                   1790: {
                   1791:   if (x<0) err(talker,"negative small integer in smodsi");
                   1792:   (void)divsi(x,y); return hiremainder;
                   1793: }
                   1794:
                   1795: /* x and y are integers. Return 1 if |x| == |y|, 0 otherwise */
                   1796: int
                   1797: absi_equal(GEN x, GEN y)
                   1798: {
                   1799:   long lx,i;
                   1800:
                   1801:   if (!signe(x)) return !signe(y);
                   1802:   if (!signe(y)) return 0;
                   1803:
                   1804:   lx=lgefint(x); if (lx != lgefint(y)) return 0;
                   1805:   i=2; while (i<lx && x[i]==y[i]) i++;
                   1806:   return (i==lx);
                   1807: }
                   1808:
                   1809: /* x and y are integers. Return sign(|x| - |y|) */
                   1810: int
                   1811: absi_cmp(GEN x, GEN y)
                   1812: {
                   1813:   long lx,ly,i;
                   1814:
                   1815:   if (!signe(x)) return signe(y)? -1: 0;
                   1816:   if (!signe(y)) return 1;
                   1817:
                   1818:   lx=lgefint(x); ly=lgefint(y);
                   1819:   if (lx>ly) return 1;
                   1820:   if (lx<ly) return -1;
                   1821:   i=2; while (i<lx && x[i]==y[i]) i++;
                   1822:   if (i==lx) return 0;
                   1823:   return ((ulong)x[i] > (ulong)y[i])? 1: -1;
                   1824: }
                   1825:
                   1826: /* x and y are reals. Return sign(|x| - |y|) */
                   1827: int
                   1828: absr_cmp(GEN x, GEN y)
                   1829: {
                   1830:   long ex,ey,lx,ly,lz,i;
                   1831:
                   1832:   if (!signe(x)) return signe(y)? -1: 0;
                   1833:   if (!signe(y)) return 1;
                   1834:
                   1835:   ex=expo(x); ey=expo(y);
                   1836:   if (ex>ey) return  1;
                   1837:   if (ex<ey) return -1;
                   1838:
                   1839:   lx=lg(x); ly=lg(y); lz = (lx<ly)?lx:ly;
                   1840:   i=2; while (i<lz && x[i]==y[i]) i++;
                   1841:   if (i<lz) return ((ulong)x[i] > (ulong)y[i])? 1: -1;
                   1842:   if (lx>=ly)
                   1843:   {
                   1844:     while (i<lx && !x[i]) i++;
                   1845:     return (i==lx)? 0: 1;
                   1846:   }
                   1847:   while (i<ly && !y[i]) i++;
                   1848:   return (i==ly)? 0: -1;
                   1849: }
                   1850:
                   1851: /********************************************************************/
                   1852: /**                                                                **/
                   1853: /**               INTEGER MULTIPLICATION (KARATSUBA)               **/
                   1854: /**                                                                **/
                   1855: /********************************************************************/
                   1856:
                   1857: #if 0 /* for tunings */
                   1858: long SQRI_LIMIT = 12;
                   1859: long MULII_LIMIT = 16;
                   1860:
                   1861: void
                   1862: setsqi(long a) { SQRI_LIMIT=a; }
                   1863: void
                   1864: setmuli(long a) { MULII_LIMIT=a; }
                   1865:
                   1866: GEN
                   1867: speci(GEN x, long nx)
                   1868: {
                   1869:   GEN z = cgeti(nx+2);
                   1870:   long i;
                   1871:   for (i=0; i<nx; i++) z[i+2] = x[i];
                   1872:   z[1]=evalsigne(1)|evallgefint(nx+2);
                   1873:   return z;
                   1874: }
                   1875: #else
                   1876: #  define SQRI_LIMIT 12
                   1877: #  define MULII_LIMIT 16
                   1878: #endif
                   1879:
                   1880: /* nx >= ny = num. of digits of x, y (not GEN, see mulii) */
                   1881: #ifdef INLINE
                   1882: INLINE
                   1883: #endif
                   1884: GEN
                   1885: muliispec(GEN x, GEN y, long nx, long ny)
                   1886: {
                   1887:   GEN z2e,z2d,yd,xd,ye,zd;
                   1888:   long p1,lz;
                   1889:   LOCAL_HIREMAINDER;
                   1890:
                   1891:   if (!ny) return gzero;
                   1892:   zd = (GEN)avma; lz = nx+ny+2;
                   1893:   (void)new_chunk(lz);
                   1894:   xd = x + nx;
                   1895:   yd = y + ny;
                   1896:   ye = yd; p1 = *--xd;
                   1897:
                   1898:   *--zd = mulll(p1, *--yd); z2e = zd;
                   1899:   while (yd > y) *--zd = addmul(p1, *--yd);
                   1900:   *--zd = hiremainder;
                   1901:
                   1902:   while (xd > x)
                   1903:   {
                   1904:     LOCAL_OVERFLOW;
                   1905:     yd = ye; p1 = *--xd;
                   1906:
                   1907:     z2d = --z2e;
                   1908:     *z2d = addll(mulll(p1, *--yd), *z2d); z2d--;
                   1909:     while (yd > y)
                   1910:     {
                   1911:       hiremainder += overflow;
                   1912:       *z2d = addll(addmul(p1, *--yd), *z2d); z2d--;
                   1913:     }
                   1914:     *--zd = hiremainder + overflow;
                   1915:   }
                   1916:   if (*zd == 0) { zd++; lz--; } /* normalize */
                   1917:   *--zd = evalsigne(1) | evallgefint(lz);
                   1918:   *--zd = evaltyp(t_INT) | evallg(lz);
                   1919:   avma=(long)zd; return zd;
                   1920: }
                   1921:
                   1922: /* return (x shifted left d words) + y. Assume d > 0, x > 0 and y >= 0 */
                   1923: static GEN
                   1924: addshiftw(GEN x, GEN y, long d)
                   1925: {
                   1926:   GEN z,z0,y0,yd, zd = (GEN)avma;
                   1927:   long a,lz,ly = lgefint(y);
                   1928:
                   1929:   z0 = new_chunk(d);
                   1930:   a = ly-2; yd = y+ly;
                   1931:   if (a >= d)
                   1932:   {
                   1933:     y0 = yd-d; while (yd > y0) *--zd = *--yd; /* copy last d words of y */
                   1934:     a -= d;
                   1935:     if (a)
                   1936:       z = addiispec(x+2, y+2, lgefint(x)-2, a);
                   1937:     else
                   1938:       z = icopy(x);
                   1939:   }
                   1940:   else
                   1941:   {
                   1942:     y0 = yd-a; while (yd > y0) *--zd = *--yd; /* copy last a words of y */
                   1943:     while (zd >= z0) *--zd = 0;    /* complete with 0s */
                   1944:     z = icopy(x);
                   1945:   }
                   1946:   lz = lgefint(z)+d;
                   1947:   z[1] = evalsigne(1) | evallgefint(lz);
                   1948:   z[0] = evaltyp(t_INT) | evallg(lz); return z;
                   1949: }
                   1950:
                   1951: /* Fast product (Karatsuba) of integers a,b. These are not real GENs, a+2
                   1952:  * and b+2 were sent instead. na, nb = number of digits of a, b.
                   1953:  * c,c0,c1,c2 are genuine GENs.
                   1954:  */
                   1955: static GEN
                   1956: quickmulii(GEN a, GEN b, long na, long nb)
                   1957: {
                   1958:   GEN a0,c,c0;
                   1959:   long av,n0,n0a,i;
                   1960:
                   1961:   if (na < nb) swapspec(a,b, na,nb);
                   1962:   if (nb == 1) return mulsispec(*b, a, na);
                   1963:   if (nb == 0) return gzero;
                   1964:   if (nb < MULII_LIMIT) return muliispec(a,b,na,nb);
                   1965:   i=(na>>1); n0=na-i; na=i;
                   1966:   av=avma; a0=a+na; n0a=n0;
                   1967:   while (!*a0 && n0a) { a0++; n0a--; }
                   1968:
                   1969:   if (n0a && nb > n0)
                   1970:   { /* nb <= na <= n0 */
                   1971:     GEN b0,c1,c2;
                   1972:     long n0b;
                   1973:
                   1974:     nb -= n0;
                   1975:     c = quickmulii(a,b,na,nb);
                   1976:     b0 = b+nb; n0b = n0;
                   1977:     while (!*b0 && n0b) { b0++; n0b--; }
                   1978:     if (n0b)
                   1979:     {
                   1980:       c0 = quickmulii(a0,b0, n0a,n0b);
                   1981:
                   1982:       c2 = addiispec(a0,a, n0a,na);
                   1983:       c1 = addiispec(b0,b, n0b,nb);
                   1984:       c1 = quickmulii(c1+2,c2+2, lgefint(c1)-2,lgefint(c2)-2);
                   1985:       c2 = addiispec(c0+2, c+2, lgefint(c0)-2,lgefint(c) -2);
                   1986:
                   1987:       c1 = subiispec(c1+2,c2+2, lgefint(c1)-2,lgefint(c2)-2);
                   1988:     }
                   1989:     else
                   1990:     {
                   1991:       c0 = gzero;
                   1992:       c1 = quickmulii(a0,b, n0a,nb);
                   1993:     }
                   1994:     c = addshiftw(c,c1, n0);
                   1995:   }
                   1996:   else
                   1997:   {
                   1998:     c = quickmulii(a,b,na,nb);
                   1999:     c0 = quickmulii(a0,b,n0a,nb);
                   2000:   }
                   2001:   return gerepileuptoint(av, addshiftw(c,c0, n0));
                   2002: }
                   2003:
                   2004: /* actual operations will take place on a+2 and b+2: we strip the codewords */
                   2005: GEN
                   2006: mulii(GEN a,GEN b)
                   2007: {
                   2008:   long sa,sb;
                   2009:   GEN z;
                   2010:
                   2011:   sa=signe(a); if (!sa) return gzero;
                   2012:   sb=signe(b); if (!sb) return gzero;
                   2013:   if (sb<0) sa = -sa;
                   2014:   z = quickmulii(a+2,b+2, lgefint(a)-2,lgefint(b)-2);
                   2015:   setsigne(z,sa); return z;
                   2016: }
                   2017:
                   2018: static GEN
                   2019: quicksqri(GEN a, long na)
                   2020: {
                   2021:   GEN a0,c,c0,c1;
                   2022:   long av,n0,n0a,i;
                   2023:
                   2024:   if (na<SQRI_LIMIT) return muliispec(a,a,na,na);
                   2025:   i=(na>>1); n0=na-i; na=i;
                   2026:   av=avma; a0=a+na; n0a=n0;
                   2027:   while (!*a0 && n0a) { a0++; n0a--; }
                   2028:   c = quicksqri(a,na);
                   2029:   if (n0a)
                   2030:   {
                   2031:     c0 = quicksqri(a0,n0a);
                   2032:     c1 = shifti(quickmulii(a0,a, n0a,na),1);
                   2033:     c = addshiftw(c,c1, n0);
                   2034:     c = addshiftw(c,c0, n0);
                   2035:   }
                   2036:   else
                   2037:     c = addshiftw(c,gzero,n0<<1);
                   2038:   return gerepileuptoint(av, c);
                   2039: }
                   2040:
                   2041: GEN
                   2042: sqri(GEN a) { return quicksqri(a+2, lgefint(a)-2); }
                   2043:
                   2044: #define MULRR_LIMIT  32
                   2045: #define MULRR2_LIMIT 32
                   2046:
                   2047: #if 0
                   2048: GEN
                   2049: karamulrr1(GEN x, GEN y)
                   2050: {
                   2051:   long sx,sy;
                   2052:   long i,i1,i2,lx=lg(x),ly=lg(y),e,flag,garde;
                   2053:   long lz2,lz3,lz4;
                   2054:   GEN z,lo1,lo2,hi;
                   2055:
                   2056:   /* ensure that lg(y) >= lg(x) */
                   2057:   if (lx>ly) { lx=ly; z=x; x=y; y=z; flag=1; } else flag = (lx!=ly);
                   2058:   if (lx < MULRR_LIMIT) return mulrr(x,y);
                   2059:   sx=signe(x); sy=signe(y);
                   2060:   e = evalexpo(expo(x)+expo(y)); if (e & ~EXPOBITS) err(muler4);
                   2061:   if (!sx || !sy) { z=cgetr(3); z[2]=0; z[1]=e; return z; }
                   2062:   if (sy<0) sx = -sx;
                   2063:   ly=lx+flag; z=cgetr(lx);
                   2064:   lz2 = (lx>>1); lz3 = lx-lz2;
                   2065:   x += 2; lx -= 2;
                   2066:   y += 2; ly -= 2;
                   2067:   hi = quickmulii(x,y,lz2,lz2);
                   2068:   i1=lz2; while (i1<lx && !x[i1]) i1++;
                   2069:   lo1 = quickmulii(y,x+i1,lz2,lx-i1);
                   2070:   i2=lz2; while (i2<ly && !y[i2]) i2++;
                   2071:   lo2 = quickmulii(x,y+i2,lz2,ly-i2);
                   2072:
                   2073:   if (signe(lo1))
                   2074:   {
                   2075:     if (flag) { lo2 = addshiftw(lo1,lo2,1); lz3++; } else lo2=addii(lo1,lo2);
                   2076:   }
                   2077:   lz4=lgefint(lo2)-lz3;
                   2078:   if (lz4>0) hi = addiispec(hi+2,lo2+2, lgefint(hi)-2,lz4);
                   2079:   if (hi[2] < 0)
                   2080:   {
                   2081:     e++; garde=hi[lx+2];
                   2082:     for (i=lx+1; i>=2 ; i--) z[i]=hi[i];
                   2083:   }
                   2084:   else
                   2085:   {
                   2086:     garde = (hi[lx+2] << 1);
                   2087:     shift_left(z,hi,2,lx+1, garde, 1);
                   2088:   }
                   2089:   z[1]=evalsigne(sx) | e;
                   2090:   if (garde < 0)
                   2091:   { /* round to nearest */
                   2092:     i=lx+2; do z[--i]++; while (z[i]==0);
                   2093:     if (i==1) z[2]=HIGHBIT;
                   2094:   }
                   2095:   avma=(long)z; return z;
                   2096: }
                   2097:
                   2098: GEN
                   2099: karamulrr2(GEN x, GEN y)
                   2100: {
                   2101:   long sx,sy,i,lx=lg(x),ly=lg(y),e,flag,garde;
                   2102:   GEN z,hi;
                   2103:
                   2104:   if (lx>ly) { lx=ly; z=x; x=y; y=z; flag=1; } else flag = (lx!=ly);
                   2105:   if (lx < MULRR2_LIMIT) return mulrr(x,y);
                   2106:   ly=lx+flag; sx=signe(x); sy=signe(y);
                   2107:   e = evalexpo(expo(x)+expo(y)); if (e & ~EXPOBITS) err(muler4);
                   2108:   if (!sx || !sy) { z=cgetr(3); z[2]=0; z[1]=e; return z; }
                   2109:   if (sy<0) sx = -sx;
                   2110:   z=cgetr(lx);
                   2111:   hi=quickmulii(y+2,x+2,ly-2,lx-2);
                   2112:   if (hi[2] < 0)
                   2113:   {
                   2114:     e++; garde=hi[lx];
                   2115:     for (i=2; i<lx ; i++) z[i]=hi[i];
                   2116:   }
                   2117:   else
                   2118:   {
                   2119:     garde = (hi[lx] << 1);
                   2120:     shift_left(z,hi,2,lx-1, garde, 1);
                   2121:   }
                   2122:   z[1]=evalsigne(sx) | e;
                   2123:   if (garde < 0)
                   2124:   { /* round to nearest */
                   2125:     i=lx; do z[--i]++; while (z[i]==0);
                   2126:     if (i==1) z[2]=HIGHBIT;
                   2127:   }
                   2128:   avma=(long)z; return z;
                   2129: }
                   2130:
                   2131: GEN
                   2132: karamulrr(GEN x, GEN y, long flag)
                   2133: {
                   2134:   switch(flag)
                   2135:   {
                   2136:     case 1: return karamulrr1(x,y);
                   2137:     case 2: return karamulrr2(x,y);
                   2138:     default: err(flagerr,"karamulrr");
                   2139:   }
                   2140:   return NULL; /* not reached */
                   2141: }
                   2142:
                   2143: GEN
                   2144: karamulir(GEN x, GEN y, long flag)
                   2145: {
                   2146:   long sx=signe(x),lz,i;
                   2147:   GEN z,temp,z1;
                   2148:
                   2149:   if (!sx) return gzero;
                   2150:   lz=lg(y); z=cgetr(lz);
                   2151:   temp=cgetr(lz+1); affir(x,temp);
                   2152:   z1=karamulrr(temp,y,flag);
                   2153:   for (i=1; i<lz; i++) z[i]=z1[i];
                   2154:   avma=(long)z; return z;
                   2155: }
                   2156: #endif
                   2157:
                   2158: #ifdef LONG_IS_64BIT
                   2159:
                   2160: #if PARI_BYTE_ORDER == LITTLE_ENDIAN_64 || PARI_BYTE_ORDER == BIG_ENDIAN_64
                   2161: #else
                   2162:   error... unknown machine
                   2163: #endif
                   2164:
                   2165: GEN
                   2166: dbltor(double x)
                   2167: {
                   2168:   GEN z = cgetr(3);
                   2169:   long e;
                   2170:   union { double f; ulong i; } fi;
                   2171:   const int mant_len = 52;  /* mantissa bits (excl. hidden bit) */
                   2172:   const int exp_mid = 0x3ff;/* exponent bias */
                   2173:   const int expo_len = 11; /* number of bits of exponent */
                   2174:   LOCAL_HIREMAINDER;
                   2175:
                   2176:   if (x==0) { z[1]=evalexpo(-308); z[2]=0; return z; }
                   2177:   fi.f = x;
                   2178:   e = evalexpo(((fi.i & (HIGHBIT-1)) >> mant_len) - exp_mid);
                   2179:   z[1] = e | evalsigne(x<0? -1: 1);
                   2180:   z[2] = (fi.i << expo_len) | HIGHBIT;
                   2181:   return z;
                   2182: }
                   2183:
                   2184: double
                   2185: rtodbl(GEN x)
                   2186: {
                   2187:   long ex,s=signe(x);
                   2188:   ulong a;
                   2189:   union { double f; ulong i; } fi;
                   2190:   const int mant_len = 52;  /* mantissa bits (excl. hidden bit) */
                   2191:   const int exp_mid = 0x3ff;/* exponent bias */
                   2192:   const int expo_len = 11; /* number of bits of exponent */
                   2193:   LOCAL_HIREMAINDER;
                   2194:
                   2195:   if (typ(x)==t_INT && !s) return 0.0;
                   2196:   if (typ(x)!=t_REAL) err(typeer,"rtodbl");
                   2197:   if (!s || (ex=expo(x)) < - exp_mid) return 0.0;
                   2198:
                   2199:   /* start by rounding to closest */
                   2200:   a = (x[2] & (HIGHBIT-1)) + 0x400;
                   2201:   if (a & HIGHBIT) { ex++; a=0; }
                   2202:   if (ex >= exp_mid) err(rtodber);
                   2203:   fi.i = ((ex + exp_mid) << mant_len) | (a >> expo_len);
                   2204:   if (s<0) fi.i |= HIGHBIT;
                   2205:   return fi.f;
                   2206: }
                   2207:
                   2208: #else
                   2209:
                   2210: #if   PARI_BYTE_ORDER == LITTLE_ENDIAN
                   2211: #  define INDEX0 1
                   2212: #  define INDEX1 0
                   2213: #elif PARI_BYTE_ORDER == BIG_ENDIAN
                   2214: #  define INDEX0 0
                   2215: #  define INDEX1 1
                   2216: #else
                   2217:    error... unknown machine
                   2218: #endif
                   2219:
                   2220: GEN
                   2221: dbltor(double x)
                   2222: {
                   2223:   GEN z;
                   2224:   long e;
                   2225:   union { double f; ulong i[2]; } fi;
                   2226:   const int mant_len = 52;  /* mantissa bits (excl. hidden bit) */
                   2227:   const int exp_mid = 0x3ff;/* exponent bias */
                   2228:   const int shift = mant_len-32;
                   2229:   const int expo_len = 11; /* number of bits of exponent */
                   2230:
                   2231:   if (x==0) { z=cgetr(3); z[1]=evalexpo(-308); z[2]=0; return z; }
                   2232:   fi.f = x; z=cgetr(4);
                   2233:   {
                   2234:     const ulong a = fi.i[INDEX0];
                   2235:     const ulong b = fi.i[INDEX1];
                   2236:     e = evalexpo(((a & (HIGHBIT-1)) >> shift) - exp_mid);
                   2237:     z[1] = e | evalsigne(x<0? -1: 1);
                   2238:     z[3] = b << expo_len;
                   2239:     z[2] = HIGHBIT | b >> (BITS_IN_LONG-expo_len) | (a << expo_len);
                   2240:   }
                   2241:   return z;
                   2242: }
                   2243:
                   2244: double
                   2245: rtodbl(GEN x)
                   2246: {
                   2247:   long ex,s=signe(x),lx=lg(x);
                   2248:   ulong a,b,k;
                   2249:   union { double f; ulong i[2]; } fi;
                   2250:   const int mant_len = 52;  /* mantissa bits (excl. hidden bit) */
                   2251:   const int exp_mid = 0x3ff;/* exponent bias */
                   2252:   const int shift = mant_len-32;
                   2253:   const int expo_len = 11; /* number of bits of exponent */
                   2254:
                   2255:   if (typ(x)==t_INT && !s) return 0.0;
                   2256:   if (typ(x)!=t_REAL) err(typeer,"rtodbl");
                   2257:   if (!s || (ex=expo(x)) < - exp_mid) return 0.0;
                   2258:
                   2259:   /* start by rounding to closest */
                   2260:   a = x[2] & (HIGHBIT-1);
                   2261:   if (lx > 3)
                   2262:   {
                   2263:     b = x[3] + 0x400UL; if (b < 0x400UL) a++;
                   2264:     if (a & HIGHBIT) { ex++; a=0; }
                   2265:   }
                   2266:   else b = 0;
                   2267:   if (ex > exp_mid) err(rtodber);
                   2268:   ex += exp_mid;
                   2269:   k = (a >> expo_len) | (ex << shift);
                   2270:   if (s<0) k |= HIGHBIT;
                   2271:   fi.i[INDEX0] = k;
                   2272:   fi.i[INDEX1] = (a << (BITS_IN_LONG-expo_len)) | (b >> expo_len);
                   2273:   return fi.f;
                   2274: }
                   2275: #endif
                   2276:
                   2277: /* Old cgiv without reference count (which was not used anyway)
                   2278:  * Should be a macro.
                   2279:  */
                   2280: void
                   2281: cgiv(GEN x)
                   2282: {
                   2283:   if (x == (GEN) avma)
                   2284:     avma = (long) (x+lg(x));
                   2285: }
                   2286:
                   2287: /********************************************************************/
                   2288: /**                                                                **/
                   2289: /**               INTEGER EXTENDED GCD  (AND INVMOD)               **/
                   2290: /**                                                                **/
                   2291: /********************************************************************/
                   2292:
                   2293: /* GN 1998Oct25, originally developed in January 1998 under 2.0.4.alpha,
                   2294:  * in the context of trying to improve elliptic curve cryptosystem attacking
                   2295:  * algorithms.
                   2296:  *
                   2297:  * Two basic ideas - (1) avoid many integer divisions, especially when the
                   2298:  * quotient is 1 (which happens more than 40% of the time).  (2) Use Lehmer's
                   2299:  * trick as modified by Jebelean of extracting a couple of words' worth of
                   2300:  * leading bits from both operands, and compute partial quotients from them
                   2301:  * as long as we can be sure of their values.  The Jebelean modifications
                   2302:  * consist in reliable inequalities from which we can decide fast whether
                   2303:  * to carry on or to return to the outer loop, and in re-shifting after the
                   2304:  * first word's worth of bits has been used up.  All of this is described
                   2305:  * in R. Lercier's these [pp148-153 & 163f.], except his outer loop isn't
                   2306:  * quite right  (the catch-up divisions needed when one partial quotient is
                   2307:  * larger than a word are missing).
                   2308:  *
                   2309:  * The API is mpxgcd() below;  the single-word routines xgcduu and xxgcduu
                   2310:  * may be called directly if desired;  lgcdii() probably doesn't make much
                   2311:  * sense out of context.
                   2312:  *
                   2313:  * The whole lot is a factor 6 .. 8 faster on word-sized operands, and asym-
                   2314:  * ptotically about a factor 2.5 .. 3, depending on processor architecture,
                   2315:  * than the naive continued-division code.  Unfortunately, thanks to the
                   2316:  * unrolled loops and all, the code is a bit lengthy.
                   2317:  */
                   2318:
                   2319: /*==================================
                   2320:  * xgcduu(d,d1,f,v,v1,s)
                   2321:  * xxgcduu(d,d1,f,u,u1,v,v1,s)
                   2322:  *==================================*/
                   2323: /*
                   2324:  * Fast `final' extended gcd algorithm, acting on two ulongs.  Ideally this
                   2325:  * should be replaced with assembler versions wherever possible.  The present
                   2326:  * code essentially does `subtract, compare, and possibly divide' at each step,
                   2327:  * which is reasonable when hardware division (a) exists, (b) is a bit slowish
                   2328:  * and (c) does not depend a lot on the operand values (as on i486).  When
                   2329:  * wordsize division is in fact an assembler routine based on subtraction,
                   2330:  * this strategy may not be the most efficient one.
                   2331:  *
                   2332:  * xxgcduu() should be called with  d > d1 > 0, returns gcd(d,d1), and assigns
                   2333:  * the usual signless cont.frac. recurrence matrix to [u, u1; v, v1]  (i.e.,
                   2334:  * the product of all the [0, 1; 1 q_j] where the leftmost factor arises from
                   2335:  * the quotient of the first division step),  and the information about the
                   2336:  * implied signs to s  (-1 when an odd number of divisions has been done,
                   2337:  * 1 otherwise).  xgcduu() is exactly the same except that u,u1 are not com-
                   2338:  * puted (and not returned, of course).
                   2339:  *
                   2340:  * The input flag f should be set to 1 if we know in advance that gcd(d,d1)==1
                   2341:  * (so we can stop the chain division one step early:  as soon as the remainder
                   2342:  * equals 1).  Use this when you intend to use only what would be v, or only
                   2343:  * what would be u and v, after that final division step, but not u1 and v1.
                   2344:  * With the flag in force and thus without that final step, the interesting
                   2345:  * quantity/ies will still sit in [u1 and] v1, of course.
                   2346:  *
                   2347:  * For computing the inverse of a single-word INTMOD known to exist, pass f=1
                   2348:  * to xgcduu(), and obtain the result from s and v1.  (The routine does the
                   2349:  * right thing when d1==1 already.)  For finishing a multiword modinv known
                   2350:  * to exist, pass f=1 to xxgcduu(), and multiply the returned matrix  (with
                   2351:  * properly adjusted signs)  onto the values v' and v1' previously obtained
                   2352:  * from the multiword division steps.  Actually, just take the scalar product
                   2353:  * of [v',v1'] with [u1,-v1], and change the sign if s==-1.  (If the final
                   2354:  * step had been carried out, it would be [-u,v], and s would also change.)
                   2355:  * For reducing a rational number to lowest terms, pass f=0 to xgcduu().
                   2356:  * Finally, f=0 with xxgcduu() is useful for Bezout computations.
                   2357:  * [Harrumph.  In the above prescription, the sign turns out to be precisely
                   2358:  * wrong.]
                   2359:  * (It is safe for inversemodulo() to call xgcduu() with f=1, because f&1
                   2360:  * doesn't make a difference when gcd(d,d1)>1.  The speedup is negligible.)
                   2361:  *
                   2362:  * In principle, when gcd(d,d1) is known to be 1, it is straightforward to
                   2363:  * recover the final u,u1 given only v,v1 and s.  However, it probably isn't
                   2364:  * worthwhile, as it trades a few multiplications for a division.
                   2365:  *
                   2366:  * Note that these routines do not know and do not need to know about the
                   2367:  * PARI stack.
                   2368:  */
                   2369:
                   2370: ulong
                   2371: xgcduu(ulong d, ulong d1, int f, ulong* v, ulong* v1, long *s)
                   2372: {
                   2373:   ulong xv,xv1, xs, q,res;
                   2374:   LOCAL_HIREMAINDER;
                   2375:
                   2376:   /* The above blurb contained a lie.  The main loop always stops when d1
                   2377:    * has become equal to 1.  If (d1 == 1 && !(f&1)) after the loop, we do
                   2378:    * the final `division' of d by 1 `by hand' as it were.
                   2379:    *
                   2380:    * The loop has already been unrolled once.  Aggressive optimization could
                   2381:    * well lead to a totally unrolled assembler version...
                   2382:    *
                   2383:    * On modern x86 architectures, this loop is a pig anyway.  The division
                   2384:    * instruction always puts its result into the same pair of registers, and
                   2385:    * we always want to use one of them straight away, so pipeline performance
                   2386:    * will suck big time.  An assembler version should probably do a first loop
                   2387:    * computing and storing all the quotients -- their number is bounded in
                   2388:    * advance -- and then assembling the matrix in a second pass.  On other
                   2389:    * architectures where we can cycle through four or so groups of registers
                   2390:    * and exploit a fast ALU result-to-operand feedback path, this is much less
                   2391:    * of an issue.  (Intel sucks.  See http://www.x86.org/ ...)
                   2392:    */
                   2393:   xs = res = 0;
                   2394:   xv = 0UL; xv1 = 1UL;
                   2395:   while (d1 > 1UL)
                   2396:   {
                   2397:     d -= d1;                   /* no need to use subll */
                   2398:     if (d >= d1)
                   2399:     {
                   2400:       hiremainder = 0; q = 1 + divll(d,d1); d = hiremainder;
                   2401:       xv += q * xv1;
                   2402:     }
                   2403:     else
                   2404:       xv += xv1;
                   2405:                                /* possible loop exit */
                   2406:     if (d <= 1UL) { xs=1; break; }
                   2407:                                /* repeat with inverted roles */
                   2408:     d1 -= d;
                   2409:     if (d1 >= d)
                   2410:     {
                   2411:       hiremainder = 0; q = 1 + divll(d1,d); d1 = hiremainder;
                   2412:       xv1 += q * xv;
                   2413:     }
                   2414:     else
                   2415:       xv1 += xv;
                   2416:   } /* while */
                   2417:
                   2418:   if (!(f&1))                  /* division by 1 postprocessing if needed */
                   2419:   {
                   2420:     if (xs && d==1)
                   2421:     { xv1 += d1 * xv; xs = 0; res = 1UL; }
                   2422:     else if (!xs && d1==1)
                   2423:     { xv += d * xv1; xs = 1; res = 1UL; }
                   2424:   }
                   2425:
                   2426:   if (xs)
                   2427:   {
                   2428:     *s = -1; *v = xv1; *v1 = xv;
                   2429:     return (res ? res : (d==1 ? 1UL : d1));
                   2430:   }
                   2431:   else
                   2432:   {
                   2433:     *s = 1; *v = xv; *v1 = xv1;
                   2434:     return (res ? res : (d1==1 ? 1UL : d));
                   2435:   }
                   2436: }
                   2437:
                   2438:
                   2439: ulong
                   2440: xxgcduu(ulong d, ulong d1, int f,
                   2441:        ulong* u, ulong* u1, ulong* v, ulong* v1, long *s)
                   2442: {
                   2443:   ulong xu,xu1, xv,xv1, xs, q,res;
                   2444:   LOCAL_HIREMAINDER;
                   2445:
                   2446:   xs = res = 0;
                   2447:   xu = xv1 = 1UL;
                   2448:   xu1 = xv = 0UL;
                   2449:   while (d1 > 1UL)
                   2450:   {
                   2451:     d -= d1;                   /* no need to use subll */
                   2452:     if (d >= d1)
                   2453:     {
                   2454:       hiremainder = 0; q = 1 + divll(d,d1); d = hiremainder;
                   2455:       xv += q * xv1;
                   2456:       xu += q * xu1;
                   2457:     }
                   2458:     else
                   2459:     { xv += xv1; xu += xu1; }
                   2460:                                /* possible loop exit */
                   2461:     if (d <= 1UL) { xs=1; break; }
                   2462:                                /* repeat with inverted roles */
                   2463:     d1 -= d;
                   2464:     if (d1 >= d)
                   2465:     {
                   2466:       hiremainder = 0; q = 1 + divll(d1,d); d1 = hiremainder;
                   2467:       xv1 += q * xv;
                   2468:       xu1 += q * xu;
                   2469:     }
                   2470:     else
                   2471:     { xv1 += xv; xu1 += xu; }
                   2472:   } /* while */
                   2473:
                   2474:   if (!(f&1))                  /* division by 1 postprocessing if needed */
                   2475:   {
                   2476:     if (xs && d==1)
                   2477:     {
                   2478:       xv1 += d1 * xv;
                   2479:       xu1 += d1 * xu;
                   2480:       xs = 0; res = 1UL;
                   2481:     }
                   2482:     else if (!xs && d1==1)
                   2483:     {
                   2484:       xv += d * xv1;
                   2485:       xu += d * xu1;
                   2486:       xs = 1; res = 1UL;
                   2487:     }
                   2488:   }
                   2489:
                   2490:   if (xs)
                   2491:   {
                   2492:     *s = -1; *u = xu1; *u1 = xu; *v = xv1; *v1 = xv;
                   2493:     return (res ? res : (d==1 ? 1UL : d1));
                   2494:   }
                   2495:   else
                   2496:   {
                   2497:     *s = 1; *u = xu; *u1 = xu1; *v = xv; *v1 = xv1;
                   2498:     return (res ? res : (d1==1 ? 1UL : d));
                   2499:   }
                   2500: }
                   2501:
                   2502: /*==================================
                   2503:  * lgcdii(d,d1,u,u1,v,v1)
                   2504:  *==================================*/
                   2505: /* Lehmer's partial extended gcd algorithm, acting on two t_INT GENs.
                   2506:  *
                   2507:  * Tries to determine, using the leading 2*BITS_IN_LONG significant bits of d
                   2508:  * and a quantity of bits from d1 obtained by a shift of the same displacement,
                   2509:  * as many partial quotients of d/d1 as possible, and assigns to [u,u1;v,v1]
                   2510:  * the product of all the [0, 1; 1, q_j] thus obtained, where the leftmost
                   2511:  * factor arises from the quotient of the first division step.
                   2512:  *
                   2513:  * MUST be called with  d > d1 > 0, and with  d  occupying more than one
                   2514:  * significant word  (if it doesn't, the caller has no business with us;
                   2515:  * he/she/it should use xgcduu() instead).  Returns the number of reduction/
                   2516:  * swap steps carried out, possibly zero, or under certain conditions minus
                   2517:  * that number.  When the return value is nonzero, the caller should use the
                   2518:  * returned recurrence matrix to update its own copies of d,d1.  When the
                   2519:  * return value is non-positive, and the latest remainder after updating
                   2520:  * turns out to be nonzero, the caller should at once attempt a full division,
                   2521:  * rather than first trying lgcdii() again -- this typically happens when we
                   2522:  * are about to encounter a quotient larger than half a word.  (This is not
                   2523:  * detected infallibly -- after a positive return value, it is perfectly
                   2524:  * possible that the next stage will end up needing a full division.  After
                   2525:  * a negative return value, however, this is certain, and should be acted
                   2526:  * upon.)
                   2527:  *
                   2528:  * (The sign information, for which xgcduu() has its return argument s, is now
                   2529:  * implicit in the LSB of our return value, and the caller may take advantage
                   2530:  * of the fact that a return value of +-1 implies u==0,u1==v==1  [only v1 pro-
                   2531:  * vides interesting information in this case].  One might also use the fact
                   2532:  * that if the return value is +-2, then u==1, but this is rather marginal.)
                   2533:  *
                   2534:  * If it was not possible to determine even the first quotient, either because
                   2535:  * we're too close to an integer quotient or because the quotient would be
                   2536:  * larger than one word  (if the `leading digit' of d1 after shifting is all
                   2537:  * zeros),  we return 0 and do not bother to assign anything to the last four
                   2538:  * args.
                   2539:  *
                   2540:  * The division chain might (sometimes) even run to completion.  It will be
                   2541:  * up to the caller to detect this case.
                   2542:  *
                   2543:  * This routine does _not_ change d or d1;  this will also be up to the caller.
                   2544:  *
                   2545:  * Note that this routine does not know and does not need to know about the
                   2546:  * PARI stack.
                   2547:  */
                   2548: /*#define DEBUG_LEHMER 1 */
                   2549: int
                   2550: lgcdii(ulong* d, ulong* d1,
                   2551:        ulong* u, ulong* u1, ulong* v, ulong* v1)
                   2552: {
                   2553:   /* Strategy:  (1) Extract/shift most significant bits.  We assume that d
                   2554:    * has at least two significant words, but we can cope with a one-word d1.
                   2555:    * Let dd,dd1 be the most significant dividend word and matching part of the
                   2556:    * divisor.
                   2557:    * (2) Check for overflow on the first division.  For our purposes, this
                   2558:    * happens when the upper half of dd1 is zero.  (Actually this is detected
                   2559:    * during extraction.)
                   2560:    * (3) Get a fix on the first quotient.  We compute q = floor(dd/dd1), which
                   2561:    * is an upper bound for floor(d/d1), and which gives the true value of the
                   2562:    * latter if (and-almost-only-if) the remainder dd' = dd-q*dd1 is >= q.
                   2563:    * (If it isn't, we give up.  This is annoying because the subsequent full
                   2564:    * division will repeat some work already done, but it happens very infre-
                   2565:    * quently.  Doing the extra-bit-fetch in this case would be awkward.)
                   2566:    * (4) Finish initializations.
                   2567:    *
                   2568:    * The remainder of the action is comparatively boring... The main loop has
                   2569:    * been unrolled once  (so we don't swap things and we can apply Jebelean's
                   2570:    * termination conditions which alternatingly take two different forms during
                   2571:    * successive iterations).  When we first run out of sufficient bits to form
                   2572:    * a quotient, and have an extra word of each operand, we pull out two whole
                   2573:    * word's worth of dividend bits, and divisor bits of matching significance;
                   2574:    * to these we apply our partial matrix (disregarding overflow because the
                   2575:    * result mod 2^(2*BITS_IN_LONG) will in fact give the correct values), and
                   2576:    * re-extract one word's worth of the current dividend and a matching amount
                   2577:    * of divisor bits.  The affair will normally terminate with matrix entries
                   2578:    * just short of a whole word.  (We terminate the inner loop before these can
                   2579:    * possibly overflow.)
                   2580:    */
                   2581:   ulong dd,dd1,ddlo,dd1lo, sh,shc;        /* `digits', shift count */
                   2582:   ulong xu,xu1, xv,xv1, q,res; /* recurrences, partial quotient, count */
                   2583:   ulong tmp0,tmp1,tmp2,tmpd,tmpu,tmpv; /* temps */
                   2584:   long ld, ld1, lz;            /* t_INT effective lengths */
                   2585:   int skip = 0;                        /* a boolean flag */
                   2586:   LOCAL_OVERFLOW;
                   2587:   LOCAL_HIREMAINDER;
                   2588:
                   2589: #ifdef DEBUG_LEHMER
                   2590:   voir(d, -1); voir(d1, -1);
                   2591: #endif
                   2592:   ld = lgefint(d); ld1 = lgefint(d1); lz = ld - ld1; /* >= 0 */
                   2593:   if (lz > 1) return 0;                /* rare, quick and desperate exit */
                   2594:
                   2595:   d += 2; d1 += 2;             /* point at the leading `digits' */
                   2596:   dd1lo = 0;                   /* unless we find something better */
                   2597:   sh = bfffo(*d);              /* obtain dividend left shift count */
                   2598:
                   2599:   if (sh)
                   2600:   {                            /* do the shifting */
                   2601:     shc = BITS_IN_LONG - sh;
                   2602:     if (lz)
                   2603:     {                          /* dividend longer than divisor */
                   2604:       dd1 = (*d1 >> shc);
                   2605:       if (!(HIGHMASK & dd1)) return 0;  /* overflow detected */
                   2606:       if (ld1 > 3)
                   2607:         dd1lo = (*d1 << sh) + (d1[1] >> shc);
                   2608:       else
                   2609:         dd1lo = (*d1 << sh);
                   2610:     }
                   2611:     else
                   2612:     {                          /* dividend and divisor have the same length */
                   2613:       /* dd1 = shiftl(d1,sh) would have left hiremainder==0, and dd1 != 0. */
                   2614:       dd1 = (*d1 << sh);
                   2615:       if (!(HIGHMASK & dd1)) return 0;
                   2616:       if (ld1 > 3)
                   2617:       {
                   2618:         dd1 += (d1[1] >> shc);
                   2619:         if (ld1 > 4)
                   2620:           dd1lo = (d1[1] << sh) + (d1[2] >> shc);
                   2621:         else
                   2622:           dd1lo = (d1[1] << sh);
                   2623:       }
                   2624:     }
                   2625:     /* following lines assume d to have 2 or more significant words */
                   2626:     dd = (*d << sh) + (d[1] >> shc);
                   2627:     if (ld > 4)
                   2628:       ddlo = (d[1] << sh) + (d[2] >> shc);
                   2629:     else
                   2630:       ddlo = (d[1] << sh);
                   2631:   }
                   2632:   else
                   2633:   {                            /* no shift needed */
                   2634:     if (lz) return 0;          /* div'd longer than div'r: o'flow automatic */
                   2635:     dd1 = *d1;
                   2636:     if (!(HIGHMASK & dd1)) return 0;
                   2637:     if(ld1 > 3) dd1lo = d1[1];
                   2638:     /* assume again that d has another significant word */
                   2639:     dd = *d; ddlo = d[1];
                   2640:   }
                   2641: #ifdef DEBUG_LEHMER
                   2642:   fprintf(stderr, "  %lx:%lx, %lx:%lx\n", dd, ddlo, dd1, dd1lo);
                   2643: #endif
                   2644:
                   2645:   /* First subtraction/division stage.  (If a subtraction initially suffices,
                   2646:    * we don't divide at all.)  If a Jebelean condition is violated, and we
                   2647:    * can't fix it even by looking at the low-order bits in ddlo,dd1lo, we
                   2648:    * give up and ask for a full division.  Otherwise we commit the result,
                   2649:    * possibly deciding to re-shift immediately afterwards.
                   2650:    */
                   2651:   dd -= dd1;
                   2652:   if (dd < dd1)
                   2653:   {                            /* first quotient known to be == 1 */
                   2654:     xv1 = 1UL;
                   2655:     if (!dd)                   /* !(Jebelean condition), extraspecial case */
                   2656:     {                          /* note this can actually happen...  Now
                   2657:                                 * q==1 is known, but we underflow already.
                   2658:                                 * OTOH we've just shortened d by a whole word.
                   2659:                                 * Thus we feel pleased with ourselves and
                   2660:                                 * return.  (The re-shift code below would
                   2661:                                 * do so anyway.) */
                   2662:       *u = 0; *v = *u1 = *v1 = 1UL;
                   2663:       return -1;               /* Next step will be a full division. */
                   2664:     } /* if !(Jebelean) then */
                   2665:   }
                   2666:   else
                   2667:   {                            /* division indicated */
                   2668:     hiremainder = 0;
                   2669:     xv1 = 1 + divll(dd, dd1);  /* xv1: alternative spelling of `q', here ;) */
                   2670:     dd = hiremainder;
                   2671:     if (dd < xv1)              /* !(Jebelean cond'), non-extra special case */
                   2672:     {                          /* Attempt to complete the division using the
                   2673:                                 * less significant bits, before skipping right
                   2674:                                 * past the 1st loop to the reshift stage. */
                   2675:       ddlo = subll(ddlo, mulll(xv1, dd1lo));
                   2676:       dd = subllx(dd, hiremainder);
                   2677:
                   2678:       /* If we now have an overflow, q was _certainly_ too large.  Thanks to
                   2679:        * our decision not to get here unless the original dd1 had bits set in
                   2680:        * the upper half of the word, however, we now do know that the correct
                   2681:        * quotient is in fact q-1.  Adjust our data accordingly. */
                   2682:       if (overflow)
                   2683:       {
                   2684:        xv1--;
                   2685:        ddlo = addll(ddlo,dd1lo);
                   2686:        dd = addllx(dd,dd1);    /* overflows again which cancels the borrow */
                   2687:        /* ...and fall through to skip=1 below */
                   2688:       }
                   2689:       else
                   2690:       /* Test Jebelean condition anew, at this point using _all_ the extracted
                   2691:        * bits we have.  This is clutching at straws; we have a more or less
                   2692:        * even chance of succeeding this time.  Note that if we fail, we really
                   2693:        * do not know whether the correct quotient would have been q or some
                   2694:        * smaller value. */
                   2695:        if (!dd && ddlo < xv1) return 0;
                   2696:
                   2697:       /* Otherwise, we now know that q is correct, but we cannot go into the
                   2698:        * 1st loop.  Raise a flag so we'll remember to skip past the loop.
                   2699:        * Get here also after the q-1 adjustment case. */
                   2700:       skip = 1;
                   2701:     } /* if !(Jebelean) then */
                   2702:   }
                   2703:   xu = 0; xv = xu1 = 1UL; res = 1;
                   2704: #ifdef DEBUG_LEHMER
                   2705:   fprintf(stderr, "  q = %ld, %lx, %lx\n", xv1, dd1, dd);
                   2706: #endif
                   2707:
                   2708:   /* Some invariants from here across the first loop:
                   2709:    *
                   2710:    * At this point, and again after we are finished with the first loop and
                   2711:    * subsequent conditional, a division and the associated update of the
                   2712:    * recurrence matrix have just been carried out completely.  The matrix
                   2713:    * xu,xu1;xv,xv1 has been initialized (or updated, possibly with permuted
                   2714:    * columns), and the current remainder == next divisor (dd at the moment)
                   2715:    * is nonzero (it might be zero here, but then skip will have been set).
                   2716:    *
                   2717:    * After the first loop, or when skip is set already, it will also be the
                   2718:    * case that there aren't sufficiently many bits to continue without re-
                   2719:    * shifting.  If the divisor after reshifting is zero, or indeed if it
                   2720:    * doesn't have more than half a word's worth of bits, we will have to
                   2721:    * return at that point.  Otherwise, we proceed into the second loop.
                   2722:    *
                   2723:    * Furthermore, when we reach the re-shift stage, dd:ddlo and dd1:dd1lo will
                   2724:    * already reflect the result of applying the current matrix to the old
                   2725:    * ddorig:ddlo and dd1orig:dd1lo.  (For the first iteration above, this
                   2726:    * was easy to achieve, and we didn't even need to peek into the (now
                   2727:    * no longer existent!) saved words.  After the loop, we'll stop for a
                   2728:    * moment to merge in the ddlo,dd1lo contributions.)
                   2729:    *
                   2730:    * Note that after the first division, even an a priori quotient of 1 cannot
                   2731:    * be trusted until we've checked Jebelean's condition -- it cannot be too
                   2732:    * large, of course, but it might be too small.
                   2733:    */
                   2734:
                   2735:   if (!skip)
                   2736:   {
                   2737:     while (1)
                   2738:     {
                   2739:       /* First half of loop divides dd into dd1, and leaves the recurrence
                   2740:        * matrix xu,...,xv1 groomed the wrong way round (xu,xv will be the newer
                   2741:        * entries) when successful. */
                   2742:       tmpd = dd1 - dd;
                   2743:       if (tmpd < dd)
                   2744:       {                                /* quotient suspected to be 1 */
                   2745: #ifdef DEBUG_LEHMER
                   2746:        q = 1;
                   2747: #endif
                   2748:        tmpu = xu + xu1;        /* cannot overflow -- everything bounded by
                   2749:                                 * the original dd during first loop */
                   2750:        tmpv = xv + xv1;
                   2751:       }
                   2752:       else
                   2753:       {                                /* division indicated */
                   2754:        hiremainder = 0;
                   2755:        q = 1 + divll(tmpd, dd);
                   2756:        tmpd = hiremainder;
                   2757:        tmpu = xu + q*xu1;      /* can't overflow, but may need to be undone */
                   2758:        tmpv = xv + q*xv1;
                   2759:       }
                   2760:
                   2761:       tmp0 = addll(tmpv, xv1);
                   2762:       if ((tmpd < tmpu) || overflow ||
                   2763:          (dd - tmpd < tmp0))   /* !(Jebelean cond.) */
                   2764:        break;                  /* skip ahead to reshift stage */
                   2765:       else
                   2766:       {                                /* commit dd1, xu, xv */
                   2767:        res++;
                   2768:        dd1 = tmpd; xu = tmpu; xv = tmpv;
                   2769: #ifdef DEBUG_LEHMER
                   2770:        fprintf(stderr, "  q = %ld, %lx, %lx [%lu,%lu;%lu,%lu]\n",
                   2771:                q, dd, dd1, xu1, xu, xv1, xv);
                   2772: #endif
                   2773:       }
                   2774:
                   2775:       /* Second half of loop divides dd1 into dd, and the matrix returns to its
                   2776:        * normal arrangement. */
                   2777:       tmpd = dd - dd1;
                   2778:       if (tmpd < dd1)
                   2779:       {                                /* quotient suspected to be 1 */
                   2780: #ifdef DEBUG_LEHMER
                   2781:        q = 1;
                   2782: #endif
                   2783:        tmpu = xu1 + xu;        /* cannot overflow */
                   2784:        tmpv = xv1 + xv;
                   2785:       }
                   2786:       else
                   2787:       {                                /* division indicated */
                   2788:        hiremainder = 0;
                   2789:        q = 1 + divll(tmpd, dd1);
                   2790:        tmpd = hiremainder;
                   2791:        tmpu = xu1 + q*xu;
                   2792:        tmpv = xv1 + q*xv;
                   2793:       }
                   2794:
                   2795:       tmp0 = addll(tmpu, xu);
                   2796:       if ((tmpd < tmpv) || overflow ||
                   2797:          (dd1 - tmpd < tmp0))  /* !(Jebelean cond.) */
                   2798:        break;                  /* skip ahead to reshift stage */
                   2799:       else
                   2800:       {                                /* commit dd, xu1, xv1 */
                   2801:        res++;
                   2802:        dd = tmpd; xu1 = tmpu; xv1 = tmpv;
                   2803: #ifdef DEBUG_LEHMER
                   2804:        fprintf(stderr, "  q = %ld, %lx, %lx [%lu,%lu;%lu,%lu]\n",
                   2805:                q, dd1, dd, xu, xu1, xv, xv1);
                   2806: #endif
                   2807:       }
                   2808:
                   2809:     } /* end of first loop */
                   2810:
                   2811:     /* Intermezzo: update dd:ddlo, dd1:dd1lo.  (But not if skip is set.) */
                   2812:
                   2813:     if (res&1)
                   2814:     {
                   2815:       /* after failed division in 1st half of loop:
                   2816:        * [dd1:dd1lo,dd:ddlo] = [ddorig:ddlo,dd1orig:dd1lo]
                   2817:        *                       * [ -xu, xu1 ; xv, -xv1 ]
                   2818:        * (Actually, we only multiply [ddlo,dd1lo] onto the matrix and
                   2819:        * add the high-order remainders + overflows onto [dd1,dd].)
                   2820:        */
                   2821:       tmp1 = mulll(ddlo, xu); tmp0 = hiremainder;
                   2822:       tmp1 = subll(mulll(dd1lo,xv), tmp1);
                   2823:       dd1 += subllx(hiremainder, tmp0);
                   2824:       tmp2 = mulll(ddlo, xu1); tmp0 = hiremainder;
                   2825:       ddlo = subll(tmp2, mulll(dd1lo,xv1));
                   2826:       dd += subllx(tmp0, hiremainder);
                   2827:       dd1lo = tmp1;
                   2828:     }
                   2829:     else
                   2830:     {
                   2831:       /* after failed division in 2nd half of loop:
                   2832:        * [dd:ddlo,dd1:dd1lo] = [ddorig:ddlo,dd1orig:dd1lo]
                   2833:        *                       * [ xu1, -xu ; -xv1, xv ]
                   2834:        * (Actually, we only multiply [ddlo,dd1lo] onto the matrix and
                   2835:        * add the high-order remainders + overflows onto [dd,dd1].)
                   2836:        */
                   2837:       tmp1 = mulll(ddlo, xu1); tmp0 = hiremainder;
                   2838:       tmp1 = subll(tmp1, mulll(dd1lo,xv1));
                   2839:       dd += subllx(tmp0, hiremainder);
                   2840:       tmp2 = mulll(ddlo, xu); tmp0 = hiremainder;
                   2841:       dd1lo = subll(mulll(dd1lo,xv), tmp2);
                   2842:       dd1 += subllx(hiremainder, tmp0);
                   2843:       ddlo = tmp1;
                   2844:     }
                   2845: #ifdef DEBUG_LEHMER
                   2846:     fprintf(stderr, "  %lx:%lx, %lx:%lx\n", dd, ddlo, dd1, dd1lo);
                   2847: #endif
                   2848:   } /* end of skip-pable section:  get here also, with res==1, when there
                   2849:      * was a problem immediately after the very first division. */
                   2850:
                   2851:   /* Re-shift.  Note:  the shift count _can_ be zero, viz. under the following
                   2852:    * precise conditions:  The original dd1 had its topmost bit set, so the 1st
                   2853:    * q was 1, and after subtraction, dd had its topmost bit unset.  If now
                   2854:    * dd==0, we'd have taken the return exit already, so we couldn't have got
                   2855:    * here.  If not, then it must have been the second division which has gone
                   2856:    * amiss  (because dd1 was very close to an exact multiple of the remainder
                   2857:    * dd value, so this will be very rare).  At this point, we'd have a fairly
                   2858:    * slim chance of fixing things by re-examining dd1:dd1lo vs. dd:ddlo, but
                   2859:    * this is not guaranteed to work.  Instead of trying, we return at once.
                   2860:    * The caller will see to it that the initial subtraction is re-done using
                   2861:    * _all_ the bits of both operands, which already helps, and the next round
                   2862:    * will either be a full division  (if dd occupied a halfword or less),  or
                   2863:    * another llgcdii() first step.  In the latter case, since we try a little
                   2864:    * harder during our first step, we may actually be able to fix the problem,
                   2865:    * and get here again with improved low-order bits and with another step
                   2866:    * under our belt.  Otherwise we'll have given up above and forced a full-
                   2867:    * blown division.
                   2868:    *
                   2869:    * If res is even, the shift count _cannot_ be zero.  (The first step forces
                   2870:    * a zero into the remainder's MSB, and all subsequent remainders will have
                   2871:    * inherited it.)
                   2872:    *
                   2873:    * The re-shift stage exits if the next divisor has at most half a word's
                   2874:    * worth of bits.
                   2875:    *
                   2876:    * For didactic reasons, the second loop will be arranged in the same way
                   2877:    * as the first -- beginning with the division of dd into dd1, as if res
                   2878:    * was odd.  To cater for this, if res is actually even, we swap things
                   2879:    * around during reshifting.  (During the second loop, the parity of res
                   2880:    * does not matter;  we know in which half of the loop we are when we decide
                   2881:    * to return.)
                   2882:    */
                   2883: #ifdef DEBUG_LEHMER
                   2884:   fprintf(stderr, "(sh)");
                   2885: #endif
                   2886:
                   2887:   if (res&1)
                   2888:   {                            /* after odd number of division(s) */
                   2889:     if (dd1 && (sh = bfffo(dd1)))
                   2890:     {
                   2891:       shc = BITS_IN_LONG - sh;
                   2892:       dd = (ddlo >> shc) + (dd << sh);
                   2893:       if (!(HIGHMASK & dd))
                   2894:       {
                   2895:        *u = xu; *u1 = xu1; *v = xv; *v1 = xv1;
                   2896:        return -res;            /* full division asked for */
                   2897:       }
                   2898:       dd1 = (dd1lo >> shc) + (dd1 << sh);
                   2899:     }
                   2900:     else
                   2901:     {                          /* time to return: <= 1 word left, or sh==0 */
                   2902:       *u = xu; *u1 = xu1; *v = xv; *v1 = xv1;
                   2903:       return res;
                   2904:     }
                   2905:   }
                   2906:   else
                   2907:   {                            /* after even number of divisions */
                   2908:     if (dd)
                   2909:     {
                   2910:       sh = bfffo(dd);          /* Known to be positive. */
                   2911:       shc = BITS_IN_LONG - sh;
                   2912:                                /* dd:ddlo will become the new dd1, and v.v. */
                   2913:       tmpd = (ddlo >> shc) + (dd << sh);
                   2914:       dd = (dd1lo >> shc) + (dd1 << sh);
                   2915:       dd1 = tmpd;
                   2916:       /* This has completed the swap;  now dd is again the current divisor.
                   2917:        * The following test originally inspected dd1 -- a most subtle and
                   2918:        * most annoying bug. The Management. */
                   2919:       if (HIGHMASK & dd)
                   2920:       {
                   2921:        /* recurrence matrix is the wrong way round;  swap it. */
                   2922:        tmp0 = xu; xu = xu1; xu1 = tmp0;
                   2923:        tmp0 = xv; xv = xv1; xv1 = tmp0;
                   2924:       }
                   2925:       else
                   2926:       {
                   2927:        /* recurrence matrix is the wrong way round;  fix this. */
                   2928:        *u = xu1; *u1 = xu; *v = xv1; *v1 = xv;
                   2929:        return -res;            /* full division asked for */
                   2930:       }
                   2931:     }
                   2932:     else
                   2933:     {                          /* time to return: <= 1 word left */
                   2934:       *u = xu1; *u1 = xu; *v = xv1; *v1 = xv;
                   2935:       return res;
                   2936:     }
                   2937:   } /* end reshift */
                   2938:
                   2939: #ifdef DEBUG_LEHMER
                   2940:   fprintf(stderr, "  %lx:%lx, %lx:%lx\n", dd, ddlo, dd1, dd1lo);
                   2941: #endif
                   2942:
                   2943:   /* The Second Loop.  Rip-off of the first, but we now check for overflow
                   2944:    * in the recurrences.  Returns instead of breaking when we cannot fix the
                   2945:    * quotient any longer.
                   2946:    */
                   2947:
                   2948:   for(;;)
                   2949:   {
                   2950:     /* First half of loop divides dd into dd1, and leaves the recurrence
                   2951:      * matrix xu,...,xv1 groomed the wrong way round (xu,xv will be the newer
                   2952:      * entries) when successful. */
                   2953:     tmpd = dd1 - dd;
                   2954:     if (tmpd < dd)
                   2955:     {                          /* quotient suspected to be 1 */
                   2956: #ifdef DEBUG_LEHMER
                   2957:       q = 1;
                   2958: #endif
                   2959:       tmpu = xu + xu1;
                   2960:       tmpv = addll(xv, xv1);   /* xv,xv1 will overflow first */
                   2961:       tmp1 = overflow;
                   2962:     }
                   2963:     else
                   2964:     {                          /* division indicated */
                   2965:       hiremainder = 0;
                   2966:       q = 1 + divll(tmpd, dd);
                   2967:       tmpd = hiremainder;
                   2968:       tmpu = xu + q*xu1;
                   2969:       tmpv = addll(xv, mulll(q,xv1));
                   2970:       tmp1 = overflow | hiremainder;
                   2971:     }
                   2972:
                   2973:     tmp0 = addll(tmpv, xv1);
                   2974:     if ((tmpd < tmpu) || overflow || tmp1 ||
                   2975:        (dd - tmpd < tmp0))     /* !(Jebelean cond.) */
                   2976:     {
                   2977:       /* The recurrence matrix has not yet been warped... */
                   2978:       *u = xu; *u1 = xu1; *v = xv; *v1 = xv1;
                   2979:       return res;
                   2980:     }
                   2981:     else
                   2982:     {                          /* commit dd1, xu, xv */
                   2983:       res++;
                   2984:       dd1 = tmpd; xu = tmpu; xv = tmpv;
                   2985: #ifdef DEBUG_LEHMER
                   2986:       fprintf(stderr, "  q = %ld, %lx, %lx\n", q, dd, dd1);
                   2987: #endif
                   2988:     }
                   2989:
                   2990:     /* Second half of loop divides dd1 into dd, and the matrix returns to its
                   2991:      * normal arrangement. */
                   2992:     tmpd = dd - dd1;
                   2993:     if (tmpd < dd1)
                   2994:     {                          /* quotient suspected to be 1 */
                   2995: #ifdef DEBUG_LEHMER
                   2996:       q = 1;
                   2997: #endif
                   2998:       tmpu = xu1 + xu;
                   2999:       tmpv = addll(xv1, xv);
                   3000:       tmp1 = overflow;
                   3001:     }
                   3002:     else
                   3003:     {                          /* division indicated */
                   3004:       hiremainder = 0;
                   3005:       q = 1 + divll(tmpd, dd1);
                   3006:       tmpd = hiremainder;
                   3007:       tmpu = xu1 + q*xu;
                   3008:       tmpv = addll(xv1, mulll(q, xv));
                   3009:       tmp1 = overflow | hiremainder;
                   3010:     }
                   3011:
                   3012:     tmp0 = addll(tmpu, xu);
                   3013:     if ((tmpd < tmpv) || overflow || tmp1 ||
                   3014:        (dd1 - tmpd < tmp0))    /* !(Jebelean cond.) */
                   3015:     {
                   3016:       /* The recurrence matrix has not yet been unwarped, so it is
                   3017:        * the wrong way round;  fix this. */
                   3018:       *u = xu1; *u1 = xu; *v = xv1; *v1 = xv;
                   3019:       return res;
                   3020:     }
                   3021:     else
                   3022:     {                          /* commit dd, xu1, xv1 */
                   3023:       res++;
                   3024:       dd = tmpd; xu1 = tmpu; xv1 = tmpv;
                   3025: #ifdef DEBUG_LEHMER
                   3026:       fprintf(stderr, "  q = %ld, %lx, %lx\n", q, dd1, dd);
                   3027: #endif
                   3028:     }
                   3029:
                   3030:   } /* end of second loop */
                   3031:
                   3032:   return(0);                   /* never reached */
                   3033: }
                   3034:
                   3035: /*==================================
                   3036:  * invmod(a,b,res)
                   3037:  *==================================
                   3038:  *    If a is invertible, return 1, and set res  = a^{ -1 }
                   3039:  *    Otherwise, return 0, and set res = gcd(a,b)
                   3040:
                   3041:  * Temporary - to be replaced with mpxgcd()
                   3042:  * I think we won't need to change much ... just the parameter-passing and
                   3043:  * return value conventions, and computing a final u in addition to a final
                   3044:  * v value before returning (and doing so even when the gcd isn't 1)
                   3045:  */
                   3046:
                   3047: #define mysetsigne(d,s) { fprintferr("%ld %ld\n",s,signe(d)); if (signe(d)==-(s)) setsigne(d,s); }
                   3048:
                   3049: int
                   3050: invmod(GEN a, GEN b, GEN *res)
                   3051: {
                   3052:   GEN v,v1,d,d1,q,r;
                   3053:   long av,av1,lim;
                   3054:   long s;
                   3055:   ulong g;
                   3056:   ulong xu,xu1,xv,xv1;         /* Lehmer stage recurrence matrix */
                   3057:   int lhmres;                  /* Lehmer stage return value */
                   3058:
                   3059:   if (typ(a) != t_INT || typ(b) != t_INT) err(arither1);
                   3060:   if (!signe(b)) { *res=absi(a); return 0; }
                   3061:   av = avma;
                   3062:   if (lgefint(b) == 3) /* single-word affair */
                   3063:   {
                   3064:     d1 = modiu(a, (ulong)b[2]);
                   3065:     if (d1 == gzero)
                   3066:     {
                   3067:       if (b[2] == 1L)
                   3068:         { *res = gzero; return 1; }
                   3069:       else
                   3070:         { *res = absi(b); return 0; }
                   3071:     }
                   3072:     g = xgcduu((ulong)b[2], (ulong)d1[2], 1, &xv, &xv1, &s);
                   3073: #ifdef DEBUG_LEHMER
                   3074:     fprintferr(" <- %lu,%lu\n", (ulong)b[2], (ulong)d1[2]);
                   3075:     fprintferr(" -> %lu,%ld,%lu; %lx\n", g,s,xv1,avma);
                   3076: #endif
                   3077:     avma = av;
                   3078:     if (g != 1UL) { *res = utoi(g); return 0; }
                   3079:     xv = xv1 % (ulong)b[2]; if (s < 0) xv = ((ulong)b[2]) - xv;
                   3080:     *res = utoi(xv); return 1;
                   3081:   }
                   3082:
                   3083:   (void)new_chunk(lgefint(b));
                   3084:   d = absi(b); d1 = modii(a,d);
                   3085:
                   3086:   v=gzero; v1=gun;     /* general case */
                   3087: #ifdef DEBUG_LEHMER
                   3088:   fprintferr("INVERT: -------------------------\n");
                   3089:   output(d1);
                   3090: #endif
                   3091:   av1 = avma; lim = stack_lim(av,1);
                   3092:
                   3093:   while (lgefint(d) > 3 && signe(d1))
                   3094:   {
                   3095: #ifdef DEBUG_LEHMER
                   3096:     fprintferr("Calling Lehmer:\n");
                   3097: #endif
                   3098:     lhmres = lgcdii((ulong*)d, (ulong*)d1, &xu, &xu1, &xv, &xv1);
                   3099:     if (lhmres != 0)           /* check progress */
                   3100:     {                          /* apply matrix */
                   3101: #ifdef DEBUG_LEHMER
                   3102:       fprintferr("Lehmer returned %d [%lu,%lu;%lu,%lu].\n",
                   3103:              lhmres, xu, xu1, xv, xv1);
                   3104: #endif
                   3105:       if ((lhmres == 1) || (lhmres == -1))
                   3106:       {
                   3107:        if (xv1 == 1)
                   3108:        {
                   3109:          r = subii(d,d1); d=d1; d1=r;
                   3110:          a = subii(v,v1); v=v1; v1=a;
                   3111:        }
                   3112:        else
                   3113:        {
                   3114:          r = subii(d, mului(xv1,d1)); d=d1; d1=r;
                   3115:          a = subii(v, mului(xv1,v1)); v=v1; v1=a;
                   3116:        }
                   3117:       }
                   3118:       else
                   3119:       {
                   3120:        r  = subii(muliu(d,xu),  muliu(d1,xv));
                   3121:        a  = subii(muliu(v,xu),  muliu(v1,xv));
                   3122:        d1 = subii(muliu(d,xu1), muliu(d1,xv1)); d = r;
                   3123:        v1 = subii(muliu(v,xu1), muliu(v1,xv1)); v = a;
                   3124:         if (lhmres&1) {
                   3125:           setsigne(d,-signe(d));
                   3126:           setsigne(v,-signe(v));
                   3127:         }
                   3128:         else {
                   3129:           setsigne(d1,-signe(d1));
                   3130:           setsigne(v1,-signe(v1));
                   3131:         }
                   3132:       }
                   3133:     }
                   3134: #ifdef DEBUG_LEHMER
                   3135:     else
                   3136:       fprintferr("Lehmer returned 0.\n");
                   3137:     output(d); output(d1); output(v); output(v1);
                   3138:     sleep(1);
                   3139: #endif
                   3140:
                   3141:     if (lhmres <= 0 && signe(d1))
                   3142:     {
                   3143:       q = dvmdii(d,d1,&r);
                   3144: #ifdef DEBUG_LEHMER
                   3145:       fprintferr("Full division:\n");
                   3146:       printf("  q = "); output(q); sleep (1);
                   3147: #endif
                   3148:       a = subii(v,mulii(q,v1));
                   3149:       v=v1; v1=a;
                   3150:       d=d1; d1=r;
                   3151:     }
                   3152:     if (low_stack(lim, stack_lim(av,1)))
                   3153:     {
                   3154:       GEN *gptr[4]; gptr[0]=&d; gptr[1]=&d1; gptr[2]=&v; gptr[3]=&v1;
                   3155:       if(DEBUGMEM>1) err(warnmem,"invmod");
                   3156:       gerepilemany(av1,gptr,4);
                   3157:     }
                   3158:   } /* end while */
                   3159:
                   3160:   /* Postprocessing - final sprint */
                   3161:   if (signe(d1))
                   3162:   {
                   3163:     /* Assertions: lgefint(d)==lgefint(d1)==3, and
                   3164:      * gcd(d,d1) is nonzero and fits into one word
                   3165:      */
                   3166:     g = xxgcduu(d[2], d1[2], 1, &xu, &xu1, &xv, &xv1, &s);
                   3167: #ifdef DEBUG_LEHMER
                   3168:     output(d);output(d1);output(v);output(v1);
                   3169:     fprintferr(" <- %lu,%lu\n", (ulong)d[2], (ulong)d1[2]);
                   3170:     fprintferr(" -> %lu,%ld,%lu; %lx\n", g,s,xv1,avma);
                   3171: #endif
                   3172:     if (g != 1UL) { avma = av; *res = utoi(g); return 0; }
                   3173:     /* (From the xgcduu() blurb:)
                   3174:      * For finishing the multiword modinv, we now have to multiply the
                   3175:      * returned matrix  (with properly adjusted signs)  onto the values
                   3176:      * v' and v1' previously obtained from the multiword division steps.
                   3177:      * Actually, it is sufficient to take the scalar product of [v',v1']
                   3178:      * with [u1,-v1], and change the sign if s==1.
                   3179:      */
                   3180:     v = subii(muliu(v,xu1),muliu(v1,xv1));
                   3181:     if (s > 0) setsigne(v,-signe(v));
                   3182:     avma = av; *res = modii(v,b);
                   3183: #ifdef DEBUG_LEHMER
                   3184:     output(*res); fprintfderr("============================Done.\n");
                   3185:     sleep(1);
                   3186: #endif
                   3187:     return 1;
                   3188:   }
                   3189:   /* get here when the final sprint was skipped (d1 was zero already) */
                   3190:   avma = av;
                   3191:   if (!egalii(d,gun)) { *res = icopy(d); return 0; }
                   3192:   *res = modii(v,b);
                   3193: #ifdef DEBUG_LEHMER
                   3194:   output(*res); fprintferr("============================Done.\n");
                   3195:   sleep(1);
                   3196: #endif
                   3197:   return 1;
                   3198: }

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