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

Annotation of OpenXM_contrib2/asir2000/engine/Q.c, Revision 1.4

1.4     ! noro        1: /*
        !             2:  * Copyright (c) 1994-2000 FUJITSU LABORATORIES LIMITED
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * FUJITSU LABORATORIES LIMITED ("FLL") hereby grants you a limited,
        !             6:  * non-exclusive and royalty-free license to use, copy, modify and
        !             7:  * redistribute, solely for non-commercial and non-profit purposes, the
        !             8:  * computer program, "Risa/Asir" ("SOFTWARE"), subject to the terms and
        !             9:  * conditions of this Agreement. For the avoidance of doubt, you acquire
        !            10:  * only a limited right to use the SOFTWARE hereunder, and FLL or any
        !            11:  * third party developer retains all rights, including but not limited to
        !            12:  * copyrights, in and to the SOFTWARE.
        !            13:  *
        !            14:  * (1) FLL does not grant you a license in any way for commercial
        !            15:  * purposes. You may use the SOFTWARE only for non-commercial and
        !            16:  * non-profit purposes only, such as academic, research and internal
        !            17:  * business use.
        !            18:  * (2) The SOFTWARE is protected by the Copyright Law of Japan and
        !            19:  * international copyright treaties. If you make copies of the SOFTWARE,
        !            20:  * with or without modification, as permitted hereunder, you shall affix
        !            21:  * to all such copies of the SOFTWARE the above copyright notice.
        !            22:  * (3) An explicit reference to this SOFTWARE and its copyright owner
        !            23:  * shall be made on your publication or presentation in any form of the
        !            24:  * results obtained by use of the SOFTWARE.
        !            25:  * (4) In the event that you modify the SOFTWARE, you shall notify FLL by
        !            26:  * e-mail at risa-admin@flab.fujitsu.co.jp of the detailed specification
        !            27:  * for such modification or the source code of the modified part of the
        !            28:  * SOFTWARE.
        !            29:  *
        !            30:  * THE SOFTWARE IS PROVIDED AS IS WITHOUT ANY WARRANTY OF ANY KIND. FLL
        !            31:  * MAKES ABSOLUTELY NO WARRANTIES, EXPRESSED, IMPLIED OR STATUTORY, AND
        !            32:  * EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS
        !            33:  * FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT OF THIRD PARTIES'
        !            34:  * RIGHTS. NO FLL DEALER, AGENT, EMPLOYEES IS AUTHORIZED TO MAKE ANY
        !            35:  * MODIFICATIONS, EXTENSIONS, OR ADDITIONS TO THIS WARRANTY.
        !            36:  * UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, TORT, CONTRACT,
        !            37:  * OR OTHERWISE, SHALL FLL BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY
        !            38:  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL
        !            39:  * DAMAGES OF ANY CHARACTER, INCLUDING, WITHOUT LIMITATION, DAMAGES
        !            40:  * ARISING OUT OF OR RELATING TO THE SOFTWARE OR THIS AGREEMENT, DAMAGES
        !            41:  * FOR LOSS OF GOODWILL, WORK STOPPAGE, OR LOSS OF DATA, OR FOR ANY
        !            42:  * DAMAGES, EVEN IF FLL SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF
        !            43:  * SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. EVEN IF A PART
        !            44:  * OF THE SOFTWARE HAS BEEN DEVELOPED BY A THIRD PARTY, THE THIRD PARTY
        !            45:  * DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE,
        !            46:  * PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE.
        !            47:  *
        !            48:  * $OpenXM: OpenXM_contrib2/asir2000/engine/Q.c,v 1.3 2000/05/29 08:54:46 noro Exp $
        !            49: */
