[BACK]Return to Z.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib2 / asir2000 / engine

Annotation of OpenXM_contrib2/asir2000/engine/Z.c, Revision 1.5

1.1       noro        1: #include "ca.h"
1.5     ! noro        2: #include "base.h"
1.1       noro        3: #include "inline.h"
                      4:
1.5     ! noro        5: inline void _addz(Z n1,Z n2,Z nr);
        !             6: inline void _subz(Z n1,Z n2,Z nr);
        !             7: inline void _mulz(Z n1,Z n2,Z nr);
        !             8: inline int _addz_main(unsigned int *m1,int d1,unsigned int *m2,int d2,unsigned int *mr);
        !             9: inline int _subz_main(unsigned int *m1,int d1,unsigned int *m2,int d2,unsigned int *mr);
1.3       noro       10:
                     11: /* immediate int -> Z */
1.5     ! noro       12: #define UTOZ(c,n) (n)=(!((unsigned int)(c))?0:(((unsigned int)(c))<=IMM_MAX?((Z)((((unsigned int)(c))<<1)|1)):utoz((unsigned int)(c))))
        !            13: #define STOZ(c,n) (n)=(!((int)(c))?0:(((int)(c))>=IMM_MIN&&((int)(c))<=IMM_MAX?((Z)((((int)(c))<<1)|1)):stoz((int)(c))))
1.3       noro       14: /* immediate Z ? */
                     15: #define IS_IMM(c) (((unsigned int)c)&1)
                     16: /* Z can be conver to immediate ? */
1.5     ! noro       17: #define IS_SZ(n) (((SL(n) == 1)||(SL(n)==-1))&&BD(n)[0]<=IMM_MAX)
1.3       noro       18: /* Z -> immediate Z */
1.5     ! noro       19: #define SZTOZ(n,z) (z)=(Z)(SL(n)<0?(((-BD(n)[0])<<1)|1):(((BD(n)[0])<<1)|1))
1.3       noro       20: /* Z -> immediate int */
1.5     ! noro       21: #define ZTOS(c) (((int)(c))>>1)
        !            22:
        !            23: int uniz(Z a)
        !            24: {
        !            25:        if ( IS_IMM(a) && ZTOS(a) == 1 ) return 1;
        !            26:        else return 0;
        !            27: }
        !            28:
        !            29: int cmpz(Z a,Z b)
        !            30: {
        !            31:        int *ma,*mb;
        !            32:        int sa,sb,da,db,ca,cb,i;
        !            33:
        !            34:        if ( !a )
        !            35:                return -sgnz(b);
        !            36:        else if ( !b )
        !            37:                return sgnz(a);
        !            38:        else {
        !            39:                sa = sgnz(a); sb = sgnz(b);
        !            40:                if ( sa > sb ) return 1;
        !            41:                else if ( sa < sb ) return -1;
        !            42:                else if ( IS_IMM(a) )
        !            43:                        if ( IS_IMM(b) ) {
        !            44:                                ca = ZTOS(a); cb = ZTOS(b);
        !            45:                                if ( ca > cb ) return sa;
        !            46:                                else if ( ca < cb ) return -sa;
        !            47:                                else return 0;
        !            48:                        } else
        !            49:                                return -sa;
        !            50:                else if ( IS_IMM(b) )
        !            51:                        return sa;
        !            52:                else {
        !            53:                        da = SL(a)*sa; db = SL(b)*sa;
        !            54:                        if ( da > db ) return sa;
        !            55:                        else if ( da < db ) return -sa;
        !            56:                        else {
        !            57:                                for ( i = da-1, ma = BD(a)+i, mb = BD(b)+i; i >= 0; i-- )
        !            58:                                        if ( *ma > *mb ) return sa;
        !            59:                                        else if ( *ma < *mb ) return -sa;
        !            60:                                return 0;
        !            61:                        }
        !            62:                }
        !            63:        }
        !            64: }
1.1       noro       65:
1.5     ! noro       66: Z stoz(int c)
1.3       noro       67: {
                     68:        Z z;
                     69:
                     70:        z = ZALLOC(1);
                     71:        if ( c < 0 ) {
                     72:                SL(z) = -1; BD(z)[0] = -c;
                     73:        } else {
                     74:                SL(z) = 1; BD(z)[0] = c;
                     75:        }
                     76:        return z;
                     77: }
                     78:
1.5     ! noro       79: Z utoz(unsigned int c)
        !            80: {
        !            81:        Z z;
        !            82:
        !            83:        z = ZALLOC(1);
        !            84:        SL(z) = 1; BD(z)[0] = c;
        !            85:        return z;
        !            86: }
        !            87:
        !            88: Z simpz(Z n)
        !            89: {
        !            90:        Z n1;
        !            91:
        !            92:        if ( !n ) return 0;
        !            93:        else if ( IS_IMM(n) ) return n;
        !            94:        else if ( IS_SZ(n) ) {
        !            95:                SZTOZ(n,n1); return n1;
        !            96:        } else
        !            97:                return n;
        !            98: }
        !            99:
1.3       noro      100: int sgnz(Z n)
1.2       noro      101: {
                    102:        if ( !n ) return 0;
1.5     ! noro      103:        else if ( IS_IMM(n) ) return ZTOS(n)>0?1:-1;
1.2       noro      104:        else if ( SL(n) < 0 ) return -1;
                    105:        else return 1;
                    106: }
                    107:
1.1       noro      108: z_mag(Z n)
                    109: {
1.4       noro      110:        int c,i;
1.3       noro      111:
                    112:        if ( !n ) return 0;
                    113:        else if ( IS_IMM(n) ) {
1.5     ! noro      114:                c = ZTOS(n);
1.3       noro      115:                if ( c < 0 ) c = -c;
                    116:                for ( i = 0; c; c >>= 1, i++ );
                    117:                return i;
                    118:        }
                    119:        else return n_bits((N)n);
1.1       noro      120: }
                    121:
                    122: Z qtoz(Q n)
                    123: {
1.3       noro      124:        Z r,t;
1.4       noro      125:        int c;
1.1       noro      126:
                    127:        if ( !n ) return 0;
                    128:        else if ( !INT(n) )
                    129:                error("qtoz : invalid input");
                    130:        else {
1.3       noro      131:                t = (Z)NM(n);
1.5     ! noro      132:                if ( IS_SZ(t) ) {
1.4       noro      133:                        c = SGN(n) < 0 ? -BD(t)[0] : BD(t)[0];
1.5     ! noro      134:                        STOZ(c,r);
1.3       noro      135:                } else {
                    136:                        r = dupz((Z)t);
1.4       noro      137:                        if ( SGN(n) < 0 ) SL(r) = -SL(r);
1.3       noro      138:                }
1.1       noro      139:                return r;
                    140:        }
                    141: }
                    142:
                    143: Q ztoq(Z n)
                    144: {
                    145:        Q r;
                    146:        Z nm;
1.3       noro      147:        int sgn,c;
1.1       noro      148:
                    149:        if ( !n ) return 0;
1.3       noro      150:        else if ( IS_IMM(n) ) {
1.5     ! noro      151:                c = ZTOS(n);
1.3       noro      152:                STOQ(c,r);
                    153:                return r;
                    154:        } else {
1.1       noro      155:                nm = dupz(n);
                    156:                if ( SL(nm) < 0 ) {
                    157:                        sgn = -1;
                    158:                        SL(nm) = -SL(nm);
                    159:                } else
                    160:                        sgn = 1;
                    161:                NTOQ((N)nm,sgn,r);
                    162:                return r;
                    163:        }
                    164: }
                    165:
                    166: Z dupz(Z n)
                    167: {
1.5     ! noro      168:        Z r;
1.1       noro      169:        int sd,i;
                    170:
                    171:        if ( !n ) return 0;
1.3       noro      172:        else if ( IS_IMM(n) ) return n;
                    173:        else {
                    174:                if ( (sd = SL(n)) < 0 ) sd = -sd;
1.5     ! noro      175:                r = ZALLOC(sd);
        !           176:                SL(r) = SL(n);
        !           177:                for ( i = 0; i < sd; i++ ) BD(r)[i] = BD(n)[i];
        !           178:                return r;
1.3       noro      179:        }
1.1       noro      180: }
                    181:
                    182: Z chsgnz(Z n)
                    183: {
                    184:        Z r;
1.3       noro      185:        int c;
1.1       noro      186:
                    187:        if ( !n ) return 0;
1.3       noro      188:        else if ( IS_IMM(n) ) {
1.5     ! noro      189:                c = -ZTOS(n);
        !           190:                STOZ(c,r);
1.3       noro      191:                return r;
                    192:        } else {
1.1       noro      193:                r = dupz(n);
                    194:                SL(r) = -SL(r);
                    195:                return r;
                    196:        }
                    197: }
                    198:
1.5     ! noro      199: Z absz(Z n)
        !           200: {
        !           201:        Z r;
        !           202:        int c;
        !           203:
        !           204:        if ( !n ) return 0;
        !           205:        else if ( sgnz(n) > 0 )
        !           206:                return n;
        !           207:        else
        !           208:                return chsgnz(n);
        !           209: }
