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

Annotation of OpenXM_contrib2/asir2000/builtin/int.c, Revision 1.1.1.1

1.1       noro        1: /* $OpenXM: OpenXM/src/asir99/builtin/int.c,v 1.1.1.1 1999/11/10 08:12:25 noro Exp $ */
                      2: #include "ca.h"
                      3: #include "parse.h"
                      4: #include "base.h"
                      5:
                      6: void Pidiv(), Pirem(), Pigcd(), Pilcm(), Pfac(), Prandom(), Pinv();
                      7: void Pup2_inv(),Pgf2nton(), Pntogf2n();
                      8: void Pup2_init_eg(), Pup2_show_eg();
                      9: void Piqr(), Pprime(), Plprime(), Pinttorat();
                     10: void Piand(), Pior(), Pixor(), Pishift();
                     11: void Pisqrt();
                     12: void iand(), ior(), ixor();
                     13: void isqrt();
                     14: void Plrandom();
                     15: void Pset_upkara(), Pset_uptkara(), Pset_up2kara(), Pset_upfft();
                     16: void Pmt_save(), Pmt_load();
                     17: void Psmall_jacobi();
                     18: void Pdp_set_mpi();
                     19:
                     20: #ifdef HMEXT
                     21: void Pigcdbin(), Pigcdbmod(), PigcdEuc(), Pigcdacc(), Pigcdcntl();
                     22:
                     23: void Pihex();
                     24: void Pimaxrsh(), Pilen();
                     25: void Ptype_t_NB();
                     26:
                     27: #endif /* HMEXT */
                     28:
                     29: struct ftab int_tab[] = {
                     30:        {"dp_set_mpi",Pdp_set_mpi,-1},
                     31:        {"isqrt",Pisqrt,1},
                     32:        {"idiv",Pidiv,2},
                     33:        {"irem",Pirem,2},
                     34:        {"iqr",Piqr,2},
                     35:        {"igcd",Pigcd,-2},
                     36:        {"ilcm",Pilcm,2},
                     37:        {"up2_inv",Pup2_inv,2},
                     38:        {"up2_init_eg",Pup2_init_eg,0},
                     39:        {"up2_show_eg",Pup2_show_eg,0},
                     40:        {"type_t_NB",Ptype_t_NB,2},
                     41:        {"gf2nton",Pgf2nton,1},
                     42:        {"ntogf2n",Pntogf2n,1},
                     43:        {"set_upkara",Pset_upkara,-1},
                     44:        {"set_uptkara",Pset_uptkara,-1},
                     45:        {"set_up2kara",Pset_up2kara,-1},
                     46:        {"set_upfft",Pset_upfft,-1},
                     47:        {"inv",Pinv,2},
                     48:        {"inttorat",Pinttorat,3},
                     49:        {"fac",Pfac,1},
                     50:        {"prime",Pprime,1},
                     51:        {"lprime",Plprime,1},
                     52:        {"random",Prandom,-1},
                     53:        {"lrandom",Plrandom,1},
                     54:        {"iand",Piand,2},
                     55:        {"ior",Pior,2},
                     56:        {"ixor",Pixor,2},
                     57:        {"ishift",Pishift,2},
                     58:        {"small_jacobi",Psmall_jacobi,2},
                     59: #ifdef HMEXT
                     60:        {"igcdbin",Pigcdbin,2},         /* HM@CCUT extension */
                     61:        {"igcdbmod",Pigcdbmod,2},       /* HM@CCUT extension */
                     62:        {"igcdeuc",PigcdEuc,2},         /* HM@CCUT extension */
                     63:        {"igcdacc",Pigcdacc,2},         /* HM@CCUT extension */
                     64:        {"igcdcntl",Pigcdcntl,-1},      /* HM@CCUT extension */
                     65:        {"ihex",Pihex,1},       /* HM@CCUT extension */
                     66:        {"imaxrsh",Pimaxrsh,1}, /* HM@CCUT extension */
                     67:        {"ilen",Pilen,1},       /* HM@CCUT extension */
                     68: #endif /* HMEXT */
                     69:        {"mt_save",Pmt_save,1},
                     70:        {"mt_load",Pmt_load,1},
                     71:        {0,0,0},
                     72: };
                     73:
                     74: static int is_prime_small(unsigned int);
                     75: static unsigned int gcd_small(unsigned int,unsigned int);
                     76: int TypeT_NB_check(unsigned int, unsigned int);
                     77: int mpi_mag;
                     78:
                     79: void Pdp_set_mpi(arg,rp)
                     80: NODE arg;
                     81: Q *rp;
                     82: {
                     83:        if ( arg ) {
                     84:                asir_assert(ARG0(arg),O_N,"dp_set_mpi");
                     85:                mpi_mag = QTOS((Q)ARG0(arg));
                     86:        }
                     87:        STOQ(mpi_mag,*rp);
                     88: }
                     89:
                     90: void Psmall_jacobi(arg,rp)
                     91: NODE arg;
                     92: Q *rp;
                     93: {
                     94:        Q a,m;
                     95:        int a0,m0,s;
                     96:
                     97:        a = (Q)ARG0(arg);
                     98:        m = (Q)ARG1(arg);
                     99:        asir_assert(a,O_N,"small_jacobi");
                    100:        asir_assert(m,O_N,"small_jacobi");
                    101:        if ( !a )
                    102:                 *rp = ONE;
                    103:        else if ( !m || !INT(m) || !INT(a)
                    104:                || PL(NM(m))>1 || PL(NM(a))>1 || SGN(m) < 0 || EVENN(NM(m)) )
                    105:                error("small_jacobi : invalid input");
                    106:        else {
                    107:                a0 = QTOS(a); m0 = QTOS(m);
                    108:                s = small_jacobi(a0,m0);
                    109:                STOQ(s,*rp);
                    110:        }
                    111: }
                    112:
                    113: int small_jacobi(a,m)
                    114: int a,m;
                    115: {
                    116:        int m4,m8,a4,j1,i,s;
                    117:
                    118:        a %= m;
                    119:        if ( a == 0 || a == 1 )
                    120:                return 1;
                    121:        else if ( a < 0 ) {
                    122:                j1 = small_jacobi(-a,m);
                    123:                m4 = m%4;
                    124:                return m4==1?j1:-j1;
                    125:        } else {
                    126:                for ( i = 0; a && !(a&1); i++, a >>= 1 );
                    127:                if ( i&1 ) {
                    128:                        m8 = m%8;
                    129:                        s = (m8==1||m8==7) ? 1 : -1;
                    130:                } else
                    131:                        s = 1;
                    132:                /* a, m are odd */
                    133:                j1 = small_jacobi(m%a,a);
                    134:                m4 = m%4; a4 = a%4;
                    135:                s *= (m4==1||a4==1) ? 1 : -1;
                    136:                return j1*s;
                    137:        }
                    138: }
                    139:
                    140: void Ptype_t_NB(arg,rp)
                    141: NODE arg;
                    142: Q *rp;
                    143: {
                    144:        if ( TypeT_NB_check(QTOS((Q)ARG0(arg)),QTOS((Q)ARG1(arg))))
                    145:                *rp = ONE;
                    146:        else
                    147:                *rp = 0;
                    148: }
                    149:
                    150: int TypeT_NB_check(unsigned int m, unsigned int t)
                    151: {
                    152:        unsigned int p,k,u,h,d;
                    153:
                    154:        if ( !(m%8) )
                    155:                return 0;
                    156:        p = t*m+1;
                    157:        if ( !is_prime_small(p) )
                    158:                return 0;
                    159:        for ( k = 1, u = 2%p; ; k++ )
                    160:                if ( u == 1 )
                    161:                        break;
                    162:                else
                    163:                        u = (2*u)%p;
                    164:        h = t*m/k;
                    165:        d = gcd_small(h,m);
                    166:        return d == 1 ? 1 : 0;
                    167: }
                    168:
                    169: /*
                    170:  * a simple prime checker
                    171:  * return value: 1  ---  prime number
                    172:  *               0  ---  composite number
                    173:  */
                    174:
                    175: static int is_prime_small(unsigned int a)
                    176: {
                    177:        unsigned int b,t,i;
                    178:
                    179:        if ( !(a%2) ) return 0;
                    180:        for ( t = a, i = 0; t; i++, t >>= 1 );
                    181:        /* b >= sqrt(a) */
                    182:        b = 1<<((i+1)/2);
                    183:
                    184:        /* divisibility test by all odd numbers <= b */
                    185:        for ( i = 3; i <= b; i += 2 )
                    186:                if ( !(a%i) )
                    187:                        return 0;
                    188:        return 1;
                    189: }
                    190:
                    191: /*
                    192:  * gcd for unsigned int as integers
                    193:  * return value: GCD(a,b)
                    194:  *
                    195:  */
                    196:
                    197:
                    198: static unsigned int gcd_small(unsigned int a,unsigned int b)
                    199: {
                    200:        unsigned int t;
                    201:
                    202:        if ( b > a ) {
                    203:                t = a; a = b; b = t;
                    204:        }
                    205:        /* Euclid's algorithm */
                    206:        while ( 1 )
                    207:                if ( !(t = a%b) ) return b;
                    208:                else {
                    209:                        a = b; b = t;
                    210:                }
                    211: }
                    212:
                    213: void Pmt_save(arg,rp)
                    214: NODE arg;
                    215: Q *rp;
                    216: {
                    217:        int ret;
                    218:
                    219:        ret = mt_save(BDY((STRING)ARG0(arg)));
                    220:        STOQ(ret,*rp);
                    221: }
                    222:
                    223: void Pmt_load(arg,rp)
                    224: NODE arg;
                    225: Q *rp;
                    226: {
                    227:        int ret;
                    228:
                    229:        ret = mt_load(BDY((STRING)ARG0(arg)));
                    230:        STOQ(ret,*rp);
                    231: }
                    232:
                    233: void Pisqrt(arg,rp)
                    234: NODE arg;
                    235: Q *rp;
                    236: {
                    237:        Q a;
                    238:        N r;
                    239:
                    240:        a = (Q)ARG0(arg);
                    241:        asir_assert(a,O_N,"isqrt");
                    242:        if ( !a )
                    243:                *rp = 0;
                    244:        else if ( SGN(a) < 0 )
                    245:                error("isqrt : negative argument");
                    246:        else {
                    247:                isqrt(NM(a),&r);
                    248:                NTOQ(r,1,*rp);
                    249:        }
                    250: }
                    251:
                    252: void Pidiv(arg,rp)
                    253: NODE arg;
                    254: Obj *rp;
                    255: {
                    256:        N q,r;
                    257:        Q a;
                    258:        Q dnd,dvr;
                    259:
                    260:        dnd = (Q)ARG0(arg); dvr = (Q)ARG1(arg);
                    261:        asir_assert(dnd,O_N,"idiv");
                    262:        asir_assert(dvr,O_N,"idiv");
                    263:        if ( !dvr )
                    264:                error("idiv: division by 0");
                    265:        else if ( !dnd )
                    266:                *rp = 0;
                    267:        else {
                    268:                divn(NM(dnd),NM(dvr),&q,&r);
                    269:                NTOQ(q,SGN(dnd)*SGN(dvr),a); *rp = (Obj)a;
                    270:        }
                    271: }
                    272:
                    273: void Pirem(arg,rp)
                    274: NODE arg;
                    275: Obj *rp;
                    276: {
                    277:        N q,r;
                    278:        Q a;
                    279:        Q dnd,dvr;
                    280:
                    281:        dnd = (Q)ARG0(arg); dvr = (Q)ARG1(arg);
                    282:        asir_assert(dnd,O_N,"irem");
                    283:        asir_assert(dvr,O_N,"irem");
                    284:        if ( !dvr )
                    285:                error("irem: division by 0");
                    286:        else if ( !dnd )
                    287:                *rp = 0;
                    288:        else {
                    289:                divn(NM(dnd),NM(dvr),&q,&r);
                    290:                NTOQ(r,SGN(dnd),a); *rp = (Obj)a;
                    291:        }
                    292: }
                    293:
                    294: void Piqr(arg,rp)
                    295: NODE arg;
                    296: LIST *rp;
                    297: {
                    298:        N q,r;
                    299:        Q a,b;
                    300:        Q dnd,dvr;
                    301:        NODE node1,node2;
                    302:
                    303:        dnd = (Q)ARG0(arg); dvr = (Q)ARG1(arg);
                    304:        if ( !dvr )
                    305:                error("iqr: division by 0");
                    306:        else if ( !dnd )
                    307:                a = b = 0;
                    308:        else if ( OID(dnd) == O_VECT ) {
                    309:                iqrv((VECT)dnd,dvr,rp); return;
                    310:        } else {
                    311:                asir_assert(dnd,O_N,"iqr");
                    312:                asir_assert(dvr,O_N,"iqr");
                    313:                divn(NM(dnd),NM(dvr),&q,&r);
                    314:                NTOQ(q,SGN(dnd)*SGN(dvr),a);
                    315:                NTOQ(r,SGN(dnd),b);
                    316:        }
                    317:        MKNODE(node2,b,0); MKNODE(node1,a,node2); MKLIST(*rp,node1);
                    318: }
                    319:
                    320: void Pinttorat(arg,rp)
                    321: NODE arg;
                    322: LIST *rp;
                    323: {
                    324:        Q cq,qq,t,u1,v1,r1,nm;
                    325:        N m,b,q,r,c,u2,v2,r2;
                    326:        NODE node1,node2;
                    327:        P p;
                    328:
                    329:        asir_assert(ARG0(arg),O_N,"inttorat");
                    330:        asir_assert(ARG1(arg),O_N,"inttorat");
                    331:        asir_assert(ARG2(arg),O_N,"inttorat");
                    332:        cq = (Q)ARG0(arg); m = NM((Q)ARG1(arg)); b = NM((Q)ARG2(arg));
                    333:        if ( !cq ) {
                    334:                MKNODE(node2,(pointer)ONE,0); MKNODE(node1,0,node2); MKLIST(*rp,node1);
                    335:                return;
                    336:        }
                    337:        divn(NM(cq),m,&q,&r);
                    338:        if ( !r ) {
                    339:                MKNODE(node2,(pointer)ONE,0); MKNODE(node1,0,node2); MKLIST(*rp,node1);
                    340:                return;
                    341:        } else if ( SGN(cq) < 0 ) {
                    342:                subn(m,r,&c);
                    343:        } else
                    344:                c = r;
                    345:        u1 = 0; v1 = ONE; u2 = m; v2 = c;
                    346:        while ( cmpn(v2,b) >= 0 ) {
                    347:                divn(u2,v2,&q,&r2); u2 = v2; v2 = r2;
                    348:                NTOQ(q,1,qq); mulq(qq,v1,&t); subq(u1,t,&r1); u1 = v1; v1 = r1;
                    349:        }
                    350:        if ( cmpn(NM(v1),b) >= 0 )
                    351:                *rp = 0;
                    352:        else {
                    353:                if ( SGN(v1) < 0 ) {
                    354:                        chsgnp((P)v1,&p); v1 = (Q)p; NTOQ(v2,-1,nm);
                    355:                } else
                    356:                        NTOQ(v2,1,nm);
                    357:                MKNODE(node2,v1,0); MKNODE(node1,nm,node2); MKLIST(*rp,node1);
                    358:        }
                    359: }
                    360:
                    361: void Pigcd(arg,rp)
                    362: NODE arg;
                    363: Q *rp;
                    364: {
                    365:        N g;
                    366:        Q n1,n2,a;
                    367:
                    368:        if ( argc(arg) == 1 ) {
                    369:                igcdv((VECT)ARG0(arg),rp);
                    370:                return;
                    371:        }
                    372:        n1 = (Q)ARG0(arg); n2 = (Q)ARG1(arg);
                    373:        asir_assert(n1,O_N,"igcd");
                    374:        asir_assert(n2,O_N,"igcd");
                    375:        if ( !n1 )
                    376:                *rp = n2;
                    377:        else if ( !n2 )
                    378:                *rp = n1;
                    379:        else {
                    380:                gcdn(NM(n1),NM(n2),&g);
                    381:                NTOQ(g,1,a); *rp = a;
                    382:        }
                    383: }
                    384:
                    385: int comp_n(a,b)
                    386: N *a,*b;
                    387: {
                    388:        return cmpn(*a,*b);
                    389: }
                    390:
                    391: void iqrv(a,dvr,rp)
                    392: VECT a;
                    393: Q dvr;
                    394: LIST *rp;
                    395: {
                    396:        int i,n;
                    397:        VECT q,r;
                    398:        Q dnd,qi,ri;
                    399:        Q *b;
                    400:        N qn,rn;
                    401:        NODE n0,n1;
                    402:
                    403:        if ( !dvr )
                    404:                error("iqrv: division by 0");
                    405:        n = a->len; b = (Q *)BDY(a);
                    406:        MKVECT(q,n); MKVECT(r,n);
                    407:        for ( i = 0; i < n; i++ ) {
                    408:                dnd = b[i];
                    409:                if ( !dnd ) {
                    410:                        qi = ri = 0;
                    411:                } else {
                    412:                        divn(NM(dnd),NM(dvr),&qn,&rn);
                    413:                        NTOQ(qn,SGN(dnd)*SGN(dvr),qi);
                    414:                        NTOQ(rn,SGN(dnd),ri);
                    415:                }
                    416:                BDY(q)[i] = (pointer)qi; BDY(r)[i] = (pointer)ri;
                    417:        }
                    418:        MKNODE(n1,r,0); MKNODE(n0,q,n1); MKLIST(*rp,n0);
                    419: }
                    420:
                    421: void igcdv(a,rp)
                    422: VECT a;
                    423: Q *rp;
                    424: {
                    425:        int i,j,n,nz;
                    426:        N g,gt,q,r;
                    427:        N *c;
                    428:
                    429:        n = a->len;
                    430:        c = (N *)ALLOCA(n*sizeof(N));
                    431:        for ( i = 0; i < n; i++ )
                    432:                c[i] = BDY(a)[i]?NM((Q)(BDY(a)[i])):0;
                    433:        qsort(c,n,sizeof(N),(int (*) (const void *,const void *))comp_n);
                    434:        for ( ; n && ! *c; n--, c++ );
                    435:
                    436:        if ( !n ) {
                    437:                *rp = 0; return;
                    438:        } else if ( n == 1 ) {
                    439:                NTOQ(*c,1,*rp); return;
                    440:        }
                    441:        gcdn(c[0],c[1],&g);
                    442:        for ( i = 2; i < n; i++ ) {
                    443:                divn(c[i],g,&q,&r);
                    444:                gcdn(g,r,&gt);
                    445:                if ( !cmpn(g,gt) ) {
                    446:                        for ( j = i+1, nz = 0; j < n; j++ ) {
                    447:                                divn(c[j],g,&q,&r); c[j] = r;
                    448:                                if ( r )
                    449:                                        nz = 1;
                    450:                        }
                    451:                } else
                    452:                        g = gt;
                    453:        }
                    454:        NTOQ(g,1,*rp);
                    455: }
                    456:
                    457: void igcdv_estimate(a,rp)
                    458: VECT a;
                    459: Q *rp;
                    460: {
                    461:        int n,i,m;
                    462:        N s,t,u,g;
                    463:        Q *q;
                    464:
                    465:        n = a->len; q = (Q *)a->body;
                    466:        if ( n == 1 ) {
                    467:                NTOQ(NM(q[0]),1,*rp); return;
                    468:        }
                    469:
                    470:        m = n/2;
                    471:        for ( i = 0 , s = 0; i < m; i++ ) {
                    472:                addn(s,NM(q[i]),&u); s = u;
                    473:        }
                    474:        for ( t = 0; i < n; i++ ) {
                    475:                addn(t,NM(q[i]),&u); t = u;
                    476:        }
                    477:        gcdn(s,t,&g); NTOQ(g,1,*rp);
                    478: }
                    479:
                    480: void Pilcm(arg,rp)
                    481: NODE arg;
                    482: Obj *rp;
                    483: {
                    484:        N g,q,r,l;
                    485:        Q n1,n2,a;
                    486:
                    487:        n1 = (Q)ARG0(arg); n2 = (Q)ARG1(arg);
                    488:        asir_assert(n1,O_N,"ilcm");
                    489:        asir_assert(n2,O_N,"ilcm");
                    490:        if ( !n1 || !n2 )
                    491:                *rp = 0;
                    492:        else {
                    493:                gcdn(NM(n1),NM(n2),&g); divn(NM(n1),g,&q,&r);
                    494:                muln(q,NM(n2),&l); NTOQ(l,1,a); *rp = (Obj)a;
                    495:        }
                    496: }
                    497:
                    498: void Piand(arg,rp)
                    499: NODE arg;
                    500: Q *rp;
                    501: {
                    502:        N g;
                    503:        Q n1,n2,a;
                    504:
                    505:        n1 = (Q)ARG0(arg); n2 = (Q)ARG1(arg);
                    506:        asir_assert(n1,O_N,"iand");
                    507:        asir_assert(n2,O_N,"iand");
                    508:        if ( !n1 || !n2 )
                    509:                *rp = 0;
                    510:        else {
                    511:                iand(NM(n1),NM(n2),&g);
                    512:                NTOQ(g,1,a); *rp = a;
                    513:        }
                    514: }
                    515:
                    516: void Pior(arg,rp)
                    517: NODE arg;
                    518: Q *rp;
                    519: {
                    520:        N g;
                    521:        Q n1,n2,a;
                    522:
                    523:        n1 = (Q)ARG0(arg); n2 = (Q)ARG1(arg);
                    524:        asir_assert(n1,O_N,"ior");
                    525:        asir_assert(n2,O_N,"ior");
                    526:        if ( !n1 )
                    527:                *rp = n2;
                    528:        else if ( !n2 )
                    529:                *rp = n1;
                    530:        else {
                    531:                ior(NM(n1),NM(n2),&g);
                    532:                NTOQ(g,1,a); *rp = a;
                    533:        }
                    534: }
                    535:
                    536: void Pixor(arg,rp)
                    537: NODE arg;
                    538: Q *rp;
                    539: {
                    540:        N g;
                    541:        Q n1,n2,a;
                    542:
                    543:        n1 = (Q)ARG0(arg); n2 = (Q)ARG1(arg);
                    544:        asir_assert(n1,O_N,"ixor");
                    545:        asir_assert(n2,O_N,"ixor");
                    546:        if ( !n1 )
                    547:                *rp = n2;
                    548:        else if ( !n2 )
                    549:                *rp = n1;
                    550:        else {
                    551:                ixor(NM(n1),NM(n2),&g);
                    552:                NTOQ(g,1,a); *rp = a;
                    553:        }
                    554: }
                    555:
                    556: void Pishift(arg,rp)
                    557: NODE arg;
                    558: Q *rp;
                    559: {
                    560:        N g;
                    561:        Q n1,s,a;
                    562:
                    563:        n1 = (Q)ARG0(arg); s = (Q)ARG1(arg);
                    564:        asir_assert(n1,O_N,"ixor");
                    565:        asir_assert(s,O_N,"ixor");
                    566:        if ( !n1 )
                    567:                *rp = 0;
                    568:        else if ( !s )
                    569:                *rp = n1;
                    570:        else {
                    571:                bshiftn(NM(n1),QTOS(s),&g);
                    572:                NTOQ(g,1,a); *rp = a;
                    573:        }
                    574: }
                    575:
                    576: void isqrt(a,r)
                    577: N a,*r;
                    578: {
                    579:        int k;
                    580:        N x,t,x2,xh,quo,rem;
                    581:
                    582:        if ( !a )
                    583:                *r = 0;
                    584:        else if ( UNIN(a) )
                    585:                *r = ONEN;
                    586:        else {
                    587:                k = n_bits(a); /* a <= 2^k-1 */
                    588:                bshiftn(ONEN,-((k>>1)+(k&1)),&x); /* a <= x^2 */
                    589:                while ( 1 ) {
                    590:                        pwrn(x,2,&t);
                    591:                        if ( cmpn(t,a) <= 0 ) {
                    592:                                *r = x; return;
                    593:                        } else {
                    594:                                if ( BD(x)[0] & 1 )
                    595:                                        addn(x,a,&t);
                    596:                                else
                    597:                                        t = a;
                    598:                                bshiftn(x,-1,&x2); divn(t,x2,&quo,&rem);
                    599:                                bshiftn(x,1,&xh); addn(quo,xh,&x);
                    600:                        }
                    601:                }
                    602:        }
                    603: }
                    604:
                    605: void iand(n1,n2,r)
                    606: N n1,n2,*r;
                    607: {
                    608:        int d1,d2,d,i;
                    609:        N nr;
                    610:        int *p1,*p2,*pr;
                    611:
                    612:        d1 = PL(n1); d2 = PL(n2);
                    613:        d = MIN(d1,d2);
                    614:        nr = NALLOC(d);
                    615:        for ( i = 0, p1 = BD(n1), p2 = BD(n2), pr = BD(nr); i < d; i++ )
                    616:                pr[i] = p1[i] & p2[i];
                    617:        for ( i = d-1; i >= 0 && !pr[i]; i-- );
                    618:        if ( i < 0 )
                    619:                *r = 0;
                    620:        else {
                    621:                PL(nr) = i+1; *r = nr;
                    622:        }
                    623: }
                    624:
                    625: void ior(n1,n2,r)
                    626: N n1,n2,*r;
                    627: {
                    628:        int d1,d2,i;
                    629:        N nr;
                    630:        int *p1,*p2,*pr;
                    631:
                    632:        if ( PL(n1) < PL(n2) ) {
                    633:                nr = n1; n1 = n2; n2 = nr;
                    634:        }
                    635:        d1 = PL(n1); d2 = PL(n2);
                    636:        *r = nr = NALLOC(d1);
                    637:        for ( i = 0, p1 = BD(n1), p2 = BD(n2), pr = BD(nr); i < d2; i++ )
                    638:                pr[i] = p1[i] | p2[i];
                    639:        for ( ; i < d1; i++ )
                    640:                pr[i] = p1[i];
                    641:        for ( i = d1-1; i >= 0 && !pr[i]; i-- );
                    642:        if ( i < 0 )
                    643:                *r = 0;
                    644:        else {
                    645:                PL(nr) = i+1; *r = nr;
                    646:        }
                    647: }
                    648:
                    649: void ixor(n1,n2,r)
                    650: N n1,n2,*r;
                    651: {
                    652:        int d1,d2,i;
                    653:        N nr;
                    654:        int *p1,*p2,*pr;
                    655:
                    656:        if ( PL(n1) < PL(n2) ) {
                    657:                nr = n1; n1 = n2; n2 = nr;
                    658:        }
                    659:        d1 = PL(n1); d2 = PL(n2);
                    660:        *r = nr = NALLOC(d1);
                    661:        for ( i = 0, p1 = BD(n1), p2 = BD(n2), pr = BD(nr); i < d2; i++ )
                    662:                pr[i] = p1[i] ^ p2[i];
                    663:        for ( ; i < d1; i++ )
                    664:                pr[i] = p1[i];
                    665:        for ( i = d1-1; i >= 0 && !pr[i]; i-- );
                    666:        if ( i < 0 )
                    667:                *r = 0;
                    668:        else {
                    669:                PL(nr) = i+1; *r = nr;
                    670:        }
                    671: }
                    672:
                    673: void Pup2_init_eg(rp)
                    674: Obj *rp;
                    675: {
                    676:        up2_init_eg();
                    677:        *rp = 0;
                    678: }
                    679:
                    680: void Pup2_show_eg(rp)
                    681: Obj *rp;
                    682: {
                    683:        up2_show_eg();
                    684:        *rp = 0;
                    685: }
                    686:
                    687: void Pgf2nton(arg,rp)
                    688: NODE arg;
                    689: Q *rp;
                    690: {
                    691:        if ( !ARG0(arg) )
                    692:                *rp = 0;
                    693:        else
                    694:                up2ton(((GF2N)ARG0(arg))->body,rp);
                    695: }
                    696:
                    697: void Pntogf2n(arg,rp)
                    698: NODE arg;
                    699: GF2N *rp;
                    700: {
                    701:        UP2 t;
                    702:
                    703:        ntoup2(ARG0(arg),&t);
                    704:        MKGF2N(t,*rp);
                    705: }
                    706:
                    707: void Pup2_inv(arg,rp)
                    708: NODE arg;
                    709: P *rp;
                    710: {
                    711:        UP2 a,b,t;
                    712:
                    713:        ptoup2(ARG0(arg),&a);
                    714:        ptoup2(ARG1(arg),&b);
                    715:        invup2(a,b,&t);
                    716:        up2top(t,rp);
                    717: }
                    718:
                    719: void Pinv(arg,rp)
                    720: NODE arg;
                    721: Num *rp;
                    722: {
                    723:        Num n;
                    724:        Q mod;
                    725:        MQ r;
                    726:        int inv;
                    727:
                    728:        n = (Num)ARG0(arg); mod = (Q)ARG1(arg);
                    729:        asir_assert(n,O_N,"inv");
                    730:        asir_assert(mod,O_N,"inv");
                    731:        if ( !n || !mod )
                    732:                error("inv: invalid input");
                    733:        else
                    734:                switch ( NID(n) ) {
                    735:                        case N_Q:
                    736:                                invl((Q)n,mod,(Q *)rp);
                    737:                                break;
                    738:                        case N_M:
                    739:                                inv = invm(CONT((MQ)n),QTOS(mod));
                    740:                                STOMQ(inv,r);
                    741:                                *rp = (Num)r;
                    742:                                break;
                    743:                        default:
                    744:                                error("inv: invalid input");
                    745:                }
                    746: }
                    747:
                    748: void Pfac(arg,rp)
                    749: NODE arg;
                    750: Q *rp;
                    751: {
                    752:        asir_assert(ARG0(arg),O_N,"fac");
                    753:        factorial(QTOS((Q)ARG0(arg)),rp);
                    754: }
                    755:
                    756: void Plrandom(arg,rp)
                    757: NODE arg;
                    758: Q *rp;
                    759: {
                    760:        N r;
                    761:
                    762:        asir_assert(ARG0(arg),O_N,"lrandom");
                    763:        randomn(QTOS((Q)ARG0(arg)),&r);
                    764:        NTOQ(r,1,*rp);
                    765: }
                    766:
                    767: void Prandom(arg,rp)
                    768: NODE arg;
                    769: Q *rp;
                    770: {
                    771:        unsigned int r;
                    772:
                    773: #if 0
                    774: #if defined(_PA_RISC1_1)
                    775:        r = mrand48()&BMASK;
                    776: #else
                    777:        if ( arg )
                    778:                srandom(QTOS((Q)ARG0(arg)));
                    779:        r = random()&BMASK;
                    780: #endif
                    781: #endif
                    782:        if ( arg )
                    783:                mt_sgenrand(QTOS((Q)ARG0(arg)));
                    784:        r = mt_genrand();
                    785:        UTOQ(r,*rp);
                    786: }
                    787:
                    788: #if defined(VISUAL) || defined(THINK_C)
                    789: void srandom(unsigned int);
                    790:
                    791: static unsigned int R_Next;
                    792:
                    793: unsigned int random() {
                    794:         if ( !R_Next )
                    795:                 R_Next = 1;
                    796:         return R_Next = (R_Next * 1103515245 + 12345);
                    797: }
                    798:
                    799: void srandom(s)
                    800: unsigned int s;
                    801: {
                    802:                if ( s )
                    803:                        R_Next = s;
                    804:         else if ( !R_Next )
                    805:             R_Next = 1;
                    806: }
                    807: #endif
                    808:
                    809: void Pprime(arg,rp)
                    810: NODE arg;
                    811: Q *rp;
                    812: {
                    813:        int i;
                    814:
                    815:        asir_assert(ARG0(arg),O_N,"prime");
                    816:        i = QTOS((Q)ARG0(arg));
                    817:        if ( i < 0 || i >= 1900 )
                    818:                *rp = 0;
                    819:        else
                    820:                STOQ(sprime[i],*rp);
                    821: }
                    822:
                    823: void Plprime(arg,rp)
                    824: NODE arg;
                    825: Q *rp;
                    826: {
                    827:        int i;
                    828:
                    829:        asir_assert(ARG0(arg),O_N,"lprime");
                    830:        i = QTOS((Q)ARG0(arg));
                    831:        if ( i < 0 || i >= 1000 )
                    832:                *rp = 0;
                    833:        else
                    834:                STOQ(lprime[i],*rp);
                    835: }
                    836:
                    837: extern int up_kara_mag, up_tkara_mag, up_fft_mag;
                    838:
                    839: void Pset_upfft(arg,rp)
                    840: NODE arg;
                    841: Q *rp;
                    842: {
                    843:        if ( arg ) {
                    844:                asir_assert(ARG0(arg),O_N,"set_upfft");
                    845:                up_fft_mag = QTOS((Q)ARG0(arg));
                    846:        }
                    847:        STOQ(up_fft_mag,*rp);
                    848: }
                    849:
                    850: void Pset_upkara(arg,rp)
                    851: NODE arg;
                    852: Q *rp;
                    853: {
                    854:        if ( arg ) {
                    855:                asir_assert(ARG0(arg),O_N,"set_upkara");
                    856:                up_kara_mag = QTOS((Q)ARG0(arg));
                    857:        }
                    858:        STOQ(up_kara_mag,*rp);
                    859: }
                    860:
                    861: void Pset_uptkara(arg,rp)
                    862: NODE arg;
                    863: Q *rp;
                    864: {
                    865:        if ( arg ) {
                    866:                asir_assert(ARG0(arg),O_N,"set_uptkara");
                    867:                up_tkara_mag = QTOS((Q)ARG0(arg));
                    868:        }
                    869:        STOQ(up_tkara_mag,*rp);
                    870: }
                    871:
                    872: extern int up2_kara_mag;
                    873:
                    874: void Pset_up2kara(arg,rp)
                    875: NODE arg;
                    876: Q *rp;
                    877: {
                    878:        if ( arg ) {
                    879:                asir_assert(ARG0(arg),O_N,"set_up2kara");
                    880:                up2_kara_mag = QTOS((Q)ARG0(arg));
                    881:        }
                    882:        STOQ(up2_kara_mag,*rp);
                    883: }
                    884:
                    885: #ifdef HMEXT
                    886: void Pigcdbin(arg,rp)
                    887: NODE arg;
                    888: Obj *rp;
                    889: {
                    890:        N g;
                    891:        Q n1,n2,a;
                    892:
                    893:        n1 = (Q)ARG0(arg); n2 = (Q)ARG1(arg);
                    894:        asir_assert(n1,O_N,"igcd");
                    895:        asir_assert(n2,O_N,"igcd");
                    896:        if ( !n1 )
                    897:                *rp = (Obj)n2;
                    898:        else if ( !n2 )
                    899:                *rp = (Obj)n1;
                    900:        else {
                    901:                gcdbinn(NM(n1),NM(n2),&g);
                    902:                NTOQ(g,1,a); *rp = (Obj)a;
                    903:        }
                    904: }
                    905:
                    906: void Pigcdbmod(arg,rp)
                    907: NODE arg;
                    908: Obj *rp;
                    909: {
                    910:        N g;
                    911:        Q n1,n2,a;
                    912:
                    913:        n1 = (Q)ARG0(arg); n2 = (Q)ARG1(arg);
                    914:        asir_assert(n1,O_N,"igcdbmod");
                    915:        asir_assert(n2,O_N,"igcdbmod");
                    916:        if ( !n1 )
                    917:                *rp = (Obj)n2;
                    918:        else if ( !n2 )
                    919:                *rp = (Obj)n1;
                    920:        else {
                    921:                gcdbmodn(NM(n1),NM(n2),&g);
                    922:                NTOQ(g,1,a); *rp = (Obj)a;
                    923:        }
                    924: }
                    925:
                    926: void Pigcdacc(arg,rp)
                    927: NODE arg;
                    928: Obj *rp;
                    929: {
                    930:        N g;
                    931:        Q n1,n2,a;
                    932:
                    933:        n1 = (Q)ARG0(arg); n2 = (Q)ARG1(arg);
                    934:        asir_assert(n1,O_N,"igcdacc");
                    935:        asir_assert(n2,O_N,"igcdacc");
                    936:        if ( !n1 )
                    937:                *rp = (Obj)n2;
                    938:        else if ( !n2 )
                    939:                *rp = (Obj)n1;
                    940:        else {
                    941:                gcdaccn(NM(n1),NM(n2),&g);
                    942:                NTOQ(g,1,a); *rp = (Obj)a;
                    943:        }
                    944: }
                    945:
                    946: void PigcdEuc(arg,rp)
                    947: NODE arg;
                    948: Obj *rp;
                    949: {
                    950:        N g;
                    951:        Q n1,n2,a;
                    952:
                    953:        n1 = (Q)ARG0(arg); n2 = (Q)ARG1(arg);
                    954:        asir_assert(n1,O_N,"igcdbmod");
                    955:        asir_assert(n2,O_N,"igcdbmod");
                    956:        if ( !n1 )
                    957:                *rp = (Obj)n2;
                    958:        else if ( !n2 )
                    959:                *rp = (Obj)n1;
                    960:        else {
                    961:                gcdEuclidn(NM(n1),NM(n2),&g);
                    962:                NTOQ(g,1,a); *rp = (Obj)a;
                    963:        }
                    964: }
                    965:
                    966: extern int igcd_algorithm;
                    967:     /* == 0 : Euclid,
                    968:      * == 1 : binary,
                    969:      * == 2 : bmod,
                    970:      * >= 3 : (Weber's accelerated)/(Jebelean's generalized binary) algorithm,
                    971:      */
                    972: extern int igcd_thre_inidiv;
                    973:     /*
                    974:      *  In the non-Euclidean algorithms, if the ratio of the lengths (number
                    975:      *  of words) of two integers is >= igcd_thre_inidiv, we first perform
                    976:      *  remainder calculation.
                    977:      *  If == 0, this remainder calculation is not performed.
                    978:      */
                    979: extern int igcdacc_thre;
                    980:     /*
                    981:      *  In the accelerated algorithm, if the bit-lengths of two integers is
                    982:      *  > igcdacc_thre, "bmod" reduction is done.
                    983:      */
                    984:
                    985: void Pigcdcntl(arg,rp)
                    986: NODE arg;
                    987: Obj *rp;
                    988: {
                    989:        Obj p;
                    990:        Q a;
                    991:        int k, m;
                    992:
                    993:        if ( arg ) {
                    994:                p = (Obj)ARG0(arg);
                    995:                if ( !p ) {
                    996:                        igcd_algorithm = 0;
                    997:                        *rp = p;
                    998:                        return;
                    999:                } else if ( OID(p) == O_N ) {
                   1000:                        k = QTOS((Q)p);
                   1001:                        a = (Q)p;
                   1002:                        if ( k >= 0 ) igcd_algorithm = k;
                   1003:                        else if ( k == -1 ) {
                   1004:                        ret_thre:
                   1005:                                k = - igcd_thre_inidiv - igcdacc_thre*10000;
                   1006:                                STOQ(k,a);
                   1007:                                *rp = (Obj)a;
                   1008:                                return;
                   1009:                        } else {
                   1010:                                if ( (m = (-k)%10000) != 0 ) igcd_thre_inidiv = m;
                   1011:                                if ( (m = -k/10000) != 0 ) igcdacc_thre = m;
                   1012:                                goto ret_thre;
                   1013:                        }
                   1014:                } else if ( OID(p) == O_STR ) {
                   1015:                        char *n = BDY((STRING) p);
                   1016:
                   1017:                        if ( !strcmp( n, "binary" ) || !strcmp( n, "Binary" )
                   1018:                             || !strcmp( n, "bin" ) || !strcmp( n, "Bin" ) )
                   1019:                                k = igcd_algorithm = 1;
                   1020:                        else if ( !strcmp( n, "bmod" ) || !strcmp( n, "Bmod" ) )
                   1021:                                igcd_algorithm = 2;
                   1022:                        else if ( !strcmp( n, "euc" ) || !strcmp( n, "Euc" )
                   1023:                                  || !strcmp( n, "euclid" ) || !strcmp( n, "Euclid" ) )
                   1024:                                igcd_algorithm = 0;
                   1025:                        else if ( !strcmp( n, "acc" ) || !strcmp( n, "Acc" )
                   1026:                             || !strcmp( n, "gen" ) || !strcmp( n, "Gen" )
                   1027:                             || !strcmp( n, "genbin" ) || !strcmp( n, "GenBin" ) )
                   1028:                                igcd_algorithm = 3;
                   1029:                        else error( "igcdhow : invalid algorithm specification" );
                   1030:                }
                   1031:        }
                   1032:        STOQ(igcd_algorithm,a);
                   1033:        *rp = (Obj)a;
                   1034:        return;
                   1035: }
                   1036:
                   1037:
                   1038: void Pimaxrsh(arg,rp)
                   1039: NODE arg;
                   1040: LIST *rp;
                   1041: {
                   1042:        N n1, n2;
                   1043:        Q q;
                   1044:        NODE node1, node2;
                   1045:        int bits;
                   1046:        N maxrshn();
                   1047:
                   1048:        q = (Q)ARG0(arg);
                   1049:        asir_assert(q,O_N,"imaxrsh");
                   1050:        if ( !q ) n1 = n2 = 0;
                   1051:        else {
                   1052:                n1 = maxrshn( NM(q), &bits );
                   1053:                STON( bits, n2 );
                   1054:        }
                   1055:        NTOQ( n2, 1, q );
                   1056:        MKNODE( node2, q, 0 );
                   1057:        NTOQ( n1, 1, q );
                   1058:        MKNODE( node1, q, node2 );
                   1059:        MKLIST( *rp, node1 );
                   1060: }
                   1061: void Pilen(arg,rp)
                   1062: NODE arg;
                   1063: Obj *rp;
                   1064: {
                   1065:        Q q;
                   1066:        int l;
                   1067:
                   1068:        q = (Q)ARG0(arg);
                   1069:        asir_assert(q,O_N,"ilenh");
                   1070:        if ( !q ) l = 0;
                   1071:        else l = PL(NM(q));
                   1072:        STOQ(l,q);
                   1073:        *rp = (Obj)q;
                   1074: }
                   1075:
                   1076: void Pihex(arg,rp)
                   1077: NODE arg;
                   1078: Obj *rp;
                   1079: {
                   1080:        Q n1;
                   1081:
                   1082:        n1 = (Q)ARG0(arg);
                   1083:        asir_assert(n1,O_N,"ihex");
                   1084:        if ( n1 ) {
                   1085:                int i, l = PL(NM(n1)), *p = BD(NM(n1));
                   1086:
                   1087:                for ( i = 0; i < l; i++ ) printf( " 0x%08x", p[i] );
                   1088:                printf( "\n" );
                   1089:        } else printf( " 0x%08x\n", 0 );
                   1090:        *rp = (Obj)n1;
                   1091: }
                   1092: #endif /* HMEXT */

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