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

Annotation of OpenXM_contrib/pari-2.2/src/kernel/none/level1.h, Revision 1.2

1.2     ! noro        1: /* $Id: level1.h,v 1.18 2002/06/08 13:07:03 karim Exp $
1.1       noro        2:
                      3: Copyright (C) 2000  The PARI group.
                      4:
                      5: This file is part of the PARI/GP package.
                      6:
                      7: PARI/GP is free software; you can redistribute it and/or modify it under the
                      8: terms of the GNU General Public License as published by the Free Software
                      9: Foundation. It is distributed in the hope that it will be useful, but WITHOUT
                     10: ANY WARRANTY WHATSOEVER.
                     11:
                     12: Check the License for details. You should have received a copy of it, along
                     13: with the package; see the file 'COPYING'. If not, write to the Free Software
                     14: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
                     15:
                     16: /* This file defines some "level 1" kernel functions                 */
                     17: /* These functions can be inline, with gcc                           */
                     18: /* If not gcc, they are defined externally with "level1.c"           */
                     19:
                     20: /* level1.c includes this file and never needs to be changed         */
                     21: /* The following seven lines are necessary for level0.c and level1.c */
                     22: #ifdef LEVEL1
                     23: #  undef  INLINE
                     24: #  define INLINE
                     25: #endif
                     26: #ifdef LEVEL0
                     27: #  undef  INLINE
                     28: #endif
                     29:
                     30: #ifndef INLINE
                     31: void   addsii(long x, GEN y, GEN z);
                     32: long   addssmod(long a, long b, long p);
                     33: void   addssz(long x, long y, GEN z);
                     34: void   affii(GEN x, GEN y);
                     35: void   affsi(long s, GEN x);
1.2     ! noro       36: void   affui(long s, GEN x);
1.1       noro       37: void   affsr(long s, GEN x);
                     38: GEN    cgetg(long x, long y);
                     39: GEN    cgeti(long x);
                     40: GEN    cgetr(long x);
                     41: int    cmpir(GEN x, GEN y);
                     42: int    cmpsr(long x, GEN y);
                     43: int    divise(GEN x, GEN y);
                     44: long   divisii(GEN x, long y, GEN z);
                     45: void   divisz(GEN x, long y, GEN z);
                     46: void   divrrz(GEN x, GEN y, GEN z);
                     47: void   divsiz(long x, GEN y, GEN z);
                     48: GEN    divss(long x, long y);
                     49: long   divssmod(long a, long b, long p);
                     50: void   divssz(long x, long y, GEN z);
                     51: void   dvmdiiz(GEN x, GEN y, GEN z, GEN t);
                     52: GEN    dvmdis(GEN x, long y, GEN *z);
                     53: void   dvmdisz(GEN x, long y, GEN z, GEN t);
                     54: GEN    dvmdsi(long x, GEN y, GEN *z);
                     55: void   dvmdsiz(long x, GEN y, GEN z, GEN t);
                     56: GEN    dvmdss(long x, long y, GEN *z);
                     57: void   dvmdssz(long x, long y, GEN z, GEN t);
                     58: long   evallg(long x);
                     59: long   evallgef(long x);
                     60: long   evalvalp(long x);
                     61: long   evalexpo(long x);
                     62: long   expi(GEN x);
                     63: double gtodouble(GEN x);
                     64: GEN    icopy(GEN x);
                     65: GEN    icopy_av(GEN x, GEN y);