1.3       noro      210:
1.1       noro      211: Z addz(Z n1,Z n2)
                    212: {
1.3       noro      213:        int d1,d2,d,c;
                    214:        Z r,r1;
                    215:        struct oZ t;
1.1       noro      216:
                    217:        if ( !n1 ) return dupz(n2);
                    218:        else if ( !n2 ) return dupz(n1);
1.3       noro      219:        else if ( IS_IMM(n1) ) {
                    220:                if ( IS_IMM(n2) ) {
1.5     ! noro      221:                        c = ZTOS(n1)+ZTOS(n2);
        !           222:                        STOZ(c,r);
1.3       noro      223:                } else {
1.5     ! noro      224:                        c = ZTOS(n1);
1.3       noro      225:                        if ( c < 0 ) {
                    226:                                t.p = -1; t.b[0] = -c;
1.1       noro      227:                        } else {
1.3       noro      228:                                t.p = 1; t.b[0] = c;
1.1       noro      229:                        }
1.3       noro      230:                        if ( (d2 = SL(n2)) < 0 ) d2 = -d2;
                    231:                        r = ZALLOC(d2+1);
                    232:                        _addz(&t,n2,r);
1.5     ! noro      233:                        if ( !SL(r) ) r = 0;
1.3       noro      234:                }
                    235:        } else if ( IS_IMM(n2) ) {
1.5     ! noro      236:                c = ZTOS(n2);
1.3       noro      237:                if ( c < 0 ) {
                    238:                        t.p = -1; t.b[0] = -c;
1.1       noro      239:                } else {
1.3       noro      240:                        t.p = 1; t.b[0] = c;
                    241:                }
                    242:                if ( (d1 = SL(n1)) < 0 ) d1 = -d1;
                    243:                r = ZALLOC(d1+1);
                    244:                _addz(n1,&t,r);
1.5     ! noro      245:                if ( !SL(r) ) r = 0;
1.3       noro      246:        } else {
                    247:                if ( (d1 = SL(n1)) < 0 ) d1 = -d1;
                    248:                if ( (d2 = SL(n2)) < 0 ) d2 = -d2;
                    249:                d = MAX(d1,d2)+1;
                    250:                r = ZALLOC(d);
                    251:                _addz(n1,n2,r);
                    252:                if ( !SL(r) ) r = 0;
1.1       noro      253:        }
1.5     ! noro      254:        if ( r && !((int)r&1) && IS_SZ(r) ) {
        !           255:                SZTOZ(r,r1); r = r1;
        !           256:        }
        !           257:        return r;
1.1       noro      258: }
                    259:
                    260: Z subz(Z n1,Z n2)
                    261: {
1.3       noro      262:        int d1,d2,d,c;
                    263:        Z r,r1;
                    264:        struct oZ t;
1.1       noro      265:
1.5     ! noro      266:        if ( !n1 )
        !           267:                return chsgnz(n2);
        !           268:        else if ( !n2 ) return n1;
1.3       noro      269:        else if ( IS_IMM(n1) ) {
                    270:                if ( IS_IMM(n2) ) {
1.5     ! noro      271:                        c = ZTOS(n1)-ZTOS(n2);
        !           272:                        STOZ(c,r);
1.3       noro      273:                } else {
1.5     ! noro      274:                        c = ZTOS(n1);
1.3       noro      275:                        if ( c < 0 ) {
                    276:                                t.p = -1; t.b[0] = -c;
                    277:                        } else {
                    278:                                t.p = 1; t.b[0] = c;
                    279:                        }
                    280:                        if ( (d2 = SL(n2)) < 0 ) d2 = -d2;
                    281:                        r = ZALLOC(d2+1);
                    282:                        _subz(&t,n2,r);
1.5     ! noro      283:                        if ( !SL(r) ) r = 0;
1.3       noro      284:                }
                    285:        } else if ( IS_IMM(n2) ) {
1.5     ! noro      286:                c = ZTOS(n2);
1.3       noro      287:                if ( c < 0 ) {
                    288:                        t.p = -1; t.b[0] = -c;
                    289:                } else {
                    290:                        t.p = 1; t.b[0] = c;
                    291:                }
                    292:                if ( (d1 = SL(n1)) < 0 ) d1 = -d1;
                    293:                r = ZALLOC(d1+1);
                    294:                _subz(n1,&t,r);
1.5     ! noro      295:                if ( !SL(r) ) r = 0;
1.3       noro      296:        } else {
                    297:                if ( (d1 = SL(n1)) < 0 ) d1 = -d1;
                    298:                if ( (d2 = SL(n2)) < 0 ) d2 = -d2;
                    299:                d = MAX(d1,d2)+1;
                    300:                r = ZALLOC(d);
                    301:                _subz(n1,n2,r);
                    302:                if ( !SL(r) ) r = 0;
1.1       noro      303:        }
1.5     ! noro      304:        if ( r && !((int)r&1) && IS_SZ(r) ) {
        !           305:                SZTOZ(r,r1); r = r1;
        !           306:        }
        !           307:        return r;
1.1       noro      308: }
                    309:
                    310: Z mulz(Z n1,Z n2)
                    311: {
1.3       noro      312:        int d1,d2,sgn,i;
1.5     ! noro      313:        int c1,c2;
1.1       noro      314:        unsigned int u1,u2,u,l;
1.3       noro      315:        Z r;
1.1       noro      316:
                    317:        if ( !n1 || !n2 ) return 0;
1.3       noro      318:
                    319:        if ( IS_IMM(n1) ) {
1.5     ! noro      320:                c1 = ZTOS(n1);
1.3       noro      321:                if ( IS_IMM(n2) ) {
1.5     ! noro      322:                        c2 = ZTOS(n2);
        !           323:                        if ( c1 == 1 )
        !           324:                                return n2;
        !           325:                        else if ( c1 == -1 )
        !           326:                                return chsgnz(n2);
        !           327:                        else if ( c2 == 1 )
        !           328:                                return n1;
        !           329:                        else if ( c2 == -1 )
        !           330:                                return chsgnz(n1);
        !           331:                        else {
        !           332:                                sgn = 1;
        !           333:                                if ( c1 < 0 ) { c1 = -c1; sgn = -sgn; }
        !           334:                                if ( c2 < 0 ) { c2 = -c2; sgn = -sgn; }
        !           335:                                u1 = (unsigned int)c1; u2 = (unsigned int)c2;
        !           336:                                DM(u1,u2,u,l);
        !           337:                                if ( !u ) {
        !           338:                                        UTOZ(l,r);
        !           339:                                } else {
        !           340:                                        r = ZALLOC(2); SL(r) = 2; BD(r)[1] = u; BD(r)[0] = l;
        !           341:                                }
1.1       noro      342:                        }
                    343:                } else {
1.5     ! noro      344:                        sgn = 1;
        !           345:                        if ( c1 < 0 ) { c1 = -c1; sgn = -sgn; }
        !           346:                        u1 = (unsigned int)c1;
1.3       noro      347:                        if ( (d2 = SL(n2)) < 0 ) { sgn = -sgn; d2 = -d2; }
                    348:                        r = ZALLOC(d2+1);
                    349:                        for ( i = d2; i >= 0; i-- ) BD(r)[i] = 0;
                    350:                        muln_1(BD(n2),d2,u1,BD(r));
                    351:                        SL(r) = BD(r)[d2]?d2+1:d2;
1.1       noro      352:                }
1.3       noro      353:        } else if ( IS_IMM(n2) ) {
1.5     ! noro      354:                c2 = ZTOS(n2);
        !           355:                if ( c2 == 1 )
        !           356:                        return n1;
        !           357:                else if ( c2 == -1 )
        !           358:                        return chsgnz(n1);
        !           359:
1.3       noro      360:                sgn = 1;
1.5     ! noro      361:                if ( c2 < 0 ) { sgn = -sgn; c2 = -c2; }
        !           362:                u2 = (unsigned int)c2;
1.3       noro      363:                if ( (d1 = SL(n1)) < 0 ) { sgn = -sgn; d1 = -d1; }
                    364:                r = ZALLOC(d1+1);
                    365:                for ( i = d1; i >= 0; i-- ) BD(r)[i] = 0;
                    366:                muln_1(BD(n1),d1,u2,BD(r));
                    367:                SL(r) = BD(r)[d1]?d1+1:d1;
                    368:        } else {
                    369:                sgn = 1;
1.5     ! noro      370:                if ( (d1 = SL(n1)) < 0 ) d1 = -d1;
        !           371:                if ( (d2 = SL(n2)) < 0 ) d2 = -d2;
1.3       noro      372:                r = ZALLOC(d1+d2);
                    373:                _mulz(n1,n2,r);
1.1       noro      374:        }
1.5     ! noro      375:        if ( sgn < 0 ) r = chsgnz(r);
1.3       noro      376:        return r;
1.1       noro      377: }
                    378:
1.3       noro      379: /* kokokara */
1.4       noro      380: #if 0
1.1       noro      381: Z divsz(Z n1,Z n2)
                    382: {
1.3       noro      383:        int sgn,d1,d2;
                    384:        Z q;
1.1       noro      385:
                    386:        if ( !n2 ) error("divsz : division by 0");
1.3       noro      387:        if ( !n1 ) return 0;
                    388:
                    389:        if ( IS_IMM(n1) ) {
                    390:                if ( !IS_IMM(n2) )
                    391:                        error("divsz : cannot happen");
1.5     ! noro      392:                c = ZTOS(n1)/ZTOS(n2);
        !           393:                STOZ(c,q);
1.3       noro      394:                return q;
1.1       noro      395:        }
1.3       noro      396:        if ( IS_IMM(n2) ) {
                    397:                sgn = 1;
1.5     ! noro      398:                u2 = ZTOS(n2); if ( u2 < 0 ) { sgn = -sgn; u2 = -u2; }
1.3       noro      399:                diviz(n1,u2,&q);
                    400:                if ( sgn < 0 ) SL(q) = -SL(q);
                    401:                return q;
                    402:        }
                    403:
                    404:        sgn = 1;
                    405:        if ( (d2 = SL(n2)) < 0 ) { sgn = -sgn; d2 = -d2; }
                    406:        if ( d2 == 1 ) {
                    407:                diviz(n1,BD(u2)[0],&q);
                    408:                if ( sgn < 0 ) SL(q) = -SL(q);
                    409:                return q;
                    410:        }
                    411:        if ( (d1 = SL(n1)) < 0 ) { sgn = -sgn; d1 = -d1; }
                    412:        if ( d1 < d2 ) error("divsz : cannot happen");
                    413:        return q;
1.1       noro      414: }
1.5     ! noro      415: #endif
        !           416:
        !           417: /* XXX */
        !           418: Z divz(Z n1,Z n2,Z *r)
        !           419: {
        !           420:        int s1,s2;
        !           421:        Q t1,t2,qq,rq;
        !           422:        N qn,rn;
        !           423:
        !           424:        if ( !n1 ) {
        !           425:                *r = 0; return 0;
        !           426:        }
        !           427:        if ( !n2 )
        !           428:                error("divz : division by 0");
        !           429:        t1 = ztoq(n1); t2 = ztoq(n2);
        !           430:        s1 = sgnz(n1); s2 = sgnz(n2);
        !           431:        /* n1 = qn*SGN(n1)*SGN(n2)*n2+SGN(n1)*rn */
        !           432:        divn(NM(t1),NM(t2),&qn,&rn);
        !           433:        NTOQ(qn,s1*s2,qq);
        !           434:        NTOQ(rn,s1,rq);
        !           435:        *r = qtoz(rq);
        !           436:        return qtoz(qq);
        !           437: }
        !           438:
        !           439: Z divsz(Z n1,Z n2)
        !           440: {
        !           441:        int s1,s2;
        !           442:        Q t1,t2,qq;
        !           443:        N qn;
        !           444:
        !           445:        if ( !n1 )
        !           446:                return 0;
        !           447:        if ( !n2 )
        !           448:                error("divsz : division by 0");
        !           449:        t1 = ztoq(n1); t2 = ztoq(n2);
        !           450:        s1 = sgnz(n1); s2 = sgnz(n2);
        !           451:        /* n1 = qn*SGN(n1)*SGN(n2)*n2 */
        !           452:        divsn(NM(t1),NM(t2),&qn);
        !           453:        NTOQ(qn,s1*s2,qq);
        !           454:        return qtoz(qq);
        !           455: }
        !           456:
        !           457: int gcdimm(int c1,int c2)
        !           458: {
        !           459:        int r;
        !           460:
        !           461:        if ( !c1 ) return c2;
        !           462:        else if ( !c2 ) return c1;
        !           463:        while ( 1 ) {
        !           464:                r = c1%c2;
        !           465:                if ( !r ) return c2;
        !           466:                c1 = c2; c2 = r;
        !           467:        }
        !           468: }
