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

Annotation of OpenXM_contrib/pari/src/basemath/trans1.c, Revision 1.1.1.1

1.1       maekawa     1: /********************************************************************/
                      2: /**                                                                **/
                      3: /**                   TRANSCENDENTAL FONCTIONS                     **/
                      4: /**                                                                **/
                      5: /********************************************************************/
                      6: /* $Id: trans1.c,v 1.2 1999/09/23 17:50:57 karim Exp $ */
                      7: #include "pari.h"
                      8:
                      9: #ifdef LONG_IS_64BIT
                     10: # define C31 (9223372036854775808.0) /* VERYBIGINT * 1.0 */
                     11: # define SQRTVERYBIGINT 3037000500   /* ceil(sqrt(VERYBIGINT)) */
                     12: # define CBRTVERYBIGINT 2097152      /* ceil(cbrt(VERYBIGINT)) */
                     13: #else
                     14: # define C31 (2147483648.0)
                     15: # define SQRTVERYBIGINT 46341
                     16: # define CBRTVERYBIGINT  1291
                     17: #endif
                     18:
                     19:
                     20: /********************************************************************/
                     21: /**                                                                **/
                     22: /**                        FONCTION PI                             **/
                     23: /**                                                                **/
                     24: /********************************************************************/
                     25:
                     26: void
                     27: constpi(long prec)
                     28: {
                     29:   GEN p1,p2,p3,tmppi;
                     30:   long l,n,n1,av1,av2;
                     31:   double alpha;
                     32:
                     33: #define k1  545140134
                     34: #define k2  13591409
                     35: #define k3  640320
                     36: #define alpha2 (1.4722004/(BYTES_IN_LONG/4))  /* 3*log(k3/12)/(32*log(2)) */
                     37:
                     38:   if (gpi && lg(gpi) >= prec) return;
                     39:
                     40:   av1 = avma; tmppi = newbloc(prec);
                     41:   *tmppi = evaltyp(t_REAL) | evallg(prec);
                     42:
                     43:   n=(long)(1+(prec-2)/alpha2);
                     44:   n1=6*n-1; p1=cgetr(prec);
                     45:   p2=addsi(k2,mulss(n,k1));
                     46:   affir(p2,p1);
                     47:
                     48:   /* initialisation longueur mantisse */
                     49:   if (prec>=4) l=4; else l=prec;
                     50:   setlg(p1,l); alpha=l;
                     51:
                     52:   av2 = avma;
                     53:   while (n)
                     54:   {
                     55:     if (n < CBRTVERYBIGINT)
                     56:       p3 = divrs(mulsr(n1-4,mulsr(n1*(n1-2),p1)),n*n*n);
                     57:     else
                     58:     {
                     59:       if (n1 < SQRTVERYBIGINT)
                     60:        p3 = divrs(divrs(mulsr(n1-4,mulsr(n1*(n1-2),p1)),n*n),n);
                     61:       else
                     62:        p3 = divrs(divrs(mulsr(n1-4,mulsr(n1,mulsr(n1-2,p1))),n*n),n);
                     63:     }
                     64:     p3 = divrs(divrs(p3,100100025), 327843840);
                     65:     subisz(p2,k1,p2); subirz(p2,p3,p1);
                     66:     alpha += alpha2; l = (long)(1+alpha); /* nouvelle longueur mantisse */
                     67:     if (l>prec) l=prec;
                     68:     setlg(p1,l); avma = av2;
                     69:     n--; n1-=6;
                     70:   }
                     71:   p1 = divsr(53360,p1);
                     72:   mulrrz(p1,gsqrt(stoi(k3),prec), tmppi);
                     73:   gunclone(gpi); avma = av1;  gpi = tmppi;
                     74: }
                     75:
                     76: GEN
                     77: mppi(long prec)
                     78: {
                     79:   GEN x = cgetr(prec);
                     80:   constpi(prec+1); affrr(gpi,x); return x;
                     81: }
                     82:
                     83: /********************************************************************/
                     84: /**                                                                **/
                     85: /**                      FONCTION EULER                            **/
                     86: /**                                                                **/
                     87: /********************************************************************/
                     88:
                     89: void
                     90: consteuler(long prec)
                     91: {
                     92:   GEN u,v,a,b,tmpeuler;
                     93:   long l,n,k,x,av1,av2;
                     94:
                     95:   if (geuler && lg(geuler) >= prec) return;
                     96:
                     97:   av1 = avma; tmpeuler = newbloc(prec);
                     98:   *tmpeuler = evaltyp(t_REAL) | evallg(prec);
                     99:
                    100:   l = prec+1; x = (long) (1 + (bit_accuracy(l) >> 2) * LOG2);
                    101:   a=cgetr(l); affsr(x,a); u=mplog(a); setsigne(u,-1); affrr(u,a);
                    102:   b=realun(l);
                    103:   v=realun(l);
                    104:   n=(long)(1+3.591*x); /* z=3.591: z*[ ln(z)-1 ]=1 */
                    105:   av2 = avma;
                    106:   if (x < SQRTVERYBIGINT)
                    107:   {
                    108:     long xx = x*x;
                    109:     for (k=1; k<=n; k++)
                    110:     {
                    111:       divrsz(mulsr(xx,b),k*k, b);
                    112:       divrsz(addrr(divrs(mulsr(xx,a),k),b),k, a);
                    113:       addrrz(u,a,u); addrrz(v,b,v); avma = av2;
                    114:     }
                    115:   }
                    116:   else
                    117:   {
                    118:     GEN xx = mulss(x,x);
                    119:     for (k=1; k<=n; k++)
                    120:     {
                    121:       divrsz(mulir(xx,b),k*k, b);
                    122:       divrsz(addrr(divrs(mulir(xx,a),k),b),k, a);
                    123:       addrrz(u,a,u); addrrz(v,b,v); avma = av2;
                    124:     }
                    125:   }
                    126:   divrrz(u,v,tmpeuler);
                    127:   gunclone(geuler); avma = av1; geuler = tmpeuler;
                    128: }
                    129:
                    130: GEN
                    131: mpeuler(long prec)
                    132: {
                    133:   GEN x=cgetr(prec);
                    134:   consteuler(prec+1); affrr(geuler,x); return x;
                    135: }
                    136:
                    137: /********************************************************************/
                    138: /**                                                                **/
                    139: /**       CONVERSION DE TYPES POUR FONCTIONS TRANSCENDANTES        **/
                    140: /**                                                                **/
                    141: /********************************************************************/
                    142:
                    143: GEN
                    144: transc(GEN (*f)(GEN,long), GEN x, long prec)
                    145: {
                    146:   GEN p1,p2,y;
                    147:   long lx,i,av,tetpil;
                    148:
                    149:   av=avma;
                    150:   switch(typ(x))
                    151:   {
                    152:     case t_INT: case t_FRAC: case t_FRACN:
                    153:       p1=cgetr(prec); gaffect(x,p1); tetpil=avma;
                    154:       return gerepile(av,tetpil,f(p1,prec));
                    155:
                    156:     case t_COMPLEX: case t_QUAD:
                    157:       av=avma; p1=gmul(x,realun(prec)); tetpil=avma;
                    158:       return gerepile(av,tetpil,f(p1,prec));
                    159:
                    160:     case t_POL: case t_RFRAC: case t_RFRACN:
                    161:       p1=tayl(x,gvar(x),precdl); tetpil=avma;
                    162:       return gerepile(av,tetpil,f(p1,prec));
                    163:
                    164:     case t_VEC: case t_COL: case t_MAT:
                    165:       lx=lg(x); y=cgetg(lx,typ(x));
                    166:       for (i=1; i<lx; i++)
                    167:        y[i] = (long) f((GEN)x[i],prec);
                    168:       return y;
                    169:
                    170:     case t_POLMOD:
                    171:       av=avma; p1=roots((GEN)x[1],prec); lx=lg(p1); p2=cgetg(lx,t_COL);
                    172:       for (i=1; i<lx; i++) p2[i]=lpoleval((GEN)x[2],(GEN)p1[i]);
                    173:       tetpil=avma; y=cgetg(lx,t_COL);
                    174:       for (i=1; i<lx; i++)
                    175:         y[i] = (long)f((GEN)p2[i],prec);
                    176:       return gerepile(av,tetpil,y);
                    177:
                    178:     case t_QFR: case t_QFI:
                    179:       err(talker,"quadratic forms cannot be used in transcendental functions");
                    180:   }
                    181:   return f(x,prec);
                    182: }
                    183:
                    184: /*******************************************************************/
                    185: /*                                                                 */
                    186: /*                            POWERING                             */
                    187: /*                                                                 */
                    188: /*******************************************************************/
                    189: GEN real_unit_form(GEN x);
                    190: GEN imag_unit_form(GEN x);
                    191:
                    192: static GEN
                    193: puiss0(GEN x)
                    194: {
                    195:   long lx,i;
                    196:   GEN y;
                    197:
                    198:   switch(typ(x))
                    199:   {
                    200:     case t_INT: case t_REAL: case t_FRAC: case t_FRACN: case t_PADIC:
                    201:       return gun;
                    202:
                    203:     case t_INTMOD:
                    204:       y=cgetg(3,t_INTMOD); copyifstack(x[1],y[1]); y[2]=un; break;
                    205:
                    206:     case t_COMPLEX:
                    207:       y=cgetg(3,t_COMPLEX); y[1]=un; y[2]=zero; break;
                    208:
                    209:     case t_QUAD:
                    210:       y=cgetg(4,t_QUAD); copyifstack(x[1],y[1]);
                    211:       y[2]=un; y[3]=zero; break;
                    212:
                    213:     case t_POLMOD:
                    214:       y=cgetg(3,t_POLMOD); copyifstack(x[1],y[1]);
                    215:       y[2]=lpolun[varn(x[1])]; break;
                    216:
                    217:     case t_POL: case t_SER: case t_RFRAC: case t_RFRACN:
                    218:       return polun[gvar(x)];
                    219:
                    220:     case t_MAT:
                    221:       lx=lg(x); if (lx==1) return cgetg(1,t_MAT);
                    222:       if (lx != (lg(x[1]))) err(mattype1,"gpowgs");
                    223:       y = idmat(lx-1);
                    224:       for (i=1; i<lx; i++) coeff(y,i,i) = lpuigs(gcoeff(x,i,i),0);
                    225:       break;
                    226:     case t_QFR: return real_unit_form(x);
                    227:     case t_QFI: return imag_unit_form(x);
                    228:     case t_VEC: case t_COL:
                    229:       err(typeer,"gpowgs");
                    230:   }
                    231:   return y;
                    232: }
                    233:
                    234: /* INTEGER POWERING (a^n for integer a and integer n > 1)
                    235:  *
                    236:  * Nonpositive powers and exponent one should be handled by gpow() and
                    237:  * gpowgs() in trans1.c, which at the time of this writing is the only place
                    238:  * where the following is [slated to be] used.
                    239:  *
                    240:  * Use left shift binary algorithm (RS is wasteful: multiplies big numbers,
                    241:  * with LS one of them is the base, hence small). If result is nonzero, its
                    242:  * sign is set to s (= +-1) regardless of what it would have been. This makes
                    243:  * life easier for gpow()/gpowgs(), which otherwise might do a
                    244:  * setsigne(gun,-1)... -- GN1998May04
                    245:  */
                    246: static GEN
                    247: puissii(GEN a, GEN n, long s)
                    248: {
                    249:   long av,*p,man,k,nb,lim;
                    250:   GEN y;
                    251:
                    252:   if (!signe(a)) return gzero; /* a==0 */
                    253:   if (lgefint(a)==3)
                    254:   { /* easy if |a| < 3 */
                    255:     if (a[2] == 1) return (s>0)? gun: negi(gun);
                    256:     if (a[2] == 2) { a = shifti(gun, itos(n)); setsigne(a,s); return a; }
                    257:   }
                    258:   if (lgefint(n)==3)
                    259:   { /* or if |n| < 3 */
                    260:     if (n[2] == 1) { a = icopy(a); setsigne(a,s); return a; }
                    261:     if (n[2] == 2) return sqri(a);
                    262:   }
                    263:   /* be paranoid about memory consumption */
                    264:   av=avma; lim=stack_lim(av,1);
                    265:   y = a; p = n+2; man = *p;
                    266:   /* normalize, i.e set highest bit to 1 (we know man != 0) */
                    267:   k = 1+bfffo(man); man<<=k; k = BITS_IN_LONG-k;
                    268:   /* first bit is now implicit */
                    269:   for (nb=lgefint(n)-2;;)
                    270:   {
                    271:     for (; k; man<<=1,k--)
                    272:     {
                    273:       y = sqri(y);
                    274:       if (low_stack(lim, stack_lim(av,1)))
                    275:       {
                    276:         if (DEBUGMEM>1) err(warnmem,"[1]: puissii");
                    277:         y = gerepileupto(av,y);
                    278:       }
                    279:       if (man < 0)
                    280:       { /* first bit is set: multiply by the base */
                    281:         y = mulii(y,a);
                    282:         if (low_stack(lim, stack_lim(av,1)))
                    283:         {
                    284:           if (DEBUGMEM>1) err(warnmem,"[2]: puissii");
                    285:           y = gerepileupto(av,y);
                    286:         }
                    287:       }
                    288:     }
                    289:     nb--; if (nb == 0) break;
                    290:     man = *++p, k = BITS_IN_LONG;
                    291:   }
                    292:   setsigne(y,s); return gerepileupto(av,y);
                    293: }
                    294:
                    295: GEN
                    296: gpowgs(GEN x, long n)
                    297: {
                    298:   long lim,av,m,tx;
                    299:   static long gn[3] = {evaltyp(t_INT)|m_evallg(3), 0, 0};
                    300:   GEN y;
                    301:
                    302:   if (n == 0) return puiss0(x);
                    303:   if (n == 1) return gcopy(x);
                    304:   if (n ==-1) return ginv(x);
                    305:   if (n>0)
                    306:     { gn[1] = evalsigne( 1) | evallgefint(3); gn[2]= n; }
                    307:   else
                    308:     { gn[1] = evalsigne(-1) | evallgefint(3); gn[2]=-n; }
                    309:  /* If gpowgs were only ever called from gpow, the switch wouldn't be needed.
                    310:   * In fact, under current word and bit field sizes, an integer power with
                    311:   * multiword exponent will always overflow.  But it seems easier to call
                    312:   * puissii|powmodulo() with a mock-up GEN as 2nd argument than to write
                    313:   * separate versions for a long exponent.  Note that n = HIGHBIT is an
                    314:   * invalid argument. --GN
                    315:   */
                    316:   switch((tx=typ(x)))
                    317:   {
                    318:     case t_INT:
                    319:     {
                    320:       long sx=signe(x), sr = (sx<0 && (n&1))? -1: 1;
                    321:       if (n>0) return puissii(x,(GEN)gn,sr);
                    322:       if (!sx) err(talker, "division by zero in gpowgs");
                    323:       if (is_pm1(x)) return (sr < 0)? icopy(x): gun;
                    324:       /* n<0, |x|>1 */
                    325:       y=cgetg(3,t_FRAC); setsigne(gn,1);
                    326:       y[1]=(sr>0)? un: lnegi(gun);
                    327:       y[2]=(long)puissii(x,(GEN)gn,1); /* force denominator > 0 */
                    328:       return y;
                    329:     }
                    330:     case t_INTMOD:
                    331:       y=cgetg(3,tx); copyifstack(x[1],y[1]);
                    332:       y[2]=(long)powmodulo((GEN)(x[2]),(GEN)gn,(GEN)(x[1]));
                    333:       return y;
                    334:     case t_FRAC: case t_FRACN:
                    335:     {
                    336:       long sr = ((n&1) && (signe(x[1])!=signe(x[2])))? -1: 1;
                    337:       if (n<0)
                    338:       {
                    339:         if (!signe((GEN)x[1]))
                    340:           err(talker, "division by zero fraction in gpowgs");
                    341:         setsigne((GEN)gn,1);
                    342:         if (is_pm1((GEN)x[1])) /* +-1/x[2] inverts to an integer */
                    343:           return puissii((GEN)x[2],(GEN)gn,sr);
                    344:         y=cgetg(3,tx);
                    345:         y[1]=(long)puissii((GEN)x[2],(GEN)gn,sr);
                    346:         y[2]=(long)puissii((GEN)x[1],(GEN)gn,1);
                    347:         return y;
                    348:       }
                    349:       else /* n > 0 */
                    350:       {
                    351:         y=cgetg(3,tx);
                    352:         if (!signe((GEN)x[1])) { y[1]=zero; y[2]=un; return y; }
                    353:         y[1]=(long)puissii((GEN)x[1],(GEN)gn,sr);
                    354:         y[2]=(long)puissii((GEN)x[2],(GEN)gn,1);
                    355:         return y;
                    356:       }
                    357:     }
                    358:     case t_POL: case t_POLMOD:
                    359:       return powgi(x,gn);
                    360:     case t_RFRAC: case t_RFRACN:
                    361:     {
                    362:       av=avma; y=cgetg(3,tx); m = labs(n);
                    363:       y[1]=lpuigs((GEN)x[1],m);
                    364:       y[2]=lpuigs((GEN)x[2],m);
                    365:       if (n<0) y=ginv(y);      /* let ginv worry about normalizations */
                    366:       return gerepileupto(av,y);
                    367:     }
                    368:     default:
                    369:       m = labs(n);
                    370:       av=avma; y=NULL; lim=stack_lim(av,1);
                    371:       for (; m>1; m>>=1)
                    372:       {
                    373:         if (m&1) y = y? gmul(y,x): x;
                    374:         x=gsqr(x);
                    375:         if (low_stack(lim, stack_lim(av,1)))
                    376:         {
                    377:           GEN *gptr[2]; gptr[0]=&x; gptr[1]=&y;
                    378:           if(DEBUGMEM>1) err(warnmem,"[3]: gpowgs");
                    379:           gerepilemany(av,gptr,y? 2: 1);
                    380:         }
                    381:       }
                    382:       y = y? gmul(y,x): x;
                    383:       if (n<=0) y=ginv(y);
                    384:       return gerepileupto(av,y);
                    385:   }
                    386: }
                    387:
                    388: GEN
                    389: pow_monome(GEN x, GEN nn)
                    390: {
                    391:   long n,m,i,j,dd,tetpil, av = avma;
                    392:   GEN p1,y;
                    393:   if (is_bigint(nn)) err(talker,"power overflow in pow_monome");
                    394:   n = itos(nn); m = labs(n);
                    395:   j=lgef(x); dd=(j-3)*m+3;
                    396:   p1=cgetg(dd,t_POL); m = labs(n);
                    397:   p1[1] = evalsigne(1) | evallgef(dd) | evalvarn(varn(x));
                    398:   for (i=2; i<dd-1; i++) p1[i]=zero;
                    399:   p1[i]=lpuigs((GEN)x[j-1],m);
                    400:   if (n>0) return p1;
                    401:
                    402:   tetpil=avma; y=cgetg(3,t_RFRAC);
                    403:   y[1]=(long)denom((GEN)p1[i]);
                    404:   y[2]=lmul(p1,(GEN)y[1]); return gerepile(av,tetpil,y);
                    405: }
                    406:
                    407: /* n is assumed to be an integer */
                    408: GEN
                    409: powgi(GEN x, GEN n)
                    410: {
                    411:   long lim,av,i,j,m,tx, sn=signe(n);
                    412:   GEN y, p1;
                    413:
                    414:   if (typ(n) != t_INT) err(talker,"not an integral exponent in powgi");
                    415:   if (!sn) return puiss0(x);
                    416:
                    417:   switch(tx=typ(x))
                    418:   {/* catch some types here, instead of trying gpowgs() first, because of
                    419:     * the simpler call interface to puissii() and powmodulo() -- even though
                    420:     * for integer/rational bases other than 0,+-1 and non-wordsized
                    421:     * exponents the result will be certain to overflow. --GN
                    422:     */
                    423:     case t_INT:
                    424:     {
                    425:       long sx=signe(x), sr = (sx<0 && mod2(n))? -1: 1;
                    426:       if (sn>0) return puissii(x,n,sr);
                    427:       if (!sx) err(talker, "division by zero in powgi");
                    428:       if (is_pm1(x)) return (sr < 0)? icopy(x): gun;
                    429:       /* n<0, |x|>1 */
                    430:       y=cgetg(3,t_FRAC); setsigne(n,1); /* temporarily replace n by abs(n) */
                    431:       y[1]=(sr>0)? un: lnegi(gun);
                    432:       y[2]=(long)puissii(x,n,1);
                    433:       setsigne(n,-1); return y;
                    434:     }
                    435:     case t_INTMOD:
                    436:       y=cgetg(3,tx); copyifstack(x[1],y[1]);
                    437:       y[2]=(long)powmodulo((GEN)x[2],n,(GEN)x[1]);
                    438:       return y;
                    439:     case t_FRAC: case t_FRACN:
                    440:     {
                    441:       long sr = (mod2(n) && (signe(x[1])!=signe(x[2]))) ? -1 : 1;
                    442:       if (sn<0)
                    443:       {
                    444:         if (!signe((GEN)x[1]))
                    445:           err(talker, "division by zero fraction in powgi");
                    446:         setsigne(n,1);
                    447:         if (is_pm1((GEN)x[1])) /* +-1/x[2] inverts to an integer */
                    448:           y=puissii((GEN)x[2],n,sr);
                    449:         else
                    450:         {
                    451:           y=cgetg(3,tx);
                    452:           y[1]=(long)puissii((GEN)x[2],n,sr);
                    453:           y[2]=(long)puissii((GEN)x[1],n,1);
                    454:         }
                    455:         setsigne(n,-1); return y;
                    456:       }
                    457:       else /* n > 0 */
                    458:       {
                    459:         y=cgetg(3,tx);
                    460:         if (!signe((GEN)x[1])) { y[1]=zero; y[2]=un; return y; }
                    461:         y[1]=(long)puissii((GEN)x[1],n,sr);
                    462:         y[2]=(long)puissii((GEN)x[2],n,1);
                    463:         return y;
                    464:       }
                    465:     }
                    466:     case t_POL:
                    467:       if (ismonome(x)) return pow_monome(x,n);
                    468:     default:
                    469:       av=avma; lim=stack_lim(av,1);
                    470:       p1 = n+2; m = *p1;
                    471:       y=x; j=1+bfffo(m); m<<=j; j = BITS_IN_LONG-j;
                    472:       for (i=lgefint(n)-2;;)
                    473:       {
                    474:         for (; j; m<<=1,j--)
                    475:         {
                    476:           y=gsqr(y);
                    477:           if (low_stack(lim, stack_lim(av,1)))
                    478:           {
                    479:             if(DEBUGMEM>1) err(warnmem,"[1]: powgi");
                    480:             y = gerepileupto(av, y);
                    481:           }
                    482:           if (m<0) y=gmul(y,x);
                    483:           if (low_stack(lim, stack_lim(av,1)))
                    484:           {
                    485:             if(DEBUGMEM>1) err(warnmem,"[2]: powgi");
                    486:             y = gerepileupto(av, y);
                    487:           }
                    488:         }
                    489:         if (--i == 0) break;
                    490:         m = *++p1, j = BITS_IN_LONG;
                    491:       }
                    492:       if (sn<0) y = ginv(y);
                    493:       return av==avma? gcopy(y): gerepileupto(av,y);
                    494:   }
                    495: }
                    496:
                    497: /* we suppose n != 0, and valp(x) = 0 */
                    498: static GEN
                    499: ser_pui(GEN x, GEN n, long prec)
                    500: {
                    501:   long av,tetpil,lx,i,j;
                    502:   GEN p1,p2,y,alp;
                    503:
                    504:   if (gvar9(n) > varn(x))
                    505:   {
                    506:     GEN lead = (GEN)x[2];
                    507:     if (gcmp1(lead))
                    508:     {
                    509:       av=avma; alp = gclone(gadd(n,gun)); avma=av;
                    510:       y=cgetg(lx=lg(x),t_SER);
                    511:       y[1] = evalsigne(1) | evalvalp(0) | evalvarn(varn(x));
                    512:       y[2] = un;
                    513:       for (i=3; i<lx; i++)
                    514:       {
                    515:        av=avma; p1=gzero;
                    516:        for (j=1; j<i-1; j++)
                    517:        {
                    518:          p2 = gsubgs(gmulgs(alp,j),i-2);
                    519:          p1 = gadd(p1,gmul(gmul(p2,(GEN)x[j+2]),(GEN)y[i-j]));
                    520:        }
                    521:        tetpil=avma; y[i]=lpile(av,tetpil,gdivgs(p1,i-2));
                    522:       }
                    523:       gunclone(alp); return y;
                    524:     }
                    525:     av=avma; p1=gdiv(x,lead); p1[2] = un; /* in case it's inexact */
                    526:     p1=gpow(p1,n,prec); p2=gpow(lead,n,prec);
                    527:     tetpil=avma; return gerepile(av,tetpil,gmul(p1,p2));
                    528:   }
                    529:   av=avma; y=gmul(n,glog(x,prec)); tetpil=avma;
                    530:   return gerepile(av,tetpil,gexp(y,prec));
                    531: }
                    532:
                    533: GEN
                    534: gpow(GEN x, GEN n, long prec)
                    535: {
                    536:   long av,tetpil,i,lx,tx;
                    537:   GEN y;
                    538:
                    539:   if (typ(n)==t_INT) return powgi(x,n);
                    540:   tx = typ(x);
                    541:   if (is_matvec_t(tx))
                    542:   {
                    543:     lx=lg(x); y=cgetg(lx,tx);
                    544:     for (i=1; i<lx; i++) y[i]=lpui((GEN)x[i],n,prec);
                    545:     return y;
                    546:   }
                    547:   if (tx==t_SER)
                    548:   {
                    549:     if (valp(x))
                    550:       err(talker,"not an integer exponent for non invertible series in gpow");
                    551:     if (lg(x) == 2) return gcopy(x); /* O(1) */
                    552:     return ser_pui(x,n,prec);
                    553:   }
                    554:   av=avma;
                    555:   if (gcmp0(x))
                    556:   {
                    557:     n = greal(n);
                    558:     if (gsigne(n)<=0) err(talker,"zero to a non positive exponent in gpow");
                    559:     i = precision(x); if (!i) return gcopy(x);
                    560:
                    561:     x=ground(gmulsg(gexpo(x),n));
                    562:     if (lgefint(x)<=3)
                    563:     {
                    564:       i = itos(x);
                    565:       if (labs(i) < (long)HIGHEXPOBIT)
                    566:       {
                    567:         avma=av; y=cgetr(3); y[1]=evalexpo(i); y[2]=0;
                    568:         return y;
                    569:       }
                    570:     }
                    571:     err(talker,"underflow or overflow in gpow");
                    572:   }
                    573:   i = (long) precision(n); if (i) prec=i;
                    574:   y=gmul(n,glog(x,prec)); tetpil=avma;
                    575:   return gerepile(av,tetpil,gexp(y,prec));
                    576: }
                    577:
                    578: /********************************************************************/
                    579: /**                                                                **/
                    580: /**                        RACINE CARREE                           **/
                    581: /**                                                                **/
                    582: /********************************************************************/
                    583:
                    584: GEN
                    585: mpsqrt(GEN x)
                    586: {
                    587:   long l,l0,l1,l2,s,eps,n,i,ex,av;
                    588:   double beta;
                    589:   GEN y,p1,p2,p3;
                    590:
                    591:   if (typ(x)!=t_REAL) err(typeer,"mpsqrt");
                    592:   s=signe(x); if (s<0) err(talker,"negative argument in mpsqrt");
                    593:   if (!s)
                    594:   {
                    595:     y = cgetr(3);
                    596:     y[1] = evalexpo(expo(x)>>1);
                    597:     y[2] = 0; return y;
                    598:   }
                    599:   l=lg(x); y=cgetr(l); av=avma;
                    600:
                    601:   p1=cgetr(l+1); affrr(x,p1);
                    602:   ex=expo(x); eps = ex & 1; ex >>= 1;
                    603:   setexpo(p1,eps); setlg(p1,3);
                    604:
                    605:   n=(long)(2+log((double) (l-2))/LOG2);
                    606:   p2=cgetr(l+1); p2[1]=evalexpo(0) | evalsigne(1);
                    607:   beta=sqrt((eps+1) * (2 + p1[2]/C31));
                    608:   p2[2]=(long)((beta-2)*C31);
                    609:   if (!p2[2]) { p2[2]=HIGHBIT; setexpo(p2,1); }
                    610:   for (i=3; i<=l; i++) p2[i]=0;
                    611:   setlg(p2,3);
                    612:
                    613:   p3=cgetr(l+1); l-=2; l1=1; l2=3;
                    614:   for (i=1; i<=n; i++)
                    615:   {
                    616:     l0 = l1<<1;
                    617:     if (l0<=l)
                    618:       { l2 += l1; l1=l0; }
                    619:     else
                    620:       { l2 += l+1-l1; l1=l+1; }
                    621:     setlg(p3,l1+2); setlg(p1,l1+2); setlg(p2,l2);
                    622:     divrrz(p1,p2,p3); addrrz(p2,p3,p2); setexpo(p2,expo(p2)-1);
                    623:   }
                    624:   affrr(p2,y); setexpo(y,expo(y)+ex);
                    625:   avma=av; return y;
                    626: }
                    627:
                    628: static GEN
                    629: padic_sqrt(GEN x)
                    630: {
                    631:   long av = avma, av2,lim,e,r,lpp,lp,pp;
                    632:   GEN y;
                    633:
                    634:   e=valp(x); y=cgetg(5,t_PADIC); copyifstack(x[2],y[2]);
                    635:   if (gcmp0(x))
                    636:   {
                    637:     y[4] = zero; e = (e+1)>>1;
                    638:     y[3] = lpuigs((GEN)x[2],e);
                    639:     y[1] = evalvalp(e) | evalprecp(precp(x));
                    640:     return y;
                    641:   }
                    642:   if (e & 1) err(sqrter6);
                    643:   e>>=1; setvalp(y,e); y[3] = y[2];
                    644:   pp = precp(x);
                    645:   if (egalii(gdeux, (GEN)x[2]))
                    646:   {
                    647:     lp=3; y[4] = un; r = mod8((GEN)x[4]);
                    648:     if ((r!=1 && pp>=2) && (r!=5 || pp!=2)) err(sqrter5);
                    649:     if (pp <= lp) { setprecp(y,1); return y; }
                    650:
                    651:     x = dummycopy(x); setvalp(x,0); setvalp(y,0);
                    652:     av2=avma; lim = stack_lim(av2,2);
                    653:     y[3] = lstoi(8);
                    654:     for(;;)
                    655:     {
                    656:       lpp=lp; lp=(lp<<1)-1;
                    657:       if (lp < pp) y[3] = lshifti((GEN)y[3], lpp-1);
                    658:       else
                    659:         { lp=pp; y[3] = x[3]; }
                    660:       setprecp(y,lp); y = gdiv(gadd(y, gdiv(x,y)), gdeux);
                    661:       if (lp < pp) lp--;
                    662:       if (cmpii((GEN)y[4], (GEN)y[3]) >= 0)
                    663:         y[4] = lsubii((GEN)y[4], (GEN)y[3]);
                    664:
                    665:       if (pp <= lp) break;
                    666:       if (low_stack(lim,stack_lim(av2,2)))
                    667:       {
                    668:         if (DEBUGMEM > 1) err(warnmem,"padic_sqrt");
                    669:         y = gerepileupto(av2,y);
                    670:       }
                    671:     }
                    672:     y = gcopy(y);
                    673:   }
                    674:   else /* p != 2 */
                    675:   {
                    676:     lp=1; y[4] = (long)mpsqrtmod((GEN)x[4],(GEN)x[2]);
                    677:     if (!y[4]) err(sqrter5);
                    678:     if (pp <= lp) { setprecp(y,1); return y; }
                    679:
                    680:     x = dummycopy(x); setvalp(x,0); setvalp(y,0);
                    681:     av2=avma; lim = stack_lim(av2,2);
                    682:     for(;;)
                    683:     {
                    684:       lp<<=1;
                    685:       if (lp < pp) y[3] = lsqri((GEN)y[3]);
                    686:       else
                    687:         { lp=pp; y[3] = x[3]; }
                    688:       setprecp(y,lp); y = gdiv(gadd(y, gdiv(x,y)), gdeux);
                    689:
                    690:       if (pp <= lp) break;
                    691:       if (low_stack(lim,stack_lim(av2,2)))
                    692:       {
                    693:         if (DEBUGMEM > 1) err(warnmem,"padic_sqrt");
                    694:         y = gerepileupto(av2,y);
                    695:       }
                    696:     }
                    697:   }
                    698:   setvalp(y,e); return gerepileupto(av,y);
                    699: }
                    700:
                    701: GEN
                    702: gsqrt(GEN x, long prec)
                    703: {
                    704:   long av,tetpil,e;
                    705:   GEN y,p1,p2;
                    706:
                    707:   switch(typ(x))
                    708:   {
                    709:     case t_REAL:
                    710:       if (signe(x)>=0) return mpsqrt(x);
                    711:       y=cgetg(3,t_COMPLEX); y[1]=zero;
                    712:       setsigne(x,1); y[2]=lmpsqrt(x); setsigne(x,-1);
                    713:       return y;
                    714:
                    715:     case t_INTMOD:
                    716:       y=cgetg(3,t_INTMOD); copyifstack(x[1],y[1]);
                    717:       p1 = mpsqrtmod((GEN)x[2],(GEN)y[1]);
                    718:       if (!p1) err(sqrter5);
                    719:       y[2] = (long)p1; return y;
                    720:
                    721:     case t_COMPLEX:
                    722:       y=cgetg(3,t_COMPLEX); av=avma;
                    723:       if (gcmp0((GEN)x[2]))
                    724:       {
                    725:        long tx=typ(x[1]);
                    726:
                    727:        if ((is_intreal_t(tx) || is_frac_t(tx)) && gsigne((GEN)x[1]) < 0)
                    728:        {
                    729:          y[1]=zero; p1=gneg_i((GEN)x[1]); tetpil=avma;
                    730:          y[2]=lpile(av,tetpil,gsqrt(p1,prec));
                    731:          return y;
                    732:        }
                    733:        y[1]=lsqrt((GEN)x[1],prec);
                    734:        y[2]=zero; return y;
                    735:       }
                    736:
                    737:       p1=gsqr((GEN)x[1]); p2=gsqr((GEN)x[2]);
                    738:       p1=gsqrt(gadd(p1,p2),prec);
                    739:       if (gcmp0(p1))
                    740:       {
                    741:        y[1]=lsqrt(p1,prec);
                    742:        y[2]=lcopy((GEN)y[1]);
                    743:        return y;
                    744:       }
                    745:
                    746:       if (gsigne((GEN)x[1])<0)
                    747:       {
                    748:        p2=gsub(p1,(GEN)x[1]); p1=gmul2n(p2,-1);
                    749:        y[2]=lsqrt(p1,prec); y[1]=ldiv((GEN)x[2],gmul2n((GEN)y[2],1));
                    750:        tetpil=avma;
                    751:         y = (gsigne((GEN)x[2]) > 0)? gcopy(y): gneg(y);
                    752:        return gerepile(av,tetpil,y);
                    753:       }
                    754:
                    755:       p1=gmul2n(gadd(p1,(GEN)x[1]),-1);
                    756:       tetpil=avma; y[1]=lpile(av,tetpil,gsqrt(p1,prec));
                    757:       av=avma; p1=gmul2n((GEN)y[1],1); tetpil=avma;
                    758:       y[2]=lpile(av,tetpil,gdiv((GEN)x[2],p1));
                    759:       return y;
                    760:
                    761:     case t_PADIC:
                    762:       return padic_sqrt(x);
                    763:
                    764:     case t_SER:
                    765:       e=valp(x);
                    766:       if (gcmp0(x)) return zeroser(varn(x), (e+1)>>1);
                    767:       if (e & 1) err(sqrter6);
                    768:       /* trick: ser_pui assumes valp(x) = 0 */
                    769:       y = ser_pui(x,ghalf,prec);
                    770:       y[1] = evalsigne(1) | evalvalp(e>>1) | evalvarn(varn(x));
                    771:       return y;
                    772:   }
                    773:   return transc(gsqrt,x,prec);
                    774: }
                    775:
                    776: void
                    777: gsqrtz(GEN x, GEN y)
                    778: {
                    779:   long av=avma, prec = precision(y);
                    780:
                    781:   if (!prec) err(infprecer,"gsqrtz");
                    782:   gaffect(gsqrt(x,prec),y); avma=av;
                    783: }
                    784:
                    785: /********************************************************************/
                    786: /**                                                                **/
                    787: /**                    FONCTION EXPONENTIELLE-1                    **/
                    788: /**                                                                **/
                    789: /********************************************************************/
                    790: #ifdef LONG_IS_64BIT
                    791: #  define EXMAX 46
                    792: #else
                    793: #  define EXMAX 22
                    794: #endif
                    795:
                    796: GEN
                    797: mpexp1(GEN x)
                    798: {
                    799:   long l,l1,l2,i,n,m,ex,s,av,av2, sx = signe(x);
                    800:   double a,b,alpha,beta, gama = 2.0 /* optimized for SUN3 */;
                    801:                                     /* KB: 3.0 is better for UltraSparc */
                    802:   GEN y,p1,p2,p3,p4,unr;
                    803:
                    804:   if (typ(x)!=t_REAL) err(typeer,"mpexp1");
                    805:   if (!sx)
                    806:   {
                    807:     y=cgetr(3); y[1]=x[1]; y[2]=0; return y;
                    808:   }
                    809:   l=lg(x); y=cgetr(l); av=avma; /* room for result */
                    810:
                    811:   l2 = l+1; ex = expo(x);
                    812:   if (ex > EXMAX) err(talker,"exponent too large in exp");
                    813:   alpha = -1-log(2+x[2]/C31)-ex*LOG2;
                    814:   beta = 5 + bit_accuracy(l)*LOG2;
                    815:   a = sqrt(beta/(gama*LOG2));
                    816:   b = (alpha + 0.5*log(beta*gama/LOG2))/LOG2;
                    817:   if (a>=b)
                    818:   {
                    819:     n=(long)(1+sqrt(beta*gama/LOG2));
                    820:     m=(long)(1+a-b);
                    821:     l2 += m>>TWOPOTBITS_IN_LONG;
                    822:   }
                    823:   else
                    824:   {
                    825:     n=(long)(1+beta/alpha);
                    826:     m=0;
                    827:   }
                    828:   unr=realun(l2);
                    829:   p2=rcopy(unr); setlg(p2,4);
                    830:   p4=cgetr(l2); affrr(x,p4); setsigne(p4,1);
                    831:   if (m) setexpo(p4,ex-m);
                    832:
                    833:   s=0; l1=4; av2 = avma;
                    834:   for (i=n; i>=2; i--)
                    835:   {
                    836:     setlg(p4,l1); p3 = divrs(p4,i);
                    837:     s -= expo(p3); p1 = mulrr(p3,p2); setlg(p1,l1);
                    838:     l1 += s>>TWOPOTBITS_IN_LONG; if (l1>l2) l1=l2;
                    839:     s %= BITS_IN_LONG;
                    840:     setlg(unr,l1); p1 = addrr(unr,p1);
                    841:     setlg(p2,l1); affrr(p1,p2); avma = av2;
                    842:   }
                    843:   setlg(p2,l2); setlg(p4,l2); p2 = mulrr(p4,p2);
                    844:
                    845:   for (i=1; i<=m; i++)
                    846:   {
                    847:     setlg(p2,l2);
                    848:     p2 = mulrr(addsr(2,p2),p2);
                    849:   }
                    850:   if (sx == -1)
                    851:   {
                    852:     setlg(unr,l2); p2 = addrr(unr,p2);
                    853:     setlg(p2,l2); p2 = ginv(p2);
                    854:     p2 = subrr(p2,unr);
                    855:   }
                    856:   affrr(p2,y); avma = av; return y;
                    857: }
                    858: #undef EXMAX
                    859:
                    860: /********************************************************************/
                    861: /**                                                                **/
                    862: /**                   FONCTION EXPONENTIELLE                       **/
                    863: /**                                                                **/
                    864: /********************************************************************/
                    865:
                    866: GEN
                    867: mpexp(GEN x)
                    868: {
                    869:   long av, sx = signe(x);
                    870:   GEN y;
                    871:
                    872:   if (!sx) return addsr(1,x);
                    873:   if (sx<0) setsigne(x,1);
                    874:   av = avma; y = addsr(1, mpexp1(x));
                    875:   if (sx<0) { y = divsr(1,y); setsigne(x,-1); }
                    876:   return gerepileupto(av,y);
                    877: }
                    878:
                    879: static GEN
                    880: paexp(GEN x)
                    881: {
                    882:   long k,av, e = valp(x), pp = precp(x), n = e + pp;
                    883:   GEN y,r,p1;
                    884:
                    885:   if (gcmp0(x)) return gaddgs(x,1);
                    886:   if (e<=0 || (!cmpis((GEN)x[2],2) && e==1))
                    887:     err(talker,"p-adic argument out of range in gexp");
                    888:   av = avma;
                    889:   if (egalii(gdeux,(GEN)x[2]))
                    890:   {
                    891:     n--; e--; k = n/e;
                    892:     if (n%e==0) k--;
                    893:   }
                    894:   else
                    895:   {
                    896:     p1 = subis((GEN)x[2], 1);
                    897:     k = itos(dvmdii(subis(mulis(p1,n), 1), subis(mulis(p1,e), 1), &r));
                    898:     if (!signe(r)) k--;
                    899:   }
                    900:   for (y=gun; k; k--) y = gaddsg(1, gdivgs(gmul(y,x), k));
                    901:   return gerepileupto(av, y);
                    902: }
                    903:
                    904: GEN
                    905: gexp(GEN x, long prec)
                    906: {
                    907:   long av,tetpil,ex;
                    908:   GEN r,y,p1,p2;
                    909:
                    910:   switch(typ(x))
                    911:   {
                    912:     case t_REAL:
                    913:       return mpexp(x);
                    914:
                    915:     case t_COMPLEX:
                    916:       y=cgetg(3,t_COMPLEX); av=avma;
                    917:       r=gexp((GEN)x[1],prec);
                    918:       gsincos((GEN)x[2],&p2,&p1,prec);
                    919:       tetpil=avma;
                    920:       y[1]=lmul(r,p1); y[2]=lmul(r,p2);
                    921:       gerepilemanyvec(av,tetpil,y+1,2);
                    922:       return y;
                    923:
                    924:     case t_PADIC:
                    925:       return paexp(x);
                    926:
                    927:     case t_SER:
                    928:       if (gcmp0(x)) return gaddsg(1,x);
                    929:
                    930:       ex=valp(x); if (ex<0) err(negexper,"gexp");
                    931:       if (ex)
                    932:       {
                    933:        long i,j,ly=lg(x)+ex;
                    934:
                    935:        y=cgetg(ly,t_SER);
                    936:        y[1] = evalsigne(1) | evalvalp(0) | evalvarn(varn(x));
                    937:         y[2] = un;
                    938:        for (i=3; i<ex+2; i++) y[i]=zero;
                    939:        for (   ; i<ly; i++)
                    940:        {
                    941:          av=avma; p1=gzero;
                    942:          for (j=ex; j<i-1; j++)
                    943:            p1=gadd(p1,gmulgs(gmul((GEN)x[j-ex+2],(GEN)y[i-j]),j));
                    944:          tetpil=avma; y[i]=lpile(av,tetpil,gdivgs(p1,i-2));
                    945:        }
                    946:        return y;
                    947:       }
                    948:       av=avma; p1=gcopy(x); p1[2]=zero;
                    949:       p2=gexp(normalize(p1),prec);
                    950:       p1=gexp((GEN)x[2],prec); tetpil=avma;
                    951:       return gerepile(av,tetpil,gmul(p1,p2));
                    952:
                    953:     case t_INTMOD:
                    954:       err(typeer,"gexp");
                    955:   }
                    956:   return transc(gexp,x,prec);
                    957: }
                    958:
                    959: void
                    960: gexpz(GEN x, GEN y)
                    961: {
                    962:   long av=avma, prec = precision(y);
                    963:
                    964:   if (!prec) err(infprecer,"gexpz");
                    965:   gaffect(gexp(x,prec),y); avma=av;
                    966: }
                    967:
                    968: /********************************************************************/
                    969: /**                                                                **/
                    970: /**                      FONCTION LOGARITHME                       **/
                    971: /**                                                                **/
                    972: /********************************************************************/
                    973:
                    974: GEN
                    975: mplog(GEN x)
                    976: {
                    977:   long l,l1,l2,m,m1,n,i,ex,s,sgn,ltop,av;
                    978:   double alpha,beta,a,b;
                    979:   GEN y,p1,p2,p3,p4,p5,unr;
                    980:
                    981:   if (typ(x)!=t_REAL) err(typeer,"mplog");
                    982:   if (signe(x)<=0) err(talker,"non positive argument in mplog");
                    983:   l=lg(x); sgn = cmpsr(1,x); if (!sgn) return realzero(l);
                    984:   y=cgetr(l); ltop=avma;
                    985:
                    986:   l2 = l+1; p2=p1=cgetr(l2); affrr(x,p1);
                    987:   av=avma;
                    988:   if (sgn > 0) p2 = divsr(1,p1); /* x<1 changer x en 1/x */
                    989:   for (m1=1; expo(p2)>0; m1++) p2 = mpsqrt(p2);
                    990:   if (m1 > 1 || sgn > 0) { affrr(p2,p1); avma=av; }
                    991:
                    992:   alpha = 1+p1[2]/C31; if (!alpha) alpha = 0.00000001;
                    993:   l -= 2; alpha = -log(alpha);
                    994:   beta = (BITS_IN_LONG/2)*l*LOG2;
                    995:   a = alpha/LOG2;
                    996:   b = sqrt((BITS_IN_LONG/2)*l/3.0);
                    997:   if (a<=b)
                    998:   {
                    999:     n=(long)(1+sqrt((BITS_IN_LONG/2)*3.0*l));
                   1000:     m=(long)(1+b-a);
                   1001:     l2 += m>>TWOPOTBITS_IN_LONG;
                   1002:     p4=cgetr(l2); affrr(p1,p4);
                   1003:     p1 = p4; av=avma;
                   1004:     for (i=1; i<=m; i++)  p1 = mpsqrt(p1);
                   1005:     affrr(p1,p4); avma=av;
                   1006:   }
                   1007:   else
                   1008:   {
                   1009:     n=(long)(1+beta/alpha);
                   1010:     m=0; p4 = p1;
                   1011:   }
                   1012:   unr=realun(l2);
                   1013:   p2=cgetr(l2); p3=cgetr(l2); av=avma;
                   1014:
                   1015:   /* affrr needed here instead of setlg since prec may DECREASE */
                   1016:   p1 = cgetr(l2); affrr(subrr(p4,unr), p1);
                   1017:
                   1018:   p5 = addrr(p4,unr); setlg(p5,l2);
                   1019:   affrr(divrr(p1,p5), p2);
                   1020:   affrr(mulrr(p2,p2), p3);
                   1021:   affrr(divrs(unr,2*n+1), p4); setlg(p4,4); avma=av;
                   1022:
                   1023:   s=0; ex=expo(p3); l1 = 4;
                   1024:   for (i=n; i>=1; i--)
                   1025:   {
                   1026:     setlg(p3,l1); p5 = mulrr(p4,p3);
                   1027:     setlg(unr,l1); p1 = divrs(unr,2*i-1);
                   1028:     s -= ex;
                   1029:     l1 += s>>TWOPOTBITS_IN_LONG; if (l1>l2) l1=l2;
                   1030:     s %= BITS_IN_LONG;
                   1031:     setlg(p1,l1); setlg(p4,l1); setlg(p5,l1);
                   1032:     p1 = addrr(p1,p5); affrr(p1,p4); avma=av;
                   1033:   }
                   1034:   setlg(p4,l2); affrr(mulrr(p2,p4), y);
                   1035:   setexpo(y, expo(y)+m+m1);
                   1036:   if (sgn > 0) setsigne(y, -1);
                   1037:   avma=ltop; return y;
                   1038: }
                   1039:
                   1040: GEN
                   1041: teich(GEN x)
                   1042: {
                   1043:   GEN aux,y,z,p1;
                   1044:   long av,n,k;
                   1045:
                   1046:   if (typ(x)!=t_PADIC) err(talker,"not a p-adic argument in teichmuller");
                   1047:   if (!signe(x[4])) return gcopy(x);
                   1048:   y=cgetp(x); z=(GEN)x[4];
                   1049:   if (!cmpis((GEN)x[2],2))
                   1050:   {
                   1051:     n = mod4(z);
                   1052:     if (n & 2)
                   1053:       addsiz(-1,(GEN)x[3],(GEN)y[4]);
                   1054:     else
                   1055:       affsi(1,(GEN)y[4]);
                   1056:     return y;
                   1057:   }
                   1058:   av = avma; p1 = addsi(-1,(GEN)x[2]);
                   1059:   aux = divii(addsi(-1,(GEN)x[3]),p1); n = precp(x);
                   1060:   for (k=1; k<n; k<<=1)
                   1061:     z=modii(mulii(z,addsi(1,mulii(aux,addsi(-1,powmodulo(z,p1,(GEN)x[3]))))),
                   1062:             (GEN)x[3]);
                   1063:   affii(z,(GEN)y[4]); avma=av; return y;
                   1064: }
                   1065:
                   1066: static GEN
                   1067: palogaux(GEN x)
                   1068: {
                   1069:   long av1=avma,tetpil,k,e,pp;
                   1070:   GEN y,s,y2;
                   1071:
                   1072:   if (egalii(gun,(GEN)x[4]))
                   1073:   {
                   1074:     y=gaddgs(x,-1);
                   1075:     if (egalii(gdeux,(GEN)x[2]))
                   1076:     {
                   1077:       setvalp(y,valp(y)-1);
                   1078:       if (!gcmp1((GEN)y[3])) y[3]=lshifti((GEN)y[3],-1);
                   1079:     }
                   1080:     tetpil=avma; return gerepile(av1,tetpil,gcopy(y));
                   1081:   }
                   1082:   y=gdiv(gaddgs(x,-1),gaddgs(x,1)); e=valp(y); pp=e+precp(y);
                   1083:   if (egalii(gdeux,(GEN)x[2])) pp--;
                   1084:   else
                   1085:   {
                   1086:     long av=avma;
                   1087:     GEN p1;
                   1088:
                   1089:     for (p1=stoi(e); cmpsi(pp,p1)>0; pp++)
                   1090:       p1 = mulii(p1,(GEN)x[2]);
                   1091:     avma=av; pp-=2;
                   1092:   }
                   1093:   k=pp/e; if (!odd(k)) k--;
                   1094:   y2=gsqr(y); s=gdivgs(gun,k);
                   1095:   while (k>=3)
                   1096:   {
                   1097:     k-=2; s=gadd(gmul(y2,s),gdivgs(gun,k));
                   1098:   }
                   1099:   tetpil=avma; return gerepile(av1,tetpil,gmul(s,y));
                   1100: }
                   1101:
                   1102: GEN
                   1103: palog(GEN x)
                   1104: {
                   1105:   long av=avma,tetpil;
                   1106:   GEN p1,y;
                   1107:
                   1108:   if (!signe(x[4])) err(talker,"zero argument in palog");
                   1109:   if (cmpis((GEN)x[2],2))
                   1110:   {
                   1111:     y=cgetp(x); p1=gsubgs((GEN)x[2],1);
                   1112:     affii(powmodulo((GEN)x[4],p1,(GEN)x[3]),(GEN)y[4]);
                   1113:     y=gmulgs(palogaux(y),2); tetpil=avma;
                   1114:     return gerepile(av,tetpil,gdiv(y,p1));
                   1115:   }
                   1116:   y=gsqr(x); setvalp(y,0); tetpil=avma;
                   1117:   return gerepile(av,tetpil,palogaux(y));
                   1118: }
                   1119:
                   1120: GEN
                   1121: log0(GEN x, long flag,long prec)
                   1122: {
                   1123:   switch(flag)
                   1124:   {
                   1125:     case 0: return glog(x,prec);
                   1126:     case 1: return glogagm(x,prec);
                   1127:     default: err(flagerr,"log");
                   1128:   }
                   1129:   return NULL; /* not reached */
                   1130: }
                   1131:
                   1132: GEN
                   1133: glog(GEN x, long prec)
                   1134: {
                   1135:   long av,tetpil;
                   1136:   GEN y,p1,p2;
                   1137:
                   1138:   switch(typ(x))
                   1139:   {
                   1140:     case t_REAL:
                   1141:       if (signe(x)>=0) return mplog(x);
                   1142:       y=cgetg(3,t_COMPLEX); y[2]=lmppi(lg(x));
                   1143:       setsigne(x,1); y[1]=lmplog(x);
                   1144:       setsigne(x,-1); return y;
                   1145:
                   1146:     case t_COMPLEX:
                   1147:       y=cgetg(3,t_COMPLEX); y[2]=larg(x,prec);
                   1148:       av=avma; p1=glog(gnorm(x),prec); tetpil=avma;
                   1149:       y[1]=lpile(av,tetpil,gmul2n(p1,-1));
                   1150:       return y;
                   1151:
                   1152:     case t_PADIC:
                   1153:       return palog(x);
                   1154:
                   1155:     case t_SER:
                   1156:       av=avma; if (valp(x)) err(negexper,"glog");
                   1157:       p1=gdiv(derivser(x),x);
                   1158:       tetpil=avma; p1=integ(p1,varn(x));
                   1159:       if (gcmp1((GEN)x[2])) return gerepile(av,tetpil,p1);
                   1160:
                   1161:       p2=glog((GEN)x[2],prec); tetpil=avma;
                   1162:       return gerepile(av,tetpil,gadd(p1,p2));
                   1163:
                   1164:     case t_INTMOD:
                   1165:       err(typeer,"glog");
                   1166:   }
                   1167:   return transc(glog,x,prec);
                   1168: }
                   1169:
                   1170: void
                   1171: glogz(GEN x, GEN y)
                   1172: {
                   1173:   long av=avma, prec = precision(y);
                   1174:
                   1175:   if (!prec) err(infprecer,"glogz");
                   1176:   gaffect(glog(x,prec),y); avma=av;
                   1177: }
                   1178:
                   1179: /********************************************************************/
                   1180: /**                                                                **/
                   1181: /**                      FONCTION SINCOS-1                         **/
                   1182: /**                                                                **/
                   1183: /********************************************************************/
                   1184:
                   1185: static GEN
                   1186: mpsc1(GEN x, long *ptmod8)
                   1187: {
                   1188:   const long mmax = 23169;
                   1189:  /* on a 64-bit machine with true 128 bit/64 bit division, one could
                   1190:   * take mmax=1518500248; on the alpha it does not seem worthwhile
                   1191:   */
                   1192:   long l,l0,l1,l2,l4,ee,i,n,m,s,t,av;
                   1193:   double alpha,beta,a,b,c,d;
                   1194:   GEN y,p1,p2,p3,p4,pitemp;
                   1195:
                   1196:   if (typ(x)!=t_REAL) err(typeer,"mpsc1");
                   1197:   if (!signe(x))
                   1198:   {
                   1199:     y=cgetr(3);
                   1200:     y[1] = evalexpo((expo(x)<<1) - 1);
                   1201:     y[2] = 0; *ptmod8=0; return y;
                   1202:   }
                   1203:   l=lg(x); y=cgetr(l); av=avma;
                   1204:
                   1205:   l++; pitemp = mppi(l+1); setexpo(pitemp,-1);
                   1206:   p1 = addrr(x,pitemp); setexpo(pitemp,0);
                   1207:   if (expo(p1) >= bit_accuracy(min(l,lg(p1))) + 3)
                   1208:     err(talker,"loss of precision in mpsc1");
                   1209:   p3 = divrr(p1,pitemp); p2 = mpent(p3);
                   1210:   if (signe(p2)) x = subrr(x, mulir(p2,pitemp));
                   1211:   p1 = cgetr(l+1); affrr(x, p1);
                   1212:
                   1213:   *ptmod8 = (signe(p1) < 0)? 4: 0;
                   1214:   if (signe(p2))
                   1215:   {
                   1216:     long mod4 = mod4(p2);
                   1217:     if (signe(p2) < 0 && mod4) mod4 = 4-mod4;
                   1218:     *ptmod8 += mod4;
                   1219:   }
                   1220:   if (gcmp0(p1)) alpha=1000000.0;
                   1221:   else
                   1222:   {
                   1223:     m=expo(p1); alpha=(m<-1023)? -1-m*LOG2: -1-log(fabs(rtodbl(p1)));
                   1224:   }
                   1225:   beta = 5 + bit_accuracy(l)*LOG2;
                   1226:   a=0.5/LOG2; b=0.5*a;
                   1227:   c = a+sqrt((beta+b)/LOG2);
                   1228:   d = ((beta/c)-alpha-log(c))/LOG2;
                   1229:   if (d>=0)
                   1230:   {
                   1231:     m=(long)(1+d);
                   1232:     n=(long)((1+c)/2.0);
                   1233:     setexpo(p1,expo(p1)-m);
                   1234:   }
                   1235:   else { m=0; n=(long)((1+beta/alpha)/2.0); }
                   1236:   l2=l+1+(m>>TWOPOTBITS_IN_LONG);
                   1237:   p2=realun(l2); setlg(p2,4);
                   1238:   p4=cgetr(l2); av = avma;
                   1239:   affrr(gsqr(p1),p4); setlg(p4,4);
                   1240:
                   1241:   if (n>mmax)
                   1242:     p3 = divrs(divrs(p4,2*n+2),2*n+1);
                   1243:   else
                   1244:     p3 = divrs(p4, (2*n+2)*(2*n+1));
                   1245:   ee = -expo(p3); s=0;
                   1246:   l4 = l1 = 3 + (ee>>TWOPOTBITS_IN_LONG);
                   1247:   if (l4<=l2) { setlg(p2,l4); setlg(p4,l4); }
                   1248:   for (i=n; i>mmax; i--)
                   1249:   {
                   1250:     p3 = divrs(divrs(p4,2*i),2*i-1); s -= expo(p3);
                   1251:     t=s&(BITS_IN_LONG-1); l0=(s>>TWOPOTBITS_IN_LONG);
                   1252:     if (t) l0++;
                   1253:     l1 += l0; if (l1>l2) { l0 += l2-l1; l1=l2; }
                   1254:     l4 += l0;
                   1255:     p3 = mulrr(p3,p2);
                   1256:     if (l4<=l2) { setlg(p2,l4); setlg(p4,l4); }
                   1257:     subsrz(1,p3,p2); avma=av;
                   1258:   }
                   1259:   for (  ; i>=2; i--)
                   1260:   {
                   1261:     p3 = divrs(p4, 2*i*(2*i-1)); s -= expo(p3);
                   1262:     t=s&(BITS_IN_LONG-1); l0=(s>>TWOPOTBITS_IN_LONG);
                   1263:     if (t) l0++;
                   1264:     l1 += l0; if (l1>l2) { l0 += l2-l1; l1=l2; }
                   1265:     l4 += l0;
                   1266:     p3 = mulrr(p3,p2);
                   1267:     if (l4<=l2) { setlg(p2,l4); setlg(p4,l4); }
                   1268:     subsrz(1,p3,p2); avma=av;
                   1269:   }
                   1270:   if (l4<=l2) { setlg(p2,l4); setlg(p4,l4); }
                   1271:   setexpo(p4,expo(p4)-1); setsigne(p4, -signe(p4));
                   1272:   p2 = mulrr(p4,p2);
                   1273:   for (i=1; i<=m; i++)
                   1274:   {
                   1275:     p2 = mulrr(p2,addsr(2,p2)); setexpo(p2,expo(p2)+1);
                   1276:   }
                   1277:   affrr(p2,y); avma=av; return y;
                   1278: }
                   1279:
                   1280: /********************************************************************/
                   1281: /**                                                                **/
                   1282: /**                      FONCTION sqrt(-x*(x+2))                   **/
                   1283: /**                                                                **/
                   1284: /********************************************************************/
                   1285:
                   1286: static GEN
                   1287: mpaut(GEN x)
                   1288: {
                   1289:   long av = avma;
                   1290:   GEN p1;
                   1291:
                   1292:   cgetr(2*lg(x)+3); /* bound for 2*lg(p1)+1 */
                   1293:   p1=mulrr(x,addsr(2,x)); setsigne(p1,-signe(p1));
                   1294:   avma = av; return mpsqrt(p1); /* safe ! */
                   1295: }
                   1296:
                   1297: /********************************************************************/
                   1298: /**                                                                **/
                   1299: /**                       FONCTION COSINUS                         **/
                   1300: /**                                                                **/
                   1301: /********************************************************************/
                   1302:
                   1303: static GEN
                   1304: mpcos(GEN x)
                   1305: {
                   1306:   long mod8,av,tetpil;
                   1307:   GEN y,p1;
                   1308:
                   1309:   if (typ(x)!=t_REAL) err(typeer,"mpcos");
                   1310:   if (!signe(x)) return addsr(1,x);
                   1311:
                   1312:   av=avma; p1=mpsc1(x,&mod8); tetpil=avma;
                   1313:   switch(mod8)
                   1314:   {
                   1315:     case 0: case 4:
                   1316:       y=addsr(1,p1); break;
                   1317:     case 1: case 7:
                   1318:       y=mpaut(p1); setsigne(y,-signe(y)); break;
                   1319:     case 2: case 6:
                   1320:       y=subsr(-1,p1); break;
                   1321:     case 3: case 5:
                   1322:       y=mpaut(p1); break;
                   1323:     default:;
                   1324:   }
                   1325:   return gerepile(av,tetpil,y);
                   1326: }
                   1327:
                   1328: GEN
                   1329: gcos(GEN x, long prec)
                   1330: {
                   1331:   long av,tetpil;
                   1332:   GEN r,u,v,y,p1,p2;
                   1333:
                   1334:   switch(typ(x))
                   1335:   {
                   1336:     case t_REAL:
                   1337:       return mpcos(x);
                   1338:
                   1339:     case t_COMPLEX:
                   1340:       y=cgetg(3,t_COMPLEX); av=avma;
                   1341:       r=gexp((GEN)x[2],prec); p1=ginv(r);
                   1342:       p2=gmul2n(mpadd(p1,r),-1);
                   1343:       p1=mpsub(p2,r);
                   1344:       gsincos((GEN)x[1],&u,&v,prec);
                   1345:       tetpil=avma;
                   1346:       y[1]=lmul(p2,v); y[2]=lmul(p1,u);
                   1347:       gerepilemanyvec(av,tetpil,y+1,2);
                   1348:       return y;
                   1349:
                   1350:     case t_SER:
                   1351:       if (gcmp0(x)) return gaddsg(1,x);
                   1352:       if (valp(x)<0) err(negexper,"gcos");
                   1353:
                   1354:       av=avma; gsincos(x,&u,&v,prec); tetpil=avma;
                   1355:       return gerepile(av,tetpil,gcopy(v));
                   1356:
                   1357:     case t_INTMOD: case t_PADIC:
                   1358:       err(typeer,"gcos");
                   1359:   }
                   1360:   return transc(gcos,x,prec);
                   1361: }
                   1362:
                   1363: void
                   1364: gcosz(GEN x, GEN y)
                   1365: {
                   1366:   long av = avma, prec = precision(y);
                   1367:
                   1368:   if (!prec) err(infprecer,"gcosz");
                   1369:   gaffect(gcos(x,prec),y); avma=av;
                   1370: }
                   1371:
                   1372: /********************************************************************/
                   1373: /**                                                                **/
                   1374: /**                       FONCTION SINUS                           **/
                   1375: /**                                                                **/
                   1376: /********************************************************************/
                   1377:
                   1378: GEN
                   1379: mpsin(GEN x)
                   1380: {
                   1381:   long mod8,av,tetpil;
                   1382:   GEN y,p1;
                   1383:
                   1384:   if (typ(x)!=t_REAL) err(typeer,"mpsin");
                   1385:   if (!signe(x))
                   1386:   {
                   1387:     y=cgetr(3); y[1]=x[1]; y[2]=0;
                   1388:     return y;
                   1389:   }
                   1390:
                   1391:   av=avma; p1=mpsc1(x,&mod8); tetpil=avma;
                   1392:   switch(mod8)
                   1393:   {
                   1394:     case 0: case 6:
                   1395:       y=mpaut(p1); break;
                   1396:     case 1: case 5:
                   1397:       y=addsr(1,p1); break;
                   1398:     case 2: case 4:
                   1399:       y=mpaut(p1); setsigne(y,-signe(y)); break;
                   1400:     case 3: case 7:
                   1401:       y=subsr(-1,p1); break;
                   1402:     default:;
                   1403:   }
                   1404:   return gerepile(av,tetpil,y);
                   1405: }
                   1406:
                   1407: GEN
                   1408: gsin(GEN x, long prec)
                   1409: {
                   1410:   long av,tetpil;
                   1411:   GEN r,u,v,y,p1,p2;
                   1412:
                   1413:   switch(typ(x))
                   1414:   {
                   1415:     case t_REAL:
                   1416:       return mpsin(x);
                   1417:
                   1418:     case t_COMPLEX:
                   1419:       y=cgetg(3,t_COMPLEX); av=avma;
                   1420:       r=gexp((GEN)x[2],prec); p1=ginv(r);
                   1421:       p2=gmul2n(mpadd(p1,r),-1);
                   1422:       p1=mpsub(p2,p1);
                   1423:       gsincos((GEN)x[1],&u,&v,prec);
                   1424:       tetpil=avma;
                   1425:       y[1]=lmul(p2,u); y[2]=lmul(p1,v);
                   1426:       gerepilemanyvec(av,tetpil,y+1,2);
                   1427:       return y;
                   1428:
                   1429:     case t_SER:
                   1430:       if (gcmp0(x)) return gcopy(x);
                   1431:       if (valp(x)<0) err(negexper,"gsin");
                   1432:
                   1433:       av=avma; gsincos(x,&u,&v,prec); tetpil=avma;
                   1434:       return gerepile(av,tetpil,gcopy(u));
                   1435:
                   1436:     case t_INTMOD: case t_PADIC:
                   1437:       err(typeer,"gsin");
                   1438:   }
                   1439:   return transc(gsin,x,prec);
                   1440: }
                   1441:
                   1442: void
                   1443: gsinz(GEN x, GEN y)
                   1444: {
                   1445:   long av=avma, prec = precision(y);
                   1446:
                   1447:   if (!prec) err(infprecer,"gsinz");
                   1448:   gaffect(gsin(x,prec),y); avma=av;
                   1449: }
                   1450:
                   1451: /********************************************************************/
                   1452: /**                                                                **/
                   1453: /**                    PROCEDURE SINUS,COSINUS                     **/
                   1454: /**                                                                **/
                   1455: /********************************************************************/
                   1456:
                   1457: void
                   1458: mpsincos(GEN x, GEN *s, GEN *c)
                   1459: {
                   1460:   long av,tetpil,mod8;
                   1461:   GEN p1, *gptr[2];
                   1462:
                   1463:   if (typ(x)!=t_REAL) err(typeer,"mpsincos");
                   1464:   if (!signe(x))
                   1465:   {
                   1466:     p1=cgetr(3); *s=p1; p1[1]=x[1];
                   1467:     p1[2]=0; *c=addsr(1,x); return;
                   1468:   }
                   1469:
                   1470:   av=avma; p1=mpsc1(x,&mod8); tetpil=avma;
                   1471:   switch(mod8)
                   1472:   {
                   1473:     case 0: *c=addsr( 1,p1); *s=mpaut(p1); break;
                   1474:     case 1: *s=addsr( 1,p1); *c=mpaut(p1); setsigne(*c,-signe(*c)); break;
                   1475:     case 2: *c=subsr(-1,p1); *s=mpaut(p1); setsigne(*s,-signe(*s)); break;
                   1476:     case 3: *s=subsr(-1,p1); *c=mpaut(p1); break;
                   1477:     case 4: *c=addsr( 1,p1); *s=mpaut(p1); setsigne(*s,-signe(*s)); break;
                   1478:     case 5: *s=addsr( 1,p1); *c=mpaut(p1); break;
                   1479:     case 6: *c=subsr(-1,p1); *s=mpaut(p1); break;
                   1480:     case 7: *s=subsr(-1,p1); *c=mpaut(p1); setsigne(*c,-signe(*c)); break;
                   1481:   }
                   1482:   gptr[0]=s; gptr[1]=c;
                   1483:   gerepilemanysp(av,tetpil,gptr,2);
                   1484: }
                   1485:
                   1486: void
                   1487: gsincos(GEN x, GEN *s, GEN *c, long prec)
                   1488: {
                   1489:   long av,tetpil,ii,i,j,ex,ex2,lx,ly;
                   1490:   GEN r,u,v,u1,v1,p1,p2,p3,p4,ps,pc;
                   1491:   GEN *gptr[4];
                   1492:
                   1493:   switch(typ(x))
                   1494:   {
                   1495:     case t_INT: case t_FRAC: case t_FRACN:
                   1496:       av=avma; p1=cgetr(prec); gaffect(x,p1); tetpil=avma;
                   1497:       mpsincos(p1,s,c); gptr[0]=s; gptr[1]=c;
                   1498:       gerepilemanysp(av,tetpil,gptr,2);
                   1499:       return;
                   1500:
                   1501:     case t_REAL:
                   1502:       mpsincos(x,s,c); return;
                   1503:
                   1504:     case t_COMPLEX:
                   1505:       ps=cgetg(3,t_COMPLEX); pc=cgetg(3,t_COMPLEX);
                   1506:       *s=ps; *c=pc; av=avma;
                   1507:       r=gexp((GEN)x[2],prec); p1=ginv(r);
                   1508:       p2=gmul2n(mpadd(p1,r),-1);
                   1509:       p1=mpsub(p2,p1); r=mpsub(p2,r);
                   1510:       gsincos((GEN)x[1],&u,&v,prec);
                   1511:       tetpil=avma;
                   1512:       p1=gmul(p2,u); p2=gmul(p1,v);
                   1513:       p3=gmul(p2,v); p4=gmul(r,u);
                   1514:       gptr[0]=&p1; gptr[1]=&p2; gptr[2]=&p3; gptr[3]=&p4;
                   1515:       gerepilemanysp(av,tetpil,gptr,4);
                   1516:       ps[1]=(long)p1; ps[2]=(long)p2; pc[1]=(long)p3; pc[2]=(long)p4;
                   1517:       return;
                   1518:
                   1519:     case t_SER:
                   1520:       if (gcmp0(x)) { *c=gaddsg(1,x); *s=gcopy(x); return; }
                   1521:
                   1522:       ex=valp(x); lx=lg(x); ex2=2*ex+2;
                   1523:       if (ex < 0) err(talker,"non zero exponent in gsincos");
                   1524:       if (ex2 > lx)
                   1525:       {
                   1526:         *s=gcopy(x); av=avma; p1=gdivgs(gsqr(x),2);
                   1527:         tetpil=avma; *c=gerepile(av,tetpil,gsubsg(1,p1));
                   1528:        return;
                   1529:       }
                   1530:       if (!ex)
                   1531:       {
                   1532:         av=avma; p1=gcopy(x); p1[2]=zero;
                   1533:         gsincos(normalize(p1),&u,&v,prec);
                   1534:         gsincos((GEN)x[2],&u1,&v1,prec);
                   1535:         p1=gmul(v1,v); p2=gmul(u1,u); p3=gmul(v1,u);
                   1536:         p4=gmul(u1,v); tetpil=avma;
                   1537:         *c=gsub(p1,p2); *s=gadd(p3,p4);
                   1538:        gptr[0]=s; gptr[1]=c;
                   1539:        gerepilemanysp(av,tetpil,gptr,2);
                   1540:        return;
                   1541:       }
                   1542:
                   1543:       ly=lx+2*ex;
                   1544:       pc=cgetg(ly,t_SER); *c=pc;
                   1545:       ps=cgetg(lx,t_SER); *s=ps;
                   1546:       pc[1] = evalsigne(1) | evalvalp(0) | evalvarn(varn(x));
                   1547:       pc[2]=un; ps[1]=x[1];
                   1548:       for (i=2; i<ex+2; i++) ps[i]=lcopy((GEN)x[i]);
                   1549:       for (i=3; i<ex2; i++) pc[i]=zero;
                   1550:       for (i=ex2; i<ly; i++)
                   1551:       {
                   1552:        ii=i-ex; av=avma; p1=gzero;
                   1553:        for (j=ex; j<ii-1; j++)
                   1554:          p1=gadd(p1,gmulgs(gmul((GEN)x[j-ex+2],(GEN)ps[ii-j]),j));
                   1555:        tetpil=avma;
                   1556:        pc[i]=lpile(av,tetpil,gdivgs(p1,2-i));
                   1557:        if (ii<lx)
                   1558:        {
                   1559:          av=avma; p1=gzero;
                   1560:          for (j=ex; j<=i-ex2; j++)
                   1561:            p1=gadd(p1,gmulgs(gmul((GEN)x[j-ex+2],(GEN)pc[i-j]),j));
                   1562:          p1=gdivgs(p1,i-2); tetpil=avma;
                   1563:          ps[i-ex]=lpile(av,tetpil,gadd(p1,(GEN)x[i-ex]));
                   1564:        }
                   1565:       }
                   1566:       return;
                   1567:   }
                   1568:   err(typeer,"gsincos");
                   1569: }
                   1570:
                   1571: /********************************************************************/
                   1572: /**                                                                **/
                   1573: /**                FONCTIONS TANGENTE ET COTANGENTE                **/
                   1574: /**                                                                **/
                   1575: /********************************************************************/
                   1576:
                   1577: static GEN
                   1578: mptan(GEN x)
                   1579: {
                   1580:   long av=avma,tetpil;
                   1581:   GEN s,c;
                   1582:
                   1583:   mpsincos(x,&s,&c); tetpil=avma;
                   1584:   return gerepile(av,tetpil,divrr(s,c));
                   1585: }
                   1586:
                   1587: GEN
                   1588: gtan(GEN x, long prec)
                   1589: {
                   1590:   long av,tetpil;
                   1591:   GEN s,c;
                   1592:
                   1593:   switch(typ(x))
                   1594:   {
                   1595:     case t_REAL:
                   1596:       return mptan(x);
                   1597:
                   1598:     case t_SER:
                   1599:       if (gcmp0(x)) return gcopy(x);
                   1600:       if (valp(x)<0) err(negexper,"gtan"); /* fall through */
                   1601:     case t_COMPLEX:
                   1602:       av=avma; gsincos(x,&s,&c,prec); tetpil=avma;
                   1603:       return gerepile(av,tetpil,gdiv(s,c));
                   1604:
                   1605:     case t_INTMOD: case t_PADIC:
                   1606:       err(typeer,"gtan");
                   1607:   }
                   1608:   return transc(gtan,x,prec);
                   1609: }
                   1610:
                   1611: void
                   1612: gtanz(GEN x, GEN y)
                   1613: {
                   1614:   long av=avma, prec = precision(y);
                   1615:
                   1616:   if (!prec) err(infprecer,"gtanz");
                   1617:   gaffect(gtan(x,prec),y); avma=av;
                   1618: }
                   1619:
                   1620: static GEN
                   1621: mpcotan(GEN x)
                   1622: {
                   1623:   long av=avma,tetpil;
                   1624:   GEN s,c;
                   1625:
                   1626:   mpsincos(x,&s,&c); tetpil=avma;
                   1627:   return gerepile(av,tetpil,divrr(c,s));
                   1628: }
                   1629:
                   1630: GEN
                   1631: gcotan(GEN x, long prec)
                   1632: {
                   1633:   long av,tetpil;
                   1634:   GEN s,c;
                   1635:
                   1636:   switch(typ(x))
                   1637:   {
                   1638:     case t_REAL:
                   1639:       return mpcotan(x);
                   1640:
                   1641:     case t_SER: err(negexper,"gcotan"); /* fall through */
                   1642:     case t_COMPLEX:
                   1643:       av=avma; gsincos(x,&s,&c,prec); tetpil=avma;
                   1644:       return gerepile(av,tetpil,gdiv(c,s));
                   1645:
                   1646:     case t_INTMOD: case t_PADIC:
                   1647:       err(typeer,"gcotan");
                   1648:   }
                   1649:   return transc(gcotan,x,prec);
                   1650: }
                   1651:
                   1652: void
                   1653: gcotanz(GEN x, GEN y)
                   1654: {
                   1655:   long av=avma, prec = precision(y);
                   1656:
                   1657:   if (!prec) err(infprecer,"gcotanz");
                   1658:   gaffect(gcotan(x,prec),y); avma=av;
                   1659: }

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