1.2     ! noro       66: GEN    itor(GEN x, long prec);
1.1       noro       67: long   itos(GEN x);
1.2     ! noro       68: ulong  itou(GEN x);
1.1       noro       69: GEN    modis(GEN x, long y);
                     70: GEN    mpabs(GEN x);
                     71: GEN    mpadd(GEN x, GEN y);
                     72: void   mpaff(GEN x, GEN y);
                     73: int    mpcmp(GEN x, GEN y);
                     74: GEN    mpcopy(GEN x);
                     75: GEN    mpdiv(GEN x, GEN y);
                     76: int    mpdivis(GEN x, GEN y, GEN z);
                     77: int    mpdivisis(GEN x, long y, GEN z);
                     78: GEN    mpmul(GEN x, GEN y);
                     79: GEN    mpneg(GEN x);
                     80: GEN    mpsub(GEN x, GEN y);
                     81: void   mulsii(long x, GEN y, GEN z);
                     82: long   mulssmod(ulong a, ulong b, ulong c);
                     83: void   mulssz(long x, long y, GEN z);
                     84: GEN    new_chunk(long x);
                     85: GEN    realun(long prec);
                     86: GEN    realzero(long prec);
1.2     ! noro       87: GEN    realzero_bit(long bitprec);
1.1       noro       88: void   resiiz(GEN x, GEN y, GEN z);
                     89: GEN    resis(GEN x, long y);
                     90: GEN    ressi(long x, GEN y);
                     91: GEN    shiftr(GEN x, long n);
                     92: long   smodis(GEN x, long y);