1.1       noro      469:
                    470: Z gcdz(Z n1,Z n2)
                    471: {
1.5     ! noro      472:        int c1,c2,g;
        !           473:        Z gcd,r;
        !           474:        N gn;
1.1       noro      475:
                    476:        if ( !n1 ) return n2;
                    477:        else if ( !n2 ) return n1;
                    478:
1.5     ! noro      479:        if ( IS_IMM(n1) ) {
        !           480:                c1 = ZTOS(n1);
        !           481:                if ( c1 < 0 ) c1 = -c1;
        !           482:                if ( IS_IMM(n2) )
        !           483:                        c2 = ZTOS(n2);
        !           484:                else
        !           485:                        c2 = remzi(n2,c1>0?c1:-c1);
        !           486:                if ( c2 < 0 ) c2 = -c2;
        !           487:                g = gcdimm(c1,c2);
        !           488:                STOZ(g,gcd);
        !           489:                return gcd;
        !           490:        } else if ( IS_IMM(n2) ) {
        !           491:                c2 = ZTOS(n2);
        !           492:                if ( c2 < 0 ) c2 = -c2;
        !           493:                c1 = remzi(n1,c2>0?c2:-c2);
        !           494:                if ( c1 < 0 ) c1 = -c1;
        !           495:                g = gcdimm(c1,c2);
        !           496:                STOZ(g,gcd);
        !           497:                return gcd;
        !           498:        } else {
        !           499:                n1 = dupz(n1);
        !           500:                if ( SL(n1) < 0 ) SL(n1) = -SL(n1);
        !           501:                n2 = dupz(n2);
        !           502:                if ( SL(n2) < 0 ) SL(n2) = -SL(n2);
        !           503:                gcdn((N)n1,(N)n2,&gn);
        !           504:                gcd = (Z)gn;
        !           505:                if ( IS_SZ(gcd) ) {
        !           506:                        SZTOZ(gcd,r); gcd = r;
        !           507:                }
        !           508:                return gcd;
        !           509:        }
1.1       noro      510: }
                    511:
                    512: int remzi(Z n,int m)
                    513: {
                    514:        unsigned int *x;
                    515:        unsigned int t,r;
1.5     ! noro      516:        int i,c;
1.1       noro      517:
                    518:        if ( !n ) return 0;
1.5     ! noro      519:        if ( IS_IMM(n) ) {
        !           520:                c = ZTOS(n)%m;
        !           521:                if ( c < 0 ) c += m;
        !           522:                return c;
        !           523:        }
        !           524:
1.1       noro      525:        i = SL(n);
                    526:        if ( i < 0 ) i = -i;
                    527:        for ( i--, x = BD(n)+i, r = 0; i >= 0; i--, x-- ) {
                    528: #if defined(sparc)
                    529:                r = dsa(m,r,*x);
                    530: #else
                    531:                DSAB(m,r,*x,t,r);
                    532: #endif
                    533:        }
1.5     ! noro      534:        if ( r && SL(n) < 0 )
        !           535:                r = m-r;
1.1       noro      536:        return r;
                    537: }
                    538:
                    539: Z gcdz_cofactor(Z n1,Z n2,Z *c1,Z *c2)
                    540: {
                    541:        Z gcd;
                    542:
                    543:        gcd = gcdz(n1,n2);
                    544:        *c1 = divsz(n1,gcd);
                    545:        *c2 = divsz(n2,gcd);
                    546:        return gcd;
                    547: }
                    548:
