Annotation of OpenXM_contrib2/asir2000/builtin/int.c, Revision 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,>);
! 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>