1.2     ! noro       93: GEN    stor(long x, long prec);
1.1       noro       94: GEN    stoi(long x);
                     95: GEN    subii(GEN x, GEN y);
                     96: GEN    subir(GEN x, GEN y);
                     97: GEN    subri(GEN x, GEN y);
                     98: GEN    subrr(GEN x, GEN y);
                     99: GEN    subsi(long x, GEN y);
                    100: GEN    subsr(long x, GEN y);
                    101: long   subssmod(long a, long b, long p);
                    102: GEN    utoi(ulong x);
                    103: long   vali(GEN x);
                    104:
                    105: #else /* defined(INLINE) */
                    106: INLINE long
                    107: evallg(long x)
                    108: {
                    109:   if (x & ~LGBITS) err(errlg);
1.2     ! noro      110:   return _evallg(x);
1.1       noro      111: }
                    112:
                    113: INLINE long
                    114: evallgef(long x)
                    115: {
                    116:   if (x & ~LGEFBITS) err(errlgef);
1.2     ! noro      117:   return _evallgef(x);
1.1       noro      118: }
                    119:
                    120: INLINE long
                    121: evalvalp(long x)
                    122: {
1.2     ! noro      123:   const long v = _evalvalp(x);
1.1       noro      124:   if (v & ~VALPBITS) err(errvalp);
                    125:   return v;
                    126: }
                    127:
                    128: INLINE long
                    129: evalexpo(long x)
                    130: {
1.2     ! noro      131:   const long v = _evalexpo(x);
1.1       noro      132:   if (v & ~EXPOBITS) err(errexpo);
                    133:   return v;
                    134: }
                    135:
                    136: INLINE GEN
                    137: new_chunk(long x)
                    138: {
                    139:   const GEN z = ((GEN) avma) - x;
                    140:   if ((ulong)x > (ulong)((GEN)avma-(GEN)bot)) err(errpile);
                    141: #ifdef MEMSTEP
                    142:   checkmemory(z);
                    143: #endif
                    144: #ifdef _WIN32
                    145:   if (win32ctrlc) dowin32ctrlc();
                    146: #endif
1.2     ! noro      147:   avma = (gpmem_t)z; return z;
1.1       noro      148: }
                    149:
                    150: /* THE FOLLOWING ONES ARE IN mp.s */
                    151: #  ifndef __M68K__
                    152:
                    153: INLINE GEN
                    154: cgetg(long x, long y)
                    155: {
                    156:   const GEN z = new_chunk(x);
                    157:   z[0] = evaltyp(y) | evallg(x);
                    158:   return z;
                    159: }
                    160:
                    161: INLINE GEN
                    162: cgeti(long x)
                    163: {
                    164:   const GEN z = new_chunk(x);
                    165:   z[0] = evaltyp(t_INT) | evallg(x);
                    166:   return z;
                    167: }
                    168:
                    169: INLINE GEN
                    170: cgetr(long x)
                    171: {
                    172:   const GEN z = new_chunk(x);
                    173:   z[0] = evaltyp(t_REAL) | evallg(x);
                    174:   return z;
                    175: }
                    176: #  endif /* __M68K__ */
                    177:
                    178: /* cannot do memcpy because sometimes x and y overlap */
                    179: INLINE GEN
                    180: mpcopy(GEN x)
                    181: {
                    182:   register long lx = lg(x);
                    183:   const GEN y = new_chunk(lx);
                    184:
                    185:   while (--lx >= 0) y[lx]=x[lx];
                    186:   return y;
                    187: }
                    188:
                    189: INLINE GEN
                    190: icopy(GEN x)
                    191: {
                    192:   register long lx = lgefint(x);
                    193:   const GEN y = cgeti(lx);
                    194:
                    195:   while (--lx > 0) y[lx]=x[lx];
                    196:   return y;
                    197: }
                    198:
                    199: /* copy integer x as if we had avma = av */
                    200: INLINE GEN
                    201: icopy_av(GEN x, GEN y)
                    202: {
                    203:   register long lx = lgefint(x);
                    204:
                    205:   y -= lx; while (--lx >= 0) y[lx]=x[lx];
                    206:   return y;
                    207: }
                    208:
                    209: INLINE GEN
                    210: mpneg(GEN x)
                    211: {
                    212:   const GEN y=mpcopy(x);
                    213:   setsigne(y,-signe(x)); return y;
                    214: }
                    215:
                    216: INLINE GEN
                    217: mpabs(GEN x)
                    218: {
                    219:   const GEN y=mpcopy(x);
                    220:   if (signe(x)<0) setsigne(y,1);
                    221:   return y;
                    222: }
                    223:
                    224: INLINE long
                    225: smodis(GEN x, long y)
                    226: {
1.2     ! noro      227:   const gpmem_t av=avma; divis(x,y); avma=av;
1.1       noro      228:   if (!hiremainder) return 0;
                    229:   return (signe(x)>0) ? hiremainder: labs(y)+hiremainder;
                    230: }
                    231:
                    232: INLINE GEN
                    233: utoi(ulong x)
                    234: {
                    235:   GEN y;
                    236:
                    237:   if (!x) return gzero;
                    238:   y=cgeti(3); y[1] = evalsigne(1) | evallgefint(3); y[2] = x;
                    239:   return y;
                    240: }
                    241:
                    242: INLINE GEN stoi(long);
                    243: INLINE GEN realzero(long);
                    244:
                    245: INLINE GEN
                    246: stosmall(long x)
                    247: {
                    248:   if (labs(x) & SMALL_MASK) return stoi(x);
                    249:   return (GEN) (1 | (x<<1));
                    250: }
                    251:
                    252: #  ifndef __M68K__
                    253: INLINE GEN
                    254: stoi(long x)
                    255: {
                    256:   GEN y;
                    257:
                    258:   if (!x) return gzero;
                    259:   y=cgeti(3);
                    260:   if (x>0) { y[1] = evalsigne(1) | evallgefint(3); y[2] = x; }
                    261:   else { y[1] = evalsigne(-1) | evallgefint(3); y[2] = -x; }
                    262:   return y;
                    263: }
                    264:
                    265: INLINE long
                    266: itos(GEN x)
                    267: {
1.2     ! noro      268:   const long s = signe(x);
        !           269:   long u;
1.1       noro      270:
                    271:   if (!s) return 0;
1.2     ! noro      272:   u = (long)x[2]; if (lgefint(x) > 3 || u < 0) err(affer2);
        !           273:   return (s>0) ? u : -u;
1.1       noro      274: }
                    275:
                    276: INLINE void
                    277: affii(GEN x, GEN y)
                    278: {
                    279:   long lx;
                    280:
                    281:   if (x==y) return;
                    282:   lx=lgefint(x); if (lg(y)<lx) err(affer3);
                    283:   while (--lx) y[lx]=x[lx];
                    284: }
                    285:
                    286: INLINE void
                    287: affsi(long s, GEN x)
                    288: {
1.2     ! noro      289:   if (!s) x[1] = evalsigne(0) | evallgefint(2);
        !           290:   else
        !           291:   {
        !           292:     if (lg(x) < 3) err(affer1);
        !           293:     if (s > 0) { x[1] = evalsigne( 1) | evallgefint(3); x[2] =  s; }
        !           294:     else       { x[1] = evalsigne(-1) | evallgefint(3); x[2] = -s; }
        !           295:   }
1.1       noro      296: }
                    297:
                    298: INLINE void
                    299: affsr(long s, GEN x)
                    300: {
                    301:   long l;
                    302:
                    303:   if (!s)
                    304:   {
1.2     ! noro      305:     x[1] = evalexpo(-bit_accuracy(lg(x)));
        !           306:     return;
1.1       noro      307:   }
                    308:   if (s<0) { x[1] = evalsigne(-1); s = -s; }
                    309:   else x[1] = evalsigne(1);
                    310:   l=bfffo(s); x[1] |= evalexpo((BITS_IN_LONG-1)-l);
                    311:   x[2] = s<<l; for (l=3; l<lg(x); l++) x[l]=0;
                    312: }
                    313:
                    314: INLINE void
                    315: mpaff(GEN x, GEN y)
                    316: {
                    317:   if (typ(x)==t_INT)
                    318:    { if (typ(y)==t_INT) affii(x,y); else affir(x,y); }
                    319:   else
                    320:    { if (typ(y)==t_INT) affri(x,y); else affrr(x,y); }
                    321: }
                    322:
                    323: INLINE GEN
                    324: shiftr(GEN x, long n)
                    325: {
                    326:   const long e = evalexpo(expo(x)+n);
                    327:   const GEN y = rcopy(x);
                    328:
                    329:   if (e & ~EXPOBITS) err(shier2);
                    330:   y[1] = (y[1]&~EXPOBITS) | e; return y;
                    331: }
                    332:
                    333: INLINE int
                    334: cmpir(GEN x, GEN y)
                    335: {
1.2     ! noro      336:   gpmem_t av;
1.1       noro      337:   GEN z;
                    338:
                    339:   if (!signe(x)) return -signe(y);
1.2     ! noro      340:   if (!signe(y)) return  signe(x);
1.1       noro      341:   av=avma; z=cgetr(lg(y)); affir(x,z); avma=av;
                    342:   return cmprr(z,y); /* cmprr does no memory adjustment */
                    343: }
                    344:
                    345: INLINE int
                    346: cmpsr(long x, GEN y)
                    347: {
1.2     ! noro      348:   gpmem_t av;
1.1       noro      349:   GEN z;
                    350:
                    351:   if (!x) return -signe(y);
                    352:   av=avma; z=cgetr(3); affsr(x,z); avma=av;
                    353:   return cmprr(z,y);
                    354: }
                    355:
                    356: INLINE void
                    357: addssz(long x, long y, GEN z)
                    358: {
                    359:   if (typ(z)==t_INT) gops2ssz(addss,x,y,z);
                    360:   else
                    361:   {
1.2     ! noro      362:     const gpmem_t av=avma;
1.1       noro      363:     const GEN p1=cgetr(lg(z));
                    364:
                    365:     affsr(x,p1); affrr(addrs(p1,y),z); avma=av;
                    366:   }
                    367: }
                    368:
                    369: INLINE GEN
                    370: subii(GEN x, GEN y)
                    371: {
                    372:   const long s=signe(y);
                    373:   GEN z;
                    374:
                    375:   if (x==y) return gzero;
                    376:   setsigne(y,-s); z=addii(x,y);
                    377:   setsigne(y, s); return z;
                    378: }
                    379:
                    380: INLINE GEN
                    381: subrr(GEN x, GEN y)
                    382: {
                    383:   const long s=signe(y);
                    384:   GEN z;
                    385:
                    386:   if (x==y) return realzero(lg(x)+2);
                    387:   setsigne(y,-s); z=addrr(x,y);
                    388:   setsigne(y, s); return z;
                    389: }
                    390:
                    391: INLINE GEN
                    392: subir(GEN x, GEN y)
                    393: {
                    394:   const long s=signe(y);
                    395:   GEN z;
                    396:
                    397:   setsigne(y,-s); z=addir(x,y);
                    398:   setsigne(y, s); return z;
                    399: }
                    400:
                    401: INLINE GEN
                    402: subri(GEN x, GEN y)
                    403: {
                    404:   const long s=signe(y);
                    405:   GEN z;
                    406:
                    407:   setsigne(y,-s); z=addir(y,x);
                    408:   setsigne(y, s); return z;
                    409: }
                    410:
                    411: INLINE GEN
                    412: subsi(long x, GEN y)
                    413: {
                    414:   const long s=signe(y);
                    415:   GEN z;
                    416:
                    417:   setsigne(y,-s); z=addsi(x,y);
                    418:   setsigne(y, s); return z;
                    419: }
                    420:
                    421: INLINE GEN
                    422: subsr(long x, GEN y)
                    423: {
                    424:   const long s=signe(y);
                    425:   GEN z;
                    426:
                    427:   setsigne(y,-s); z=addsr(x,y);
                    428:   setsigne(y, s); return z;
                    429: }
                    430:
                    431: INLINE void
                    432: mulssz(long x, long y, GEN z)
                    433: {
                    434:   if (typ(z)==t_INT) gops2ssz(mulss,x,y,z);
                    435:   else
                    436:   {
1.2     ! noro      437:     const gpmem_t av=avma;
1.1       noro      438:     const GEN p1=cgetr(lg(z));
                    439:
                    440:     affsr(x,p1); mpaff(mulsr(y,p1),z); avma=av;
                    441:   }
                    442: }
                    443:
                    444: INLINE void
                    445: mulsii(long x, GEN y, GEN z)
                    446: {
1.2     ! noro      447:   const gpmem_t av=avma;
1.1       noro      448:   affii(mulsi(x,y),z); avma=av;
                    449: }
                    450:
                    451: INLINE void
                    452: addsii(long x, GEN y, GEN z)
                    453: {
1.2     ! noro      454:   const gpmem_t av=avma;
1.1       noro      455:   affii(addsi(x,y),z); avma=av;
                    456: }
                    457:
                    458: INLINE long
                    459: divisii(GEN x, long y, GEN z)
                    460: {
1.2     ! noro      461:   const gpmem_t av=avma;
1.1       noro      462:   affii(divis(x,y),z); avma=av; return hiremainder;
                    463: }
                    464:
                    465: INLINE long
                    466: vali(GEN x)
                    467: {
                    468:   long lx,i;
                    469:
                    470:   if (!signe(x)) return -1;
                    471:   i = lx = lgefint(x)-1; while (!x[i]) i--;
                    472:   return ((lx-i)<<TWOPOTBITS_IN_LONG) + vals(x[i]);
                    473: }
                    474:
                    475: INLINE GEN
                    476: divss(long x, long y)
                    477: {
                    478:   long p1;
                    479:   LOCAL_HIREMAINDER;
                    480:
                    481:   if (!y) err(diver1);
                    482:   hiremainder=0; p1 = divll((ulong)labs(x),(ulong)labs(y));
                    483:   if (x<0) { hiremainder = -((long)hiremainder); p1 = -p1; }
                    484:   if (y<0) p1 = -p1;
                    485:   SAVE_HIREMAINDER; return stoi(p1);
                    486: }
                    487:
                    488: INLINE GEN
                    489: dvmdss(long x, long y, GEN *z)
                    490: {
                    491:   const GEN p1=divss(x,y);
                    492:   *z = stoi(hiremainder); return p1;
                    493: }
                    494:
                    495: INLINE GEN
                    496: dvmdsi(long x, GEN y, GEN *z)
                    497: {
                    498:   const GEN p1=divsi(x,y);
                    499:   *z = stoi(hiremainder); return p1;
                    500: }
                    501:
                    502: INLINE GEN
                    503: dvmdis(GEN x, long y, GEN *z)
                    504: {
                    505:   const GEN p1=divis(x,y);
                    506:   *z=stoi(hiremainder); return p1;
                    507: }
                    508:
                    509: INLINE void
                    510: dvmdssz(long x, long y, GEN z, GEN t)
                    511: {
1.2     ! noro      512:   const gpmem_t av=avma;
1.1       noro      513:   const GEN p1=divss(x,y);
                    514:
                    515:   affsi(hiremainder,t); mpaff(p1,z); avma=av;
                    516: }
                    517:
                    518: INLINE void
                    519: dvmdsiz(long x, GEN y, GEN z, GEN t)
                    520: {
1.2     ! noro      521:   const gpmem_t av=avma;
1.1       noro      522:   const GEN p1=divsi(x,y);
                    523:
                    524:   affsi(hiremainder,t); mpaff(p1,z); avma=av;
                    525: }
                    526:
                    527: INLINE void
                    528: dvmdisz(GEN x, long y, GEN z, GEN t)
                    529: {
1.2     ! noro      530:   const gpmem_t av=avma;
1.1       noro      531:   const GEN p1=divis(x,y);
                    532:
                    533:   affsi(hiremainder,t); mpaff(p1,z); avma=av;
                    534: }
                    535:
                    536: INLINE void
                    537: dvmdiiz(GEN x, GEN y, GEN z, GEN t)
                    538: {
1.2     ! noro      539:   const gpmem_t av=avma;
1.1       noro      540:   GEN p;
                    541:
                    542:   mpaff(dvmdii(x,y,&p),z); mpaff(p,t); avma=av;
                    543: }
                    544:
                    545: INLINE GEN
                    546: modis(GEN x, long y)
                    547: {
                    548:   return stoi(smodis(x,y));
                    549: }
                    550:
                    551: INLINE GEN
                    552: ressi(long x, GEN y)
                    553: {
1.2     ! noro      554:   const gpmem_t av=avma;
1.1       noro      555:   divsi(x,y); avma=av; return stoi(hiremainder);
                    556: }
                    557:
                    558: INLINE GEN
                    559: resis(GEN x, long y)
                    560: {
1.2     ! noro      561:   const gpmem_t av=avma;
1.1       noro      562:   divis(x,y); avma=av; return stoi(hiremainder);
                    563: }
                    564:
                    565: INLINE void
                    566: divisz(GEN x, long y, GEN z)
                    567: {
                    568:   if (typ(z)==t_INT) gops2gsz(divis,x,y,z);
                    569:   else
                    570:   {
1.2     ! noro      571:     const gpmem_t av=avma;
1.1       noro      572:     const GEN p1=cgetr(lg(z));
                    573:
                    574:     affir(x,p1); affrr(divrs(p1,y),z); avma=av;
                    575:   }
                    576: }
                    577:
                    578: INLINE void
                    579: divsiz(long x, GEN y, GEN z)
                    580: {
1.2     ! noro      581:   const gpmem_t av=avma;
1.1       noro      582:
                    583:   if (typ(z)==t_INT) gaffect(divsi(x,y),z);
                    584:   else
                    585:   {
                    586:     const long lz=lg(z);
                    587:     const GEN p1=cgetr(lz), p2=cgetr(lz);
                    588:
                    589:     affsr(x,p1); affir(y,p2);
                    590:     affrr(divrr(p1,p2),z);
                    591:   }
                    592:   avma=av;
                    593: }
                    594:
                    595: INLINE void
                    596: divssz(long x, long y, GEN z)
                    597: {
1.2     ! noro      598:   const gpmem_t av=avma;
1.1       noro      599:
                    600:   if (typ(z)==t_INT) gaffect(divss(x,y),z);
                    601:   else
                    602:   {
                    603:     const GEN p1=cgetr(lg(z));
                    604:
                    605:     affsr(x,p1); affrr(divrs(p1,y),z);
                    606:   }
                    607:   avma=av;
                    608: }
                    609:
                    610: INLINE void
                    611: divrrz(GEN x, GEN y, GEN z)
                    612: {
1.2     ! noro      613:   const gpmem_t av=avma;
1.1       noro      614:   mpaff(divrr(x,y),z); avma=av;
                    615: }
                    616:
                    617: INLINE void
                    618: resiiz(GEN x, GEN y, GEN z)
                    619: {
1.2     ! noro      620:   const gpmem_t av=avma;
1.1       noro      621:   affii(resii(x,y),z); avma=av;
                    622: }
                    623:
                    624: INLINE int
                    625: divise(GEN x, GEN y)
                    626: {
1.2     ! noro      627:   const gpmem_t av=avma;
1.1       noro      628:   const GEN p1=resii(x,y);
                    629:   avma=av; return p1 == gzero;
                    630: }
                    631:
                    632: INLINE int
                    633: mpcmp(GEN x, GEN y)
                    634: {
                    635:   if (typ(x)==t_INT)
                    636:     return (typ(y)==t_INT) ? cmpii(x,y) : cmpir(x,y);
                    637:   return (typ(y)==t_INT) ? -cmpir(y,x) : cmprr(x,y);
                    638: }
                    639:
                    640: INLINE GEN
                    641: mpadd(GEN x, GEN y)
                    642: {
                    643:   if (typ(x)==t_INT)
                    644:     return (typ(y)==t_INT) ? addii(x,y) : addir(x,y);
                    645:   return (typ(y)==t_INT) ? addir(y,x) : addrr(x,y);
                    646: }
                    647:
                    648: INLINE GEN
                    649: mpsub(GEN x, GEN y)
                    650: {
                    651:   if (typ(x)==t_INT)
                    652:     return (typ(y)==t_INT) ? subii(x,y) : subir(x,y);
                    653:   return (typ(y)==t_INT) ? subri(x,y) : subrr(x,y);
                    654: }
                    655:
                    656: INLINE GEN
                    657: mpmul(GEN x, GEN y)
                    658: {
                    659:   if (typ(x)==t_INT)
                    660:     return (typ(y)==t_INT) ? mulii(x,y) : mulir(x,y);
                    661:   return (typ(y)==t_INT) ? mulir(y,x) : mulrr(x,y);
                    662: }
                    663:
                    664: INLINE GEN
                    665: mpdiv(GEN x, GEN y)
                    666: {
                    667:   if (typ(x)==t_INT)
                    668:     return (typ(y)==t_INT) ? divii(x,y) : divir(x,y);
                    669:   return (typ(y)==t_INT) ? divri(x,y) : divrr(x,y);
                    670: }
                    671:
                    672: INLINE int
                    673: mpdivis(GEN x, GEN y, GEN z)
                    674: {
1.2     ! noro      675:   const gpmem_t av=avma;
1.1       noro      676:   GEN p2;
                    677:   const GEN p1=dvmdii(x,y,&p2);
                    678:
                    679:   if (signe(p2)) { avma=av; return 0; }
                    680:   affii(p1,z); avma=av; return 1;
                    681: }
                    682:
                    683: /* THE FOLLOWING ONES ARE NOT IN mp.s */
                    684: #  endif /* !defined(__M68K__) */
                    685:
1.2     ! noro      686: INLINE ulong
        !           687: itou(GEN x)
        !           688: {
        !           689:   const long s = signe(x);
        !           690:
        !           691:   if (!s) return 0;
        !           692:   if (lgefint(x) > 3) err(affer2);
        !           693:   return x[2];
        !           694: }
        !           695:
        !           696: INLINE void
        !           697: affui(ulong u, GEN x)
        !           698: {
        !           699:   if (!u) x[1] = evalsigne(0) | evallgefint(2);
        !           700:   else
        !           701:   {
        !           702:     if (lg(x) < 3) err(affer1);
        !           703:     x[1] = evalsigne(1) | evallgefint(3); x[2] = u;
        !           704:   }
        !           705: }
        !           706:
1.1       noro      707: INLINE int
                    708: mpdivisis(GEN x, long y, GEN z)
                    709: {
1.2     ! noro      710:   const gpmem_t av = avma;
1.1       noro      711:   GEN p1 = divis(x,y);
                    712:   if (hiremainder) { avma = av; return 0; }
                    713:   affii(p1,z); avma = av; return 1;
                    714: }
                    715:
                    716: INLINE double
                    717: gtodouble(GEN x)
                    718: {
1.2     ! noro      719:   static long reel4[4]={ evaltyp(t_REAL) | _evallg(4),0,0,0 };
1.1       noro      720:
                    721:   if (typ(x)==t_REAL) return rtodbl(x);
                    722:   gaffect(x,(GEN)reel4); return rtodbl((GEN)reel4);
                    723: }
                    724:
                    725: INLINE GEN