1.5     ! noro      549: #if 0
1.1       noro      550: Z estimate_array_gcdz(Z *b,int n)
                    551: {
                    552:        int m,i,j,sd;
                    553:        Z *a;
                    554:        Z s,t;
                    555:
                    556:        a = (Z *)ALLOCA(n*sizeof(Z));
                    557:        for ( i = j = 0; i < n; i++ ) if ( b[i] ) a[j++] = b[i];
                    558:        n = j;
                    559:        if ( !n ) return 0;
                    560:        if ( n == 1 ) return a[0];
                    561:
                    562:        m = n/2;
                    563:        for ( i = 0, s = 0; i < m; i++ ) {
                    564:                if ( !a[i] ) continue;
                    565:                else s = (SL(a[i])<0)?subz(s,a[i]):addz(s,a[i]);
                    566:        }
                    567:        for ( t = 0; i < n; i++ ) {
                    568:                if ( !a[i] ) continue;
                    569:                else t = (SL(a[i])<0)?subz(t,a[i]):addz(t,a[i]);
                    570:        }
                    571:        return gcdz(s,t);
                    572: }
                    573:
                    574: Z array_gcdz(Z *b,int n)
                    575: {
                    576:        int m,i,j,sd;
                    577:        Z *a;
                    578:        Z gcd;
                    579:
                    580:        a = (Z *)ALLOCA(n*sizeof(Z));
                    581:        for ( i = j = 0; i < n; i++ ) if ( b[i] ) a[j++] = b[i];
                    582:        n = j;
                    583:        if ( !n ) return 0;
                    584:        if ( n == 1 ) return a[0];
                    585:        gcd = a[0];
                    586:        for ( i = 1; i < n; i++ )
                    587:                gcd = gcdz(gcd,a[i]);
                    588:        return gcd;
                    589: }