1.1       noro       50: #include "ca.h"
                     51: #include "base.h"
                     52: #include "inline.h"
                     53:
                     54: void addq(n1,n2,nr)
                     55: Q n1,n2,*nr;
                     56: {
                     57:        N nm,dn,nm1,nm2,nm3,dn0,dn1,dn2,g,g1,g0,m;
                     58:        int sgn;
                     59:        unsigned t,t1;
                     60:
                     61:        if ( !n1 )
                     62:                *nr = n2;
                     63:        else if ( !n2 )
                     64:                *nr = n1;
                     65:        else if ( INT(n1) )
                     66:                if ( INT(n2) ) {
                     67:                        nm1 = NM(n1); nm2 = NM(n2);
                     68:                        if ( SGN(n1) == SGN(n2) ) {
                     69:                                if ( PL(nm1) == 1 && PL(nm2) == 1 ) {
                     70:                                        t1 = BD(nm1)[0]; t = t1+BD(nm2)[0];
                     71:                                        if ( t < t1 ) {
                     72:                                                m = NALLOC(2); PL(m) = 2; BD(m)[0] = t; BD(m)[1] = 1;
                     73:                                        } else
                     74:                                                UTON(t,m);
                     75:                                } else
                     76:                                        addn(NM(n1),NM(n2),&m);
                     77:                                NTOQ(m,SGN(n1),*nr);
                     78:                        } else {
                     79:                                if ( PL(nm1) == 1 && PL(nm2) == 1 ) {
                     80:                                        t1 = BD(nm1)[0]; t = t1-BD(nm2)[0];
                     81:                                        if ( !t )
                     82:                                                sgn = 0;
                     83:                                        else if ( t > t1 ) {
                     84:                                                sgn = -1; t = -((int)t); UTON(t,m);
                     85:                                        } else {
                     86:                                                sgn = 1; UTON(t,m);
                     87:                                        }
                     88:                                } else
                     89:                                        sgn = subn(NM(n1),NM(n2),&m);
                     90:                                if ( sgn ) {
                     91:                                        if ( SGN(n1) == sgn )
                     92:                                                NTOQ(m,1,*nr);
                     93:                                        else
                     94:                                                NTOQ(m,-1,*nr);
                     95:                                } else
                     96:                                        *nr = 0;
                     97:                        }
                     98:                } else {
                     99:                        kmuln(NM(n1),DN(n2),&m);
                    100:                        if ( SGN(n1) == SGN(n2) ) {
                    101:                                sgn = SGN(n1); addn(m,NM(n2),&nm);
                    102:                        } else
                    103:                                sgn = SGN(n1)*subn(m,NM(n2),&nm);
                    104:                        if ( sgn ) {
                    105:                                dn = DN(n2); NDTOQ(nm,dn,sgn,*nr);
                    106:                        } else
                    107:                                *nr = 0;
                    108:                }
                    109:        else if ( INT(n2) ) {
                    110:                kmuln(NM(n2),DN(n1),&m);
                    111:                if ( SGN(n1) == SGN(n2) ) {
                    112:                        sgn = SGN(n1); addn(m,NM(n1),&nm);
                    113:                } else
                    114:                        sgn = SGN(n1)*subn(NM(n1),m,&nm);
                    115:                if ( sgn ) {
                    116:                        dn = DN(n1); NDTOQ(nm,dn,sgn,*nr);
                    117:                } else
                    118:                        *nr = 0;
                    119:        } else {
                    120:                gcdn(DN(n1),DN(n2),&g); divsn(DN(n1),g,&dn1); divsn(DN(n2),g,&dn2);
                    121:                kmuln(NM(n1),dn2,&nm1); kmuln(NM(n2),dn1,&nm2);
                    122:                if ( SGN(n1) == SGN(n2) ) {
                    123:                        sgn = SGN(n1); addn(nm1,nm2,&nm3);
                    124:                } else
                    125:                        sgn = SGN(n1)*subn(nm1,nm2,&nm3);
                    126:                if ( sgn ) {
                    127:                        gcdn(nm3,g,&g1); divsn(nm3,g1,&nm); divsn(g,g1,&g0);
                    128:                        kmuln(dn1,dn2,&dn0); kmuln(g0,dn0,&dn);
                    129:                        if ( UNIN(dn) )
                    130:                                NTOQ(nm,sgn,*nr);
                    131:                        else
                    132:                                NDTOQ(nm,dn,sgn,*nr);
                    133:                } else
                    134:                        *nr = 0;
                    135:        }
                    136: }
                    137:
                    138: void subq(n1,n2,nr)
                    139: Q n1,n2,*nr;
                    140: {
                    141:        Q m;
                    142:
                    143:        if ( !n1 )
                    144:                if ( !n2 )
                    145:                        *nr = 0;
                    146:                else {
                    147:                        DUPQ(n2,*nr); SGN(*nr) = -SGN(n2);
                    148:                }
                    149:        else if ( !n2 )
                    150:                *nr = n1;
                    151:        else if ( n1 == n2 )
                    152:                *nr = 0;
                    153:        else {
                    154:                DUPQ(n2,m); SGN(m) = -SGN(n2); addq(n1,m,nr);
                    155:        }
                    156: }
                    157:
                    158: void mulq(n1,n2,nr)
                    159: Q n1,n2,*nr;
                    160: {
                    161:        N nm,nm1,nm2,dn,dn1,dn2,g;
                    162:        int sgn;
                    163:        unsigned u,l;
                    164:
                    165:        if ( !n1 || !n2 ) *nr = 0;
                    166:        else if ( INT(n1) )
                    167:                if ( INT(n2) ) {
                    168:                        nm1 = NM(n1); nm2 = NM(n2);
                    169:                        if ( PL(nm1) == 1 && PL(nm2) == 1 ) {
                    170:                                DM(BD(NM(n1))[0],BD(NM(n2))[0],u,l)
                    171:                                if ( u ) {
                    172:                                        nm = NALLOC(2); PL(nm) = 2; BD(nm)[0] = l; BD(nm)[1] = u;
                    173:                                } else {
                    174:                                        nm = NALLOC(1); PL(nm) = 1; BD(nm)[0] = l;
                    175:                                }
                    176:                        } else
                    177:                                kmuln(nm1,nm2,&nm);
                    178:                        sgn = (SGN(n1)==SGN(n2)?1:-1); NTOQ(nm,sgn,*nr);
                    179:                } else {
                    180:                        gcdn(NM(n1),DN(n2),&g); divsn(NM(n1),g,&nm1); divsn(DN(n2),g,&dn);
                    181:                        kmuln(nm1,NM(n2),&nm); sgn = SGN(n1)*SGN(n2);
                    182:                        if ( UNIN(dn) )
                    183:                                NTOQ(nm,sgn,*nr);
                    184:                        else
                    185:                                NDTOQ(nm,dn,sgn,*nr);
                    186:                }
                    187:        else if ( INT(n2) ) {
                    188:                gcdn(NM(n2),DN(n1),&g); divsn(NM(n2),g,&nm2); divsn(DN(n1),g,&dn);
                    189:                kmuln(nm2,NM(n1),&nm); sgn = SGN(n1)*SGN(n2);
                    190:                if ( UNIN(dn) )
                    191:                        NTOQ(nm,sgn,*nr);
                    192:                else
                    193:                        NDTOQ(nm,dn,sgn,*nr);
                    194:        } else {
                    195:                gcdn(NM(n1),DN(n2),&g); divsn(NM(n1),g,&nm1); divsn(DN(n2),g,&dn2);
                    196:                gcdn(DN(n1),NM(n2),&g); divsn(DN(n1),g,&dn1); divsn(NM(n2),g,&nm2);
                    197:                kmuln(nm1,nm2,&nm); kmuln(dn1,dn2,&dn); sgn = SGN(n1) * SGN(n2);
                    198:                if ( UNIN(dn) )
                    199:                        NTOQ(nm,sgn,*nr);
                    200:                else
                    201:                        NDTOQ(nm,dn,sgn,*nr);
                    202:        }
                    203: }
                    204:
                    205: void divq(n1,n2,nq)
                    206: Q n1,n2,*nq;
                    207: {
                    208:        Q m;
                    209:
                    210:        if ( !n2 ) {
                    211:                error("division by 0");
                    212:                *nq = 0;
                    213:                return;
                    214:        } else if ( !n1 )
                    215:                *nq = 0;
                    216:        else if ( n1 == n2 )
                    217:                *nq = ONE;
                    218:        else {
                    219:                invq(n2,&m); mulq(n1,m,nq);
                    220:        }
                    221: }
                    222:
                    223: void invq(n,nr)
                    224: Q n,*nr;
                    225: {
                    226:        N nm,dn;
                    227:
                    228:        if ( INT(n) )
                    229:                if ( UNIN(NM(n)) )
                    230:                        if ( SGN(n) > 0 )
                    231:                                *nr = ONE;
                    232:                        else {
                    233:                                nm = ONEN; NTOQ(nm,SGN(n),*nr);
                    234:                        }
                    235:                else {
                    236:                        nm = ONEN; dn = NM(n); NDTOQ(nm,dn,SGN(n),*nr);
                    237:                }
                    238:        else if ( UNIN(NM(n)) ) {
                    239:                nm = DN(n); NTOQ(nm,SGN(n),*nr);
                    240:        } else {
                    241:                nm = DN(n); dn = NM(n); NDTOQ(nm,dn,SGN(n),*nr);
                    242:        }
                    243: }
                    244:
                    245: void chsgnq(n,nr)
                    246: Q n,*nr;
                    247: {
                    248:        Q t;
                    249:
                    250:        if ( !n )
                    251:                *nr = 0;
                    252:        else {
                    253:                DUPQ(n,t); SGN(t) = -SGN(t); *nr = t;
                    254:        }
                    255: }
                    256:
                    257: void pwrq(n1,n,nr)
                    258: Q n1,n,*nr;
                    259: {
                    260:        N nm,dn;
                    261:        int sgn;
                    262:
                    263:        if ( !n || UNIQ(n1) )
                    264:                *nr = ONE;
                    265:        else if ( !n1 )
                    266:                *nr = 0;
                    267:        else if ( !INT(n) ) {
                    268:                error("can't calculate fractional power."); *nr = 0;
                    269:        } else if ( MUNIQ(n1) )
                    270:                *nr = BD(NM(n))[0]%2 ? n1 : ONE;
                    271:        else if ( PL(NM(n)) > 1 ) {
                    272:                error("exponent too big."); *nr = 0;
                    273:        } else {
                    274:                sgn = ((SGN(n1)>0)||EVENN(NM(n))?1:-1);
                    275:                pwrn(NM(n1),BD(NM(n))[0],&nm);
                    276:                if ( INT(n1) ) {
                    277:                        if ( UNIN(nm) )
                    278:                                if ( sgn == 1 )
                    279:                                        *nr = ONE;
                    280:                                else
                    281:                                        NTOQ(ONEN,sgn,*nr);
                    282:                        else if ( SGN(n) > 0 )
                    283:                                NTOQ(nm,sgn,*nr);
                    284:                        else
                    285:                                NDTOQ(ONEN,nm,sgn,*nr);
                    286:                } else {
                    287:                        pwrn(DN(n1),BD(NM(n))[0],&dn);
                    288:                        if ( SGN(n) > 0 )
                    289:                                NDTOQ(nm,dn,sgn,*nr);
                    290:                        else if ( UNIN(nm) )
                    291:                                NTOQ(dn,sgn,*nr);
                    292:                        else
                    293:                                NDTOQ(dn,nm,sgn,*nr);
                    294:                }
                    295:        }
                    296: }
                    297:
                    298: int cmpq(q1,q2)
                    299: Q q1,q2;
                    300: {
                    301:        int sgn;
                    302:        N t,s;
                    303:
                    304:        if ( !q1 )
                    305:                if ( !q2 )
                    306:                        return ( 0 );
                    307:                else
                    308:                        return ( -SGN(q2) );
                    309:        else if ( !q2 )
                    310:                return ( SGN(q1) );
                    311:        else if ( SGN(q1) != SGN(q2) )
                    312:                        return ( SGN(q1) );
                    313:        else if ( INT(q1) )
                    314:                        if ( INT(q2) ) {
                    315:                                sgn = cmpn(NM(q1),NM(q2));
                    316:                                if ( !sgn )
                    317:                                        return ( 0 );
                    318:                                else
                    319:                                        return ( SGN(q1)==sgn?1:-1 );
                    320:                        } else {
                    321:                                kmuln(NM(q1),DN(q2),&t); sgn = cmpn(t,NM(q2));
                    322:                                return ( SGN(q1) * sgn );
                    323:                        }
                    324:        else if ( INT(q2) ) {
                    325:                kmuln(NM(q2),DN(q1),&t); sgn = cmpn(NM(q1),t);
                    326:                return ( SGN(q1) * sgn );
                    327:        } else {
                    328:                kmuln(NM(q1),DN(q2),&t); kmuln(NM(q2),DN(q1),&s); sgn = cmpn(t,s);
                    329:                return ( SGN(q1) * sgn );
                    330:        }
                    331: }
                    332:
                    333: void remq(n,m,nr)
                    334: Q n,m;
                    335: Q *nr;
                    336: {
                    337:        N q,r,s;
                    338:
                    339:        if ( !n ) {
                    340:                *nr = 0;
                    341:                return;
                    342:        }
                    343:        divn(NM(n),NM(m),&q,&r);
                    344:        if ( !r )
                    345:                *nr = 0;
                    346:        else if ( SGN(n) > 0 )
                    347:                NTOQ(r,1,*nr);
                    348:        else {
                    349:                subn(NM(m),r,&s); NTOQ(s,1,*nr);
                    350:        }
                    351: }
                    352:
1.2       noro      353: /* t = [nC0 nC1 ... nCn] */
                    354:
1.1       noro      355: void mkbc(n,t)
                    356: int n;
                    357: Q *t;
                    358: {
                    359:        int i;
                    360:        N c,d;
                    361:
                    362:        for ( t[0] = ONE, i = 1; i <= n/2; i++ ) {
                    363:                c = NALLOC(1); PL(c) = 1; BD(c)[0] = n-i+1;
                    364:                kmuln(NM(t[i-1]),c,&d); divin(d,i,&c); NTOQ(c,1,t[i]);
                    365:        }
                    366:        for ( ; i <= n; i++ )
                    367:                t[i] = t[n-i];
1.2       noro      368: }
                    369:
                    370: /*
                    371:  *  Dx^k*x^l = W(k,l,0)*x^l*Dx^k+W(k,l,1)*x^(l-1)*x^(k-1)*+...
                    372:  *
                    373:  *  t = [W(k,l,0) W(k,l,1) ... W(k,l,min(k,l)]
                    374:  *  where W(k,l,i) = i! * kCi * lCi
                    375:  */
                    376:
                    377: void mkwc(k,l,t)
                    378: int k,l;
                    379: Q *t;
                    380: {
                    381:        int i,n,up,low;
                    382:        N nm,d,c;
                    383:
                    384:        n = MIN(k,l);
                    385:        for ( t[0] = ONE, i = 1; i <= n; i++ ) {
                    386:                DM(k-i+1,l-i+1,up,low);
                    387:                if ( up ) {
                    388:                        nm = NALLOC(2); PL(nm) = 2; BD(nm)[0] = low; BD(nm)[1] = up;
                    389:                } else {
                    390:                        nm = NALLOC(1); PL(nm) = 1; BD(nm)[0] = low;
                    391:                }
                    392:                kmuln(NM(t[i-1]),nm,&d); divin(d,i,&c); NTOQ(c,1,t[i]);
1.3       noro      393:        }
                    394: }
                    395:
                    396: /* mod m table */
                    397: /* XXX : should be optimized */
                    398:
                    399: void mkwcm(k,l,m,t)
                    400: int k,l,m;
                    401: int *t;
                    402: {
                    403:        int i,n;
                    404:        Q *s;
                    405:
                    406:        n = MIN(k,l);
                    407:        s = (Q *)ALLOCA((n+1)*sizeof(Q));
                    408:        mkwc(k,l,s);
                    409:        for ( i = 0; i <= n; i++ ) {
                    410:                t[i] = rem(NM(s[i]),m);
1.2       noro      411:        }
1.1       noro      412: }
                    413:
                    414: void factorial(n,r)
                    415: int n;
                    416: Q *r;
                    417: {
                    418:        Q t,iq,s;
                    419:        unsigned int i,m,m0;
                    420:        unsigned int c;
                    421:
                    422:        if ( !n )
                    423:                *r = ONE;
                    424:        else if ( n < 0 )
                    425:                *r = 0;
                    426:        else {
                    427:                for ( i = 1, t = ONE; (int)i <= n; ) {
                    428:                        for ( m0 = m = 1, c = 0; ((int)i <= n) && !c; i++ ) {
                    429:                                m0 = m; DM(m0,i,c,m)
                    430:                        }
                    431:                        if ( c ) {
                    432:                                m = m0; i--;
                    433:                        }
                    434:                        UTOQ(m,iq); mulq(t,iq,&s); t = s;
                    435:                }
                    436:                *r = t;
                    437:        }
                    438: }
                    439:
                    440: void invl(a,mod,ar)
                    441: Q a,mod,*ar;
                    442: {
                    443:        Q f1,f2,a1,a2,q,m,s;
                    444:        N qn,rn;
                    445:
                    446:        a1 = ONE; a2 = 0;
                    447:        DUPQ(a,f1); SGN(f1) = 1; f2 = mod;
                    448:
                    449:        while ( 1 ) {
                    450:                divn(NM(f1),NM(f2),&qn,&rn);
                    451:                if ( !qn )
                    452:                        q = 0;
                    453:                else
                    454:                        NTOQ(qn,1,q);
                    455:
                    456:                f1 = f2;
                    457:                if ( !rn )
                    458:                        break;
                    459:                else
                    460:                        NTOQ(rn,1,f2);
                    461:
                    462:                mulq(a2,q,&m); subq(a1,m,&s); a1 = a2;
                    463:                if ( !s )
                    464:                        a2 = 0;
                    465:                else
                    466:                        remq(s,mod,&a2);
                    467:        }
                    468:        if ( SGN(a) < 0 )
                    469:                chsgnq(a2,&m);
                    470:        else
                    471:                m = a2;
                    472:
                    473:        if ( SGN(m) >= 0 )
                    474:                *ar = m;
                    475:        else
                    476:                addq(m,mod,ar);
                    477: }
                    478:
                    479: int kara_mag=100;
                    480:
                    481: void kmuln(n1,n2,nr)
                    482: N n1,n2,*nr;
                    483: {
                    484:        N n,t,s,m,carry;
                    485:        int d,d1,d2,len,i,l;
                    486:        int *r,*r0;
                    487:
                    488:        if ( !n1 || !n2 ) {
                    489:                *nr = 0; return;
                    490:        }
                    491:        d1 = PL(n1); d2 = PL(n2);
                    492:        if ( (d1 < kara_mag) || (d2 < kara_mag) ) {
                    493:                muln(n1,n2,nr); return;
                    494:        }
                    495:        if ( d1 < d2 ) {
                    496:                n = n1; n1 = n2; n2 = n;
                    497:                d = d1; d1 = d2; d2 = d;
                    498:        }
                    499:        if ( d2 > (d1+1)/2 ) {
                    500:                kmulnmain(n1,n2,nr); return;
                    501:        }
                    502:        d = (d1/d2)+((d1%d2)!=0);
                    503:        len = (d+1)*d2;
                    504:        r0 = (int *)ALLOCA(len*sizeof(int));
                    505:        bzero((char *)r0,len*sizeof(int));
                    506:        for ( carry = 0, i = 0, r = r0; i < d; i++, r += d2 ) {
                    507:                extractn(n1,i*d2,d2,&m);
                    508:                if ( m ) {
                    509:                        kmuln(m,n2,&t);
                    510:                        addn(t,carry,&s);
                    511:                        copyn(s,d2,r);
                    512:                        extractn(s,d2,d2,&carry);
                    513:                } else {
                    514:                        copyn(carry,d2,r);
                    515:                        carry = 0;
                    516:                }
                    517:        }
                    518:        copyn(carry,d2,r);
                    519:        for ( l = len - 1; !r0[l]; l-- );
                    520:        l++;
                    521:        *nr = t = NALLOC(l); PL(t) = l;
                    522:        bcopy((char *)r0,(char *)BD(t),l*sizeof(int));
                    523: }
                    524:
                    525: void extractn(n,index,len,nr)
                    526: N n;
                    527: int index,len;
                    528: N *nr;
                    529: {
                    530:        unsigned int *m;
                    531:        int l;
                    532:        N t;
                    533:
                    534:        if ( !n ) {
                    535:                *nr = 0; return;
                    536:        }
                    537:        m = BD(n)+index;
                    538:        if ( (l = PL(n)-index) >= len ) {
                    539:                for ( l = len - 1; (l >= 0) && !m[l]; l-- );
                    540:                l++;
                    541:        }
                    542:        if ( l <= 0 ) {
                    543:                *nr = 0; return;
                    544:        } else {
                    545:                *nr = t = NALLOC(l); PL(t) = l;
                    546:                bcopy((char *)m,(char *)BD(t),l*sizeof(int));
                    547:        }
                    548: }
                    549:
                    550: void copyn(n,len,p)
                    551: N n;
                    552: int len;
                    553: int *p;
                    554: {
                    555:        if ( n )
                    556:                bcopy((char *)BD(n),(char *)p,MIN(PL(n),len)*sizeof(int));
                    557: }
                    558:
                    559: void dupn(n,p)
                    560: N n;
                    561: N p;
                    562: {
                    563:        if ( n )
                    564:                bcopy((char *)n,(char *)p,(1+PL(n))*sizeof(int));
                    565: }
                    566:
                    567: void kmulnmain(n1,n2,nr)
                    568: N n1,n2,*nr;
                    569: {
                    570:        int d1,d2,h,sgn,sgn1,sgn2,len;
                    571:        N n1lo,n1hi,n2lo,n2hi,hi,lo,mid1,mid2,mid,s1,s2,t1,t2;
                    572:
                    573:        d1 = PL(n1); d2 = PL(n2); h = (d1+1)/2;
                    574:        extractn(n1,0,h,&n1lo); extractn(n1,h,d1-h,&n1hi);
                    575:        extractn(n2,0,h,&n2lo); extractn(n2,h,d2-h,&n2hi);
                    576:        kmuln(n1hi,n2hi,&hi); kmuln(n1lo,n2lo,&lo);
                    577:        len = PL(hi)+2*h; t1 = NALLOC(len); PL(t1) = len;
                    578:        bzero((char *)BD(t1),len*sizeof(int));
                    579:        if ( lo )
                    580:                bcopy((char *)BD(lo),(char *)BD(t1),PL(lo)*sizeof(int));
                    581:        if ( hi )
                    582:                bcopy((char *)BD(hi),(char *)(BD(t1)+2*h),PL(hi)*sizeof(int));
                    583:
                    584:        addn(hi,lo,&mid1);
                    585:        sgn1 = subn(n1hi,n1lo,&s1); sgn2 = subn(n2lo,n2hi,&s2);
                    586:        kmuln(s1,s2,&mid2); sgn = sgn1*sgn2;
                    587:        if ( sgn > 0 )
                    588:                addn(mid1,mid2,&mid);
                    589:        else
                    590:                subn(mid1,mid2,&mid);
                    591:        if ( mid ) {
                    592:                len = PL(mid)+h; t2 = NALLOC(len); PL(t2) = len;
                    593:                bzero((char *)BD(t2),len*sizeof(int));
                    594:                bcopy((char *)BD(mid),(char *)(BD(t2)+h),PL(mid)*sizeof(int));
                    595:                addn(t1,t2,nr);
                    596:        } else
                    597:                *nr = t1;
                    598: }

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