Annotation of OpenXM_contrib2/asir2000/engine/pari-mp.c, Revision 1.4
1.1 saito 1: /*
1.4 ! saito 2: * $OpenXM: OpenXM_contrib2/asir2000/engine/pari-mp.c,v 1.3 2003/02/14 22:29:09 ohara Exp $
1.1 saito 3: */
4: /* for f-itv.c */
5:
1.3 ohara 6: #if defined(PARI)
1.2 noro 7:
1.4 ! saito 8: #include <genpari.h>
1.1 saito 9: #include "itv-pari.h"
1.4 ! saito 10:
! 11: # if PARI_VERSION_CODE > 131588
! 12: extern ulong hiremainder, overflow;
! 13: # endif
1.1 saito 14:
15:
16: GEN
17: PariAddDown(GEN x, GEN y)
18: {
19: if(typ(x)==1) return (typ(y)==1) ? addii(x,y) : PariAddirDown(y,x);
20: return (typ(y)==1) ? PariAddirDown(y,x) : PariAddrrDown(x,y);
21: }
22:
23: GEN
24: PariAddirDown(GEN x, GEN y)
25: {
26: long l,e,ly,av,i,l1;
27: GEN z;
28:
29: if(!signe(x)) return rcopy(y);
30: if(!signe(y))
31: {
32: l=lgef(x)-(expo(y)>>TWOPOTBITS_IN_LONG);if((l<3)||(l>32767)) err(adder3);
33: z=cgetr(l);affir(x,z);return z;
34: }
35: else
36: {
37: e=expo(y)-expi(x);ly=lg(y);
38: if(e>0)
39: {
40: l=ly-(e>>TWOPOTBITS_IN_LONG);if(l<=2) return rcopy(y);
41: }
42: else
43: {
44: l=ly+((-e)>>TWOPOTBITS_IN_LONG)+1;if(l>32767) err(adder3);
45: }
46: av=avma;z=cgetr(l);affir(x,z);l1=av-avma;l=l1>>TWOPOTBYTES_IN_LONG;
47: z=PariAddrrDown(z,y);
48: for(i=lg(z)-1;i>=0;i--) z[i+l]=z[i];z+=l;avma+=l1;
49: }
50: return z;
51: }
52:
53: GEN
54: PariAddrrDown(GEN x, GEN y)
55: {
56: long sx=signe(x),sy=signe(y),lx=lg(x),ly=lg(y),lz,ex=expo(x),ey=expo(y),sz;
57: long av0=avma,e,l,i,d,m,flag,lp1,lp2,av,k,j,cex,f2;
58: GEN z,p1,p2;
59:
60: if(!sy)
61: {
62: if(!sx) {e=(ex>=ey)?ex:ey;z=cgetr(3);z[2]=0;z[1]=e+HIGHEXPOBIT;return z;}
63: e=ex-ey;
64: if(e<0) {z=cgetr(3);z[2]=0;z[1]=ey+HIGHEXPOBIT;return z;}
65: l=(e>>TWOPOTBITS_IN_LONG)+3;if(l>lx) l=lx;z=cgetr(l);
66: for(i=1;i<l;i++) z[i]=x[i];return z;
67: }
68: e=ey-ex;
69: if(!sx)
70: {
71: if(e<0) {z=cgetr(3);z[2]=0;z[1]=ex+HIGHEXPOBIT;return z;}
72: l=(e>>TWOPOTBITS_IN_LONG)+3;if(l>ly) l=ly;z=cgetr(l);
73: for(i=1;i<l;i++) z[i]=y[i];return z;
74: }
75: if(e)
76: {
77: if(e<0) {z=x;x=y;y=z;lz=lx;lx=ly;ly=lz;ey=ex;e= -e;sz=sx;sx=sy;sy=sz;}
78: d=(e>>TWOPOTBITS_IN_LONG);m=e&(BITS_IN_LONG-1);
79: if(d>=ly-2) return rcopy(y);
80: l=d+lx;
81: if(l>=ly)
82: {
83: flag=1;p1=cgetr(ly);lp1=ly;lp2=ly-d;
84: }
85: else
86: {
87: flag=0;p1=cgetr(l+1);lp2=lx+1;lp1=l+1;
88: }
89: av=avma;
90: if(m)
91: {
92: p2=cgetr(lp2);m=BITS_IN_LONG-m;
93: if(flag) {shiftl(x[lp2-1],m);k=hiremainder;}
94: else k=0;
95: for(i=lp2-1;i>=3;i--)
96: {
97: p2[i]=shiftl(x[i-1],m)+k;k=hiremainder;
98: }
99: p2[2]=k;
100: }
101: else p2=x;
102: }
103: else
104: {
105: l=(lx>ly)?ly:lx;p1=cgetr(l);av=avma;lp2=lp1=l;flag=2;p2=x;m=0;
106: }
107: if(sx==sy)
108: {
109: overflow=0;
110: if(m+flag) for(i=lp1-1,j=lp2-1;j>=2;i--,j--) p1[i]=addllx(p2[j],y[i]);
111: else
112: {
113: p1[lp1-1]=y[lp1-1];
114: for(i=lp1-2,j=lp2-2;j>=2;i--,j--) p1[i]=addllx(p2[j],y[i]);
115: }
116: if(overflow)
117: {
118: for(;(i>=2)&&(y[i]==(long)MAXULONG);i--) p1[i]=0;
119: if(i>=2) {cex=0;p1[i]=y[i]+1;while(i>=3) {i--;p1[i]=y[i];}}
120: else
121: {
122: cex=1;k=HIGHBIT;if(ey==(HIGHEXPOBIT-1)) err(adder4);
123: for(i=2;i<lp1;i++) {p1[i]=shiftlr(p1[i],1)+k;k=hiremainder;}
124:
125: if ( sx < 0 && hiremainder ) { /* |p1| + 1 */
126: overflow=1;
127: for(j=lg(p1);(overflow) && j>=2;j--) p1[j]=addllx(p1[j],0);
128: }
129:
130: }
131: }
132: else {cex=0;for(;i>=2;i--) p1[i]=y[i];}
133: p1[1]=evalsigne(sx)+ey+cex+HIGHEXPOBIT;
134: avma=av;return p1;
135: }
136: else
137: {
138: if(!e)
139: {
140: for(i=2;(i<l)&&(p2[i]==y[i]);i++);
141: if(i==l)
142: {
143: e=ex-((l-2)<<TWOPOTBITS_IN_LONG)+HIGHEXPOBIT;if(e<0) err(adder5);
144: if(e>EXPOBITS) err(adder4);
145: avma=av0;z=cgetr(3);z[2]=0;z[1]=e;return z;
146: }
147: else
148: {
149: f2=(((ulong)y[i])>((ulong)p2[i]))?1:0;
150: }
151: }
152: else f2=1;
153: if(f2)
154: {
155: overflow=0;
156: if(m+flag) for(i=lp1-1,j=lp2-1;j>=2;i--,j--) p1[i]=subllx(y[i],p2[j]);
157: else
158: {
159: p1[lp1-1]=y[lp1-1];
160: for(i=lp1-2,j=lp2-2;j>=2;i--,j--) p1[i]=subllx(y[i],p2[j]);
161: }
162: if(overflow)
163: {
164: for(;(i>=2)&&(!y[i]);i--) p1[i]=(long)MAXULONG;
165: p1[i]=y[i]-1;while(i>=3) {i--;p1[i]=y[i];}
166: }
167: else for(;i>=2;i--) p1[i]=y[i];
168: }
169: else
170: {
171: overflow=0;
172: if(m+flag) for(i=lp1-1;i>=2;i--) p1[i]=subllx(p2[i],y[i]);
173: else
174: {
175: p1[lp1-1]=subllx(0,y[lp1-1]);
176: for(i=lp1-2;i>=2;i--) p1[i]=subllx(p2[i],y[i]);
177: }
178: }
179: for(i=2;!p1[i];i++);j=i-2;avma=av+(j<<TWOPOTBYTES_IN_LONG);p1[j]=p1[0]-j;p1+=j;
180: m=bfffo(p1[2]);e=ey-(j<<TWOPOTBITS_IN_LONG)-m+HIGHEXPOBIT;
181: if(e<0) err(adder5);
182: p1[1]=f2 ? evalsigne(sy)+e : evalsigne(sx)+e;
183: if(m)
184: {
185: k=0;for(i=lp1-1-j;i>=2;i--) {p1[i]=shiftl(p1[i],m)+k;k=hiremainder;}
186: }
187: return p1;
188: }
189: }
190:
191: GEN
192: PariSubDown(GEN x, GEN y)
193: {
194: if(typ(x)==1) return (typ(y)==1) ? subii(x,y) : PariSubirDown(x,y);
195: return (typ(y)==1) ? PariSubriDown(x,y) : PariSubrrDown(x,y);
196: }
197:
198: GEN
199: PariSubrrDown(GEN x, GEN y)
200: {
201: long s=signe(y);
202: GEN z;
203:
204: if(x==y)
205: {
206: z=cgetr(3);z[2]=0;z[1]=HIGHEXPOBIT-(lg(x)<<TWOPOTBITS_IN_LONG);return z;
207: }
208: setsigne(y,-s);z=PariAddrrDown(x,y);setsigne(y,s);return z;
209: }
210:
211: GEN
212: PariSubirDown(GEN x, GEN y)
213: {
214: long s=signe(y);
215: GEN z;
216:
217: setsigne(y,-s);z=PariAddirDown(x,y);setsigne(y,s);return z;
218: }
219:
220: GEN
221: PariSubriDown(GEN x, GEN y)
222: {
223: long s=signe(y);
224: GEN z;
225:
226: setsigne(y,-s);z=PariAddirDown(y,x);setsigne(y,s);return z;
227: }
228:
229: GEN
230: PariMulDown(GEN x, GEN y)
231: {
232: if(typ(x)==1) return (typ(y)==1) ? mulii(x,y) : PariMulirDown(x,y);
233: return (typ(y)==1) ? PariMulirDown(y,x) : PariMulrrDown(x,y);
234: }
235:
236: GEN
237: PariMulrrDown(GEN x, GEN y)
238: {
239: long i,j,lx=lg(x),ly=lg(y),sx=signe(x),sy=signe(y),ex=expo(x),ey=expo(y);
240: long e,flag,garde,p1,p2,lz;
241: GEN z;
242:
243: e=ex+ey+HIGHEXPOBIT;if(e>=EXPOBITS) err(muler4);
244: if(e<0) err(muler5);
245: if((!sx)||(!sy)) {z=cgetr(3);z[2]=0;z[1]=e;return z;}
246: if(sy<0) sx= -sx;
247: if(lx>ly) {lz=ly;z=x;x=y;y=z;flag=1;} else {lz=lx;flag=(lx!=ly);}
248: z=cgetr(lz);z[1]=evalsigne(sx)+e;
249: if(flag) mulll(x[2],y[lz]);else hiremainder=0;
250: if(lz==3)
251: {
252: garde=flag ? addmul(x[2],y[2]) : mulll(x[2],y[2]);
253: if((long)hiremainder<0) {z[2]=hiremainder;z[1]++;}
254: else {z[2]=(garde<0)?(hiremainder<<1)+1:(hiremainder<<1);}
255: return z;
256: }
257: p1=x[lz-1];garde=hiremainder;
258: if(p1)
259: {
260: mulll(p1,y[3]);p2=addmul(p1,y[2]);
261: garde=addll(p2,garde);z[lz-1]=overflow+hiremainder;
262: }
263: else z[lz-1]=0;
264: for(j=lz-2;j>=3;j--)
265: {
266: p1=x[j];
267: if(p1)
268: {
269: mulll(p1,y[lz+2-j]);
270: p2=addmul(p1,y[lz+1-j]);
271: garde=addll(p2,garde);hiremainder+=overflow;
272: for(i=lz-j;i>=2;i--)
273: {
274: p2=addmul(p1,y[i]);
275: z[i+j-1]=addll(p2,z[i+j-1]);hiremainder+=overflow;
276: }
277: z[j]=hiremainder;
278: }
279: else z[j]=0;
280: }
281: p1=x[2];p2=mulll(p1,y[lz-1]);
282: garde=addll(p2,garde);hiremainder+=overflow;
283: for(i=lz-2;i>=2;i--)
284: {
285: p2=addmul(p1,y[i]);
286: z[i+1]=addll(p2,z[i+1]);hiremainder+=overflow;
287: }
288: z[2]=hiremainder;
289: if((long)hiremainder>0)
290: {
291: overflow=(garde<0)?1:0;
292: for(i=lz-1;i>=2;i--) {p1=z[i];z[i]=addllx(p1,p1);}
293: }
294: else z[1]++;
295: return z;
296: }
297:
298: GEN
299: PariMulirDown(GEN x, GEN y)
300: {
301: long sx=signe(x),sy,av,lz,ey,e,garde,p1,p2,i,j;
302: GEN z,temp;
303:
304: if(!sx) return gzero;
305: sy=signe(y);ey=expo(y);
306: if(!sy)
307: {
308: z=cgetr(3);z[2]=0;e=expi(x)+ey+HIGHEXPOBIT;if(e>EXPOBITS) err(muler6);
309: z[1]=e;return z;
310: }
311: lz=lg(y);if(sy<0) sx= -sx;
312: z=cgetr(lz);av=avma;
313: temp=cgetr(lz+1);affir(x,temp);x=y;y=temp;
314: e=expo(y)+ey+HIGHEXPOBIT;if(e>=EXPOBITS) err(muler4);
315: if(e<0) err(muler5);
316: z[1]=evalsigne(sx)+e;
317: mulll(x[2],y[lz]);
318: if(lz==3)
319: {
320: garde=addmul(x[2],y[2]);
321: if((long)hiremainder<0) {z[2]=hiremainder;z[1]++;}
322: else {z[2]=(garde<0)?(hiremainder<<1)+1:(hiremainder<<1);}
323: avma=av;return z;
324: }
325: garde=hiremainder;
326: p1=x[lz-1];mulll(p1,y[3]);p2=addmul(p1,y[2]);
327: garde=addll(p2,garde);z[lz-1]=overflow+hiremainder;
328: for(j=lz-2;j>=3;j--)
329: {
330: p1=x[j];mulll(p1,y[lz+2-j]);
331: p2=addmul(p1,y[lz+1-j]);
332: garde=addll(p2,garde);hiremainder+=overflow;
333: for(i=lz-j;i>=2;i--)
334: {
335: p2=addmul(p1,y[i]);
336: z[i+j-1]=addll(p2,z[i+j-1]);hiremainder+=overflow;
337: }
338: z[j]=hiremainder;
339: }
340: p1=x[2];p2=mulll(p1,y[lz-1]);
341: garde=addll(p2,garde);hiremainder+=overflow;
342: for(i=lz-2;i>=2;i--)
343: {
344: p2=addmul(p1,y[i]);
345: z[i+1]=addll(p2,z[i+1]);hiremainder+=overflow;
346: }
347: z[2]=hiremainder;
348: if((long)hiremainder>0)
349: {
350: overflow=(garde<0)?1:0;
351: for(i=lz-1;i>=2;i--) {p1=z[i];z[i]=addllx(p1,p1);}
352: }
353: else z[1]++;
354: avma=av;return z;
355: }
356:
1.3 ohara 357: #if defined(LONG_IS_32BIT)
1.1 saito 358: #define DIVCONVI 14
359: #endif
360:
1.3 ohara 361: #if defined(LONG_IS_64BIT)
1.1 saito 362: #define DIVCONVI 7
363: #endif
364:
365: GEN
366: PariDivDown(GEN x, GEN y)
367: {
368: if(typ(x)==1) return (typ(y)==1) ? divii(x,y) : PariDivirDown(x,y);
369: return (typ(y)==1) ? PariDivriDown(x,y) : PariDivrrDown(x,y);
370: }
371:
372: GEN
373: PariDivirDown(GEN x, GEN y)
374: {
375: GEN xr,z;
376: long av,ly;
377:
378: if(!signe(y)) err(diver5);
379: if(!signe(x)) return gzero;
380: ly=lg(y);z=cgetr(ly);av=avma;affir(x,xr=cgetr(ly+1));
381: xr=PariDivrrDown(xr,y);affrr(xr,z);avma=av;return z;
382: }
383:
384: GEN
385: PariDivriDown(GEN x, GEN y)
386: {
387: GEN yr,z;
388: long av,lx,ex,s=signe(y);
389:
390: if(!s) err(diver8);
391: if(!signe(x))
392: {
393: ex=expo(x)-expi(y)+HIGHEXPOBIT;
394: if(ex<0) err(diver12);
395: z=cgetr(3);z[1]=ex;z[2]=0;return z;
396: }
397: if((lg(y)==3)&&(y[2]>0)) return (s>0) ? divrs(x,y[2]) : divrs(x,-y[2]);
398: lx=lg(x);z=cgetr(lx);av=avma;affir(y,yr=cgetr(lx+1));
399: yr=PariDivrrDown(x,yr);affrr(yr,z);avma=av;return z;
400: }
401:
402: GEN
403: PariDivrrDown(GEN x, GEN y)
404: {
405: long sx=signe(x),sy=signe(y),lx,ly,lz,ex,ex1,i,z0;
406: ulong ldif,y0,y1,si,saux,qp,k,k3,k4,j;
407: GEN z;
408: if(!sy) err(diver9);
409: ex=expo(x)-expo(y)+HIGHEXPOBIT;
410: if(ex<=0) err(diver10);
411: if(ex>EXPOBITS) err(diver11);
412: if(!sx)
413: {
414: z=cgetr(3);z[1]=ex;z[2]=0;return z;
415: }
416: lx=lg(x);ly=lg(y);lz=(lx<=ly)?lx:ly;
417: z=cgetr(lz);if(sy<0) sx= -sx;
418: ex1=evalsigne(sx)+ex;
419: if(ly==3)
420: {
421: i=x[2];si=(lx>3)?x[3]:0;
422: if((ulong)i<(ulong)y[2])
423: {
424: hiremainder=i;z[2]=divll(si,y[2]);
425: z[1]=ex1-1;return z;
426: }
427: else
428: {
429: hiremainder=((ulong)i)>>1;
430: z[2]=(i&1)?divll((((ulong)si)>>1)|(HIGHBIT),y[2]):divll(((ulong)si)>>1,y[2]);
431: z[1]=ex1;return z;
432: }
433: }
434: z0= *z;*z=0;
435: for(i=2;i<=lz-1;i++) z[i-1]=x[i];
436: z[lz-1]=(lx>lz) ? x[lz] : 0;
437: ldif=ly-lz;if(!ldif) {y0=y[lz];y[lz]=0;}
438: if(ldif<=1) {y1=y[lz+1];y[lz+1]=0;}
439: si=y[2];saux=y[3];
440: for(i=0;i<lz-1;i++)
441: {
442: if(z[i]!=si)
443: {
444: if((ulong)z[i]>si)
445: {
446: overflow=0;
447: for(j=lz-i+1;j>=2;j--) z[i+j-2]=subllx(z[i+j-2],y[j]);
448: {z[i-1]++;for(j=i-1;j&&(!z[j]);j--) z[j-1]++;}
449: }
450: hiremainder=z[i];qp=divll(z[i+1],si);
451: overflow=0;k=hiremainder;
452: }
453: else
454: {
455: qp=(long)MAXULONG;k=addll(si,z[i+1]);
456: }
457: if(!overflow)
458: {
459: k3=subll(mulll(qp,saux),z[i+2]);k4=subllx(hiremainder,k);
460: while((!overflow)&&k4) {qp--;k3=subll(k3,saux);k4=subllx(k4,si);}
461: }
462: mulll(qp,y[lz+1-i]);
463: for(j=lz-i;j>=2;j--)
464: {
465: z[i+j-1]=subll(z[i+j-1],addmul(qp,y[j]));hiremainder+=overflow;
466: }
467: if((ulong)z[i]!=(ulong)hiremainder)
468: {
469: if((ulong)z[i]<(ulong)hiremainder)
470: {
471: overflow=0;qp--;
472: for(j=lz-i;j>=2;j--) z[i+j-1]=addllx(z[i+j-1],y[j]);
473: }
474: else
475: {
476: z[i]-=hiremainder;
477: while(z[i])
478: {
479: overflow=0;qp++;
480: if(!qp) {z[i-1]++;for(j=i-1;j&&(!z[j]);j--) z[j-1]++;}
481: for(j=lz-i;j>=2;j--) z[i+j-1]=subllx(z[i+j-1],y[j]);
482: z[i]-=overflow;
483: }
484: }
485: }
486: z[i]=qp;
487: }
488: if(!ldif) y[lz]=y0;if(ldif<=1) y[lz+1]=y1;
489: for(j=lz-1;j>=2;j--) z[j]=z[j-1];
490: if(*z)
491: {
492: k=HIGHBIT;
493: for(j=2;j<lz;j++) {z[j]=shiftlr(z[j],1)+k;k=hiremainder;}
494: }
495: else ex1--;
496: z[1]=ex1;*z=z0;return z;
497: }
498:
1.2 noro 499: #endif /* PARI */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>