1.4       noro      590: #endif
1.1       noro      591:
                    592: void _copyz(Z n1,Z n2)
                    593: {
                    594:        int n,i;
                    595:
                    596:        if ( !n1 || !SL(n1) ) SL(n2) = 0;
                    597:        else {
                    598:                n = SL(n2) = SL(n1);
                    599:                if ( n < 0 ) n = -n;
                    600:                for ( i = 0; i < n; i++ ) BD(n2)[i] = BD(n1)[i];
                    601:        }
                    602: }
                    603:
                    604: void _addz(Z n1,Z n2,Z nr)
                    605: {
1.3       noro      606:        int d1,d2;
1.1       noro      607:
                    608:        if ( !n1 || !SL(n1) ) _copyz(n2,nr);
                    609:        else if ( !n2 || !SL(n2) ) _copyz(n1,nr);
1.3       noro      610:        else if ( (d1=SL(n1)) > 0 )
                    611:                if ( (d2=SL(n2)) > 0 )
                    612:                        SL(nr) = _addz_main(BD(n1),d1,BD(n2),d2,BD(nr));
1.1       noro      613:                else
1.3       noro      614:                        SL(nr) = _subz_main(BD(n1),d1,BD(n2),-d2,BD(nr));
                    615:        else if ( (d2=SL(n2)) > 0 )
                    616:                SL(nr) = _subz_main(BD(n2),d2,BD(n1),-d1,BD(nr));
1.1       noro      617:        else
1.3       noro      618:                SL(nr) = -_addz_main(BD(n1),-d1,BD(n2),-d2,BD(nr));
1.1       noro      619: }
                    620:
                    621: void _subz(Z n1,Z n2,Z nr)
                    622: {
1.3       noro      623:        int d1,d2;
1.1       noro      624:
                    625:        if ( !n1 || !SL(n1) ) _copyz(n2,nr);
                    626:        else if ( !n2 || !SL(n2) ) {
                    627:                _copyz(n1,nr);
                    628:                SL(nr) = -SL(nr);
1.3       noro      629:        } else if ( (d1=SL(n1)) > 0 )
                    630:                if ( (d2=SL(n2)) > 0 )
                    631:                        SL(nr) = _subz_main(BD(n1),d1,BD(n2),d2,BD(nr));
1.1       noro      632:                else
1.3       noro      633:                        SL(nr) = _addz_main(BD(n1),d1,BD(n2),-d2,BD(nr));
                    634:        else if ( (d2=SL(n2)) > 0 )
                    635:                SL(nr) = -_addz_main(BD(n1),-d1,BD(n2),d2,BD(nr));
1.1       noro      636:        else
1.3       noro      637:                SL(nr) = -_subz_main(BD(n1),-d1,BD(n2),-d2,BD(nr));
1.1       noro      638: }
                    639:
                    640: void _mulz(Z n1,Z n2,Z nr)
                    641: {
1.3       noro      642:        int d1,d2;
1.1       noro      643:        int i,d,sgn;
                    644:        unsigned int mul;
                    645:        unsigned int *m1,*m2;
                    646:
                    647:        if ( !n1 || !SL(n1) || !n2 || !SL(n2) )
                    648:                SL(nr) = 0;
                    649:        else {
1.3       noro      650:                d1 = SL(n1); d2 = SL(n2);
1.1       noro      651:                sgn = 1;
1.3       noro      652:                if ( d1 < 0 ) { sgn = -sgn; d1 = -d1; }
                    653:                if ( d2 < 0 ) { sgn = -sgn; d2 = -d2; }
                    654:                d = d1+d2;
1.1       noro      655:                for ( i = d-1, m1 = BD(nr); i >= 0; i-- ) *m1++ = 0;
1.3       noro      656:                for ( i = 0, m1 = BD(n1), m2 = BD(n2); i < d2; i++, m2++ )
                    657:                        if ( mul = *m2 ) muln_1(m1,d1,mul,BD(nr)+i);
1.1       noro      658:                SL(nr) = sgn*(BD(nr)[d-1]?d:d-1);
                    659:        }
                    660: }
                    661:
                    662: int _addz_main(unsigned int *m1,int d1,unsigned int *m2,int d2,unsigned int *mr)
                    663: {
                    664:        int d,i;
                    665:        unsigned int tmp,c;
                    666:        unsigned int *t;
                    667:
                    668:        if ( d2 > d1 ) {
                    669:                t = m1; m1 = m2; m2 = t;
                    670:                d = d1; d1 = d2; d2 = d;
                    671:        }
                    672: #if defined(VISUAL)
                    673:        __asm {
                    674:        push    esi
                    675:        push    edi
                    676:        mov esi,m1
                    677:        mov edi,m2
                    678:        mov ebx,mr
                    679:        mov ecx,d2
                    680:        xor     eax,eax
                    681:        Lstart__addz:
                    682:        mov eax,DWORD PTR [esi]
                    683:        mov edx,DWORD PTR [edi]
                    684:        adc eax,edx
                    685:        mov DWORD PTR [ebx],eax
                    686:        lea esi,DWORD PTR [esi+4]
                    687:        lea edi,DWORD PTR [edi+4]
                    688:        lea ebx,DWORD PTR [ebx+4]
                    689:        dec ecx
                    690:        jnz Lstart__addz
                    691:        pop     edi
                    692:        pop     esi
                    693:        mov eax,0
                    694:        adc eax,eax
                    695:        mov c,eax
                    696:        }
                    697: #elif defined(i386)
                    698:        asm volatile("\
                    699:        movl    %1,%%esi;\
                    700:        movl    %2,%%edi;\
                    701:        movl    %3,%%ebx;\
                    702:        movl    %4,%%ecx;\
                    703:        testl   %%eax,%%eax;\
                    704:        Lstart__addz:;\
                    705:        movl    (%%esi),%%eax;\
                    706:        movl    (%%edi),%%edx;\
                    707:        adcl    %%edx,%%eax;\
                    708:        movl    %%eax,(%%ebx);\
                    709:        leal    4(%%esi),%%esi;\
                    710:        leal    4(%%edi),%%edi;\
                    711:        leal    4(%%ebx),%%ebx;\
                    712:        decl    %%ecx;\
                    713:        jnz Lstart__addz;\
                    714:        movl    $0,%%eax;\
                    715:        adcl    %%eax,%%eax;\
                    716:        movl    %%eax,%0"\
                    717:        :"=m"(c)\
                    718:        :"m"(m1),"m"(m2),"m"(mr),"m"(d2)\
                    719:        :"eax","ebx","ecx","edx","esi","edi");
                    720: #else
                    721:        for ( i = 0, c = 0, mr = BD(nr); i < d2; i++, m1++, m2++, mr++ ) {
                    722:                tmp = *m1 + *m2;
                    723:                if ( tmp < *m1 ) {
                    724:                        tmp += c;
                    725:                        c = 1;
                    726:                } else {
                    727:                        tmp += c;
                    728:                        c = tmp < c ? 1 : 0;
                    729:                }
                    730:                *mr = tmp;
                    731:        }
                    732: #endif
                    733:        for ( i = d2, m1 += d2, mr += d2; (i < d1) && c ; i++ ) {
                    734:                tmp = *m1++ + c;
                    735:                c = tmp < c ? 1 : 0;
                    736:                *mr++ = tmp;
                    737:        }
                    738:        for ( ; i < d1; i++ )
                    739:                        *mr++ = *m1++;
                    740:        *mr = c;
                    741:        return (c?d1+1:d1);
                    742: }
                    743:
                    744: int _subz_main(unsigned int *m1,int d1,unsigned int *m2,int d2,unsigned int *mr)
                    745: {
                    746:        int d,i,sgn;
                    747:        unsigned int t,tmp,br;
                    748:        unsigned int *m;
                    749:
                    750:        if ( d1 > d2 ) sgn = 1;
                    751:        else if ( d1 < d2 ) sgn = -1;
                    752:        else {
                    753:                for ( i = d1-1; i >= 0 && m1[i] == m2[i]; i-- );
                    754:                if ( i < 0 ) return 0;
                    755:                if ( m1[i] > m2[i] ) sgn = 1;
                    756:                else if ( m1[i] < m2[i] ) sgn = -1;
                    757:        }
                    758:        if ( sgn < 0 ) {
                    759:                m = m1; m1 = m2; m2 = m;
                    760:                d = d1; d1 = d2; d2 = d;
                    761:        }
                    762: #if defined(VISUAL)
                    763:        __asm {
                    764:        push    esi
                    765:        push    edi
                    766:        mov esi,m1
                    767:        mov edi,m2
                    768:        mov ebx,mr
                    769:        mov ecx,d2
                    770:        xor     eax,eax
                    771:        Lstart__subz:
                    772:        mov eax,DWORD PTR [esi]
                    773:        mov edx,DWORD PTR [edi]
                    774:        sbb eax,edx
                    775:        mov DWORD PTR [ebx],eax
                    776:        lea esi,DWORD PTR [esi+4]
                    777:        lea edi,DWORD PTR [edi+4]
                    778:        lea ebx,DWORD PTR [ebx+4]
                    779:        dec ecx
                    780:        jnz Lstart__subz
                    781:        pop     edi
                    782:        pop     esi
                    783:        mov eax,0
                    784:        adc eax,eax
                    785:        mov br,eax
                    786:        }
                    787: #elif defined(i386)
                    788:        asm volatile("\
                    789:        movl    %1,%%esi;\
                    790:        movl    %2,%%edi;\
                    791:        movl    %3,%%ebx;\
                    792:        movl    %4,%%ecx;\
                    793:        testl   %%eax,%%eax;\
                    794:        Lstart__subz:;\
                    795:        movl    (%%esi),%%eax;\
                    796:        movl    (%%edi),%%edx;\
                    797:        sbbl    %%edx,%%eax;\
                    798:        movl    %%eax,(%%ebx);\
                    799:        leal    4(%%esi),%%esi;\
                    800:        leal    4(%%edi),%%edi;\
                    801:        leal    4(%%ebx),%%ebx;\
                    802:        decl    %%ecx;\
                    803:        jnz Lstart__subz;\
                    804:        movl    $0,%%eax;\
                    805:        adcl    %%eax,%%eax;\
                    806:        movl    %%eax,%0"\
                    807:        :"=m"(br)\
                    808:        :"m"(m1),"m"(m2),"m"(mr),"m"(d2)\
                    809:        :"eax","ebx","ecx","edx","esi","edi");
                    810: #else
                    811:        for ( i = 0, br = 0, mr = BD(nr); i < d2; i++, mr++ ) {
                    812:                t = *m1++;
                    813:                tmp = *m2++ + br;
                    814:                if ( br > 0 && !tmp ) {
                    815:                        /* tmp = 2^32 => br = 1 */
                    816:                }else {
                    817:                        tmp = t-tmp;
                    818:                        br = tmp > t ? 1 : 0;
                    819:                        *mr = tmp;
                    820:                }
                    821:        }
                    822: #endif
                    823:        for ( i = d2, m1 += d2, mr += d2; (i < d1) && br; i++ ) {
                    824:                t = *m1++;
                    825:                tmp = t - br;
                    826:                br = tmp > t ? 1 : 0;
                    827:                *mr++ = tmp;
                    828:        }
                    829:        for ( ; i < d1; i++ )
                    830:                *mr++ = *m1++;
                    831:        for ( i = d1-1, mr--; i >= 0 && !*mr--; i-- );
                    832:        return sgn*(i+1);
                    833: }
                    834:
                    835: /* XXX */
                    836:
                    837: void printz(Z n)
                    838: {
1.4       noro      839:        int sd,u;
1.1       noro      840:
                    841:        if ( !n )
                    842:                fprintf(asir_out,"0");
1.4       noro      843:        else if ( IS_IMM(n) ) {
1.5     ! noro      844:                u = ZTOS(n);
1.4       noro      845:                fprintf(asir_out,"%d",u);
                    846:        } else {
1.1       noro      847:                if ( (sd = SL(n)) < 0 ) { SL(n) = -SL(n); fprintf(asir_out,"-"); }
                    848:                printn((N)n);
                    849:                if ( sd < 0 ) SL(n) = -SL(n);
1.2       noro      850:        }
                    851: }
                    852:
                    853: /*
                    854:  *  Dx^k*x^l = W(k,l,0)*x^l*Dx^k+W(k,l,1)*x^(l-1)*x^(k-1)*+...
                    855:  *
                    856:  *  t = [W(k,l,0) W(k,l,1) ... W(k,l,min(k,l)]
                    857:  *  where W(k,l,i) = i! * kCi * lCi
                    858:  */
                    859:
                    860: void mkwcz(int k,int l,Z *t)
                    861: {
                    862:        int i,n,up,low;
                    863:        N nm,d,c;
                    864:
                    865:        n = MIN(k,l);
                    866:        for ( t[0] = (Z)ONEN, i = 1; i <= n; i++ ) {
                    867:                DM(k-i+1,l-i+1,up,low);
                    868:                if ( up ) {
                    869:                        nm = NALLOC(2); PL(nm) = 2; BD(nm)[0] = low; BD(nm)[1] = up;
                    870:                } else {
                    871:                        nm = NALLOC(1); PL(nm) = 1; BD(nm)[0] = low;
                    872:                }
                    873:                kmuln((N)t[i-1],nm,&d); divin(d,i,&c); t[i] = (Z)c;
1.1       noro      874:        }
                    875: }

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