1.2     ! noro      726: realzero_bit(long bitprec) { GEN x=cgetr(2); x[1]=evalexpo(bitprec); return x; }
        !           727:
        !           728: INLINE GEN
        !           729: realzero(long prec) { return realzero_bit(-bit_accuracy(prec)); }
        !           730:
        !           731: INLINE GEN
        !           732: realun(long prec) { GEN x=cgetr(prec); affsr(1,x); return x; }
        !           733:
        !           734: INLINE GEN
        !           735: stor(long s, long prec) { GEN z = cgetr(prec); affsr(s,z); return z; }
1.1       noro      736:
                    737: INLINE GEN
1.2     ! noro      738: itor(GEN x, long prec) { GEN z = cgetr(prec); affir(x,z); return z; }
1.1       noro      739:
                    740: INLINE long
                    741: addssmod(long a, long b, long p)
                    742: {
                    743:   ulong res = a + b;
                    744:   return (res >= (ulong)p) ? res - p : res;
                    745: }
                    746:
                    747: INLINE long
                    748: subssmod(long a, long b, long p)
                    749: {
                    750:   long res = a - b;
                    751:   return (res >= 0) ? res : res + p;
                    752: }
                    753:
                    754: INLINE long
                    755: mulssmod(ulong a, ulong b, ulong c)
                    756: {
                    757:   LOCAL_HIREMAINDER;
                    758:   {
                    759:     register ulong x = mulll(a,b);
                    760:
                    761:     /* alter the doubleword by a multiple of c: */
                    762:     if (hiremainder>=c) hiremainder %= c;
                    763:     (void)divll(x,c);
                    764:   }
                    765:   return hiremainder;
                    766: }
                    767:
                    768: INLINE long
                    769: divssmod(long a, long b, long p)
                    770: {
                    771:   long v1 = 0, v2 = 1, v3, r, oldp = p;
                    772:
                    773:   while (b > 1)
                    774:   {
                    775:     v3 = v1 - (p / b) * v2; v1 = v2; v2 = v3;
                    776:     r = p % b; p = b; b = r;
                    777:   }
                    778:
                    779:   if (v2 < 0) v2 += oldp;
                    780:   return mulssmod(a, v2, oldp);
                    781: }
                    782:
                    783: INLINE long
                    784: expi(GEN x)
                    785: {
                    786:   const long lx=lgefint(x);
                    787:   return lx==2? -HIGHEXPOBIT: bit_accuracy(lx)-bfffo(x[2])-1;
                    788: }
                    789:
                    790: #endif

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