Annotation of OpenXM_contrib/pari-2.2/src/kernel/none/level1.h, Revision 1.2
1.2 ! noro 1: /* $Id: level1.h,v 1.18 2002/06/08 13:07:03 karim Exp $
1.1 noro 2:
3: Copyright (C) 2000 The PARI group.
4:
5: This file is part of the PARI/GP package.
6:
7: PARI/GP is free software; you can redistribute it and/or modify it under the
8: terms of the GNU General Public License as published by the Free Software
9: Foundation. It is distributed in the hope that it will be useful, but WITHOUT
10: ANY WARRANTY WHATSOEVER.
11:
12: Check the License for details. You should have received a copy of it, along
13: with the package; see the file 'COPYING'. If not, write to the Free Software
14: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
15:
16: /* This file defines some "level 1" kernel functions */
17: /* These functions can be inline, with gcc */
18: /* If not gcc, they are defined externally with "level1.c" */
19:
20: /* level1.c includes this file and never needs to be changed */
21: /* The following seven lines are necessary for level0.c and level1.c */
22: #ifdef LEVEL1
23: # undef INLINE
24: # define INLINE
25: #endif
26: #ifdef LEVEL0
27: # undef INLINE
28: #endif
29:
30: #ifndef INLINE
31: void addsii(long x, GEN y, GEN z);
32: long addssmod(long a, long b, long p);
33: void addssz(long x, long y, GEN z);
34: void affii(GEN x, GEN y);
35: void affsi(long s, GEN x);
1.2 ! noro 36: void affui(long s, GEN x);
1.1 noro 37: void affsr(long s, GEN x);
38: GEN cgetg(long x, long y);
39: GEN cgeti(long x);
40: GEN cgetr(long x);
41: int cmpir(GEN x, GEN y);
42: int cmpsr(long x, GEN y);
43: int divise(GEN x, GEN y);
44: long divisii(GEN x, long y, GEN z);
45: void divisz(GEN x, long y, GEN z);
46: void divrrz(GEN x, GEN y, GEN z);
47: void divsiz(long x, GEN y, GEN z);
48: GEN divss(long x, long y);
49: long divssmod(long a, long b, long p);
50: void divssz(long x, long y, GEN z);
51: void dvmdiiz(GEN x, GEN y, GEN z, GEN t);
52: GEN dvmdis(GEN x, long y, GEN *z);
53: void dvmdisz(GEN x, long y, GEN z, GEN t);
54: GEN dvmdsi(long x, GEN y, GEN *z);
55: void dvmdsiz(long x, GEN y, GEN z, GEN t);
56: GEN dvmdss(long x, long y, GEN *z);
57: void dvmdssz(long x, long y, GEN z, GEN t);
58: long evallg(long x);
59: long evallgef(long x);
60: long evalvalp(long x);
61: long evalexpo(long x);
62: long expi(GEN x);
63: double gtodouble(GEN x);
64: GEN icopy(GEN x);
65: GEN icopy_av(GEN x, GEN y);
1.2 ! noro 66: GEN itor(GEN x, long prec);
1.1 noro 67: long itos(GEN x);
1.2 ! noro 68: ulong itou(GEN x);
1.1 noro 69: GEN modis(GEN x, long y);
70: GEN mpabs(GEN x);
71: GEN mpadd(GEN x, GEN y);
72: void mpaff(GEN x, GEN y);
73: int mpcmp(GEN x, GEN y);
74: GEN mpcopy(GEN x);
75: GEN mpdiv(GEN x, GEN y);
76: int mpdivis(GEN x, GEN y, GEN z);
77: int mpdivisis(GEN x, long y, GEN z);
78: GEN mpmul(GEN x, GEN y);
79: GEN mpneg(GEN x);
80: GEN mpsub(GEN x, GEN y);
81: void mulsii(long x, GEN y, GEN z);
82: long mulssmod(ulong a, ulong b, ulong c);
83: void mulssz(long x, long y, GEN z);
84: GEN new_chunk(long x);
85: GEN realun(long prec);
86: GEN realzero(long prec);
1.2 ! noro 87: GEN realzero_bit(long bitprec);
1.1 noro 88: void resiiz(GEN x, GEN y, GEN z);
89: GEN resis(GEN x, long y);
90: GEN ressi(long x, GEN y);
91: GEN shiftr(GEN x, long n);
92: long smodis(GEN x, long y);
1.2 ! noro 93: GEN stor(long x, long prec);
1.1 noro 94: GEN stoi(long x);
95: GEN subii(GEN x, GEN y);
96: GEN subir(GEN x, GEN y);
97: GEN subri(GEN x, GEN y);
98: GEN subrr(GEN x, GEN y);
99: GEN subsi(long x, GEN y);
100: GEN subsr(long x, GEN y);
101: long subssmod(long a, long b, long p);
102: GEN utoi(ulong x);
103: long vali(GEN x);
104:
105: #else /* defined(INLINE) */
106: INLINE long
107: evallg(long x)
108: {
109: if (x & ~LGBITS) err(errlg);
1.2 ! noro 110: return _evallg(x);
1.1 noro 111: }
112:
113: INLINE long
114: evallgef(long x)
115: {
116: if (x & ~LGEFBITS) err(errlgef);
1.2 ! noro 117: return _evallgef(x);
1.1 noro 118: }
119:
120: INLINE long
121: evalvalp(long x)
122: {
1.2 ! noro 123: const long v = _evalvalp(x);
1.1 noro 124: if (v & ~VALPBITS) err(errvalp);
125: return v;
126: }
127:
128: INLINE long
129: evalexpo(long x)
130: {
1.2 ! noro 131: const long v = _evalexpo(x);
1.1 noro 132: if (v & ~EXPOBITS) err(errexpo);
133: return v;
134: }
135:
136: INLINE GEN
137: new_chunk(long x)
138: {
139: const GEN z = ((GEN) avma) - x;
140: if ((ulong)x > (ulong)((GEN)avma-(GEN)bot)) err(errpile);
141: #ifdef MEMSTEP
142: checkmemory(z);
143: #endif
144: #ifdef _WIN32
145: if (win32ctrlc) dowin32ctrlc();
146: #endif
1.2 ! noro 147: avma = (gpmem_t)z; return z;
1.1 noro 148: }
149:
150: /* THE FOLLOWING ONES ARE IN mp.s */
151: # ifndef __M68K__
152:
153: INLINE GEN
154: cgetg(long x, long y)
155: {
156: const GEN z = new_chunk(x);
157: z[0] = evaltyp(y) | evallg(x);
158: return z;
159: }
160:
161: INLINE GEN
162: cgeti(long x)
163: {
164: const GEN z = new_chunk(x);
165: z[0] = evaltyp(t_INT) | evallg(x);
166: return z;
167: }
168:
169: INLINE GEN
170: cgetr(long x)
171: {
172: const GEN z = new_chunk(x);
173: z[0] = evaltyp(t_REAL) | evallg(x);
174: return z;
175: }
176: # endif /* __M68K__ */
177:
178: /* cannot do memcpy because sometimes x and y overlap */
179: INLINE GEN
180: mpcopy(GEN x)
181: {
182: register long lx = lg(x);
183: const GEN y = new_chunk(lx);
184:
185: while (--lx >= 0) y[lx]=x[lx];
186: return y;
187: }
188:
189: INLINE GEN
190: icopy(GEN x)
191: {
192: register long lx = lgefint(x);
193: const GEN y = cgeti(lx);
194:
195: while (--lx > 0) y[lx]=x[lx];
196: return y;
197: }
198:
199: /* copy integer x as if we had avma = av */
200: INLINE GEN
201: icopy_av(GEN x, GEN y)
202: {
203: register long lx = lgefint(x);
204:
205: y -= lx; while (--lx >= 0) y[lx]=x[lx];
206: return y;
207: }
208:
209: INLINE GEN
210: mpneg(GEN x)
211: {
212: const GEN y=mpcopy(x);
213: setsigne(y,-signe(x)); return y;
214: }
215:
216: INLINE GEN
217: mpabs(GEN x)
218: {
219: const GEN y=mpcopy(x);
220: if (signe(x)<0) setsigne(y,1);
221: return y;
222: }
223:
224: INLINE long
225: smodis(GEN x, long y)
226: {
1.2 ! noro 227: const gpmem_t av=avma; divis(x,y); avma=av;
1.1 noro 228: if (!hiremainder) return 0;
229: return (signe(x)>0) ? hiremainder: labs(y)+hiremainder;
230: }
231:
232: INLINE GEN
233: utoi(ulong x)
234: {
235: GEN y;
236:
237: if (!x) return gzero;
238: y=cgeti(3); y[1] = evalsigne(1) | evallgefint(3); y[2] = x;
239: return y;
240: }
241:
242: INLINE GEN stoi(long);
243: INLINE GEN realzero(long);
244:
245: INLINE GEN
246: stosmall(long x)
247: {
248: if (labs(x) & SMALL_MASK) return stoi(x);
249: return (GEN) (1 | (x<<1));
250: }
251:
252: # ifndef __M68K__
253: INLINE GEN
254: stoi(long x)
255: {
256: GEN y;
257:
258: if (!x) return gzero;
259: y=cgeti(3);
260: if (x>0) { y[1] = evalsigne(1) | evallgefint(3); y[2] = x; }
261: else { y[1] = evalsigne(-1) | evallgefint(3); y[2] = -x; }
262: return y;
263: }
264:
265: INLINE long
266: itos(GEN x)
267: {
1.2 ! noro 268: const long s = signe(x);
! 269: long u;
1.1 noro 270:
271: if (!s) return 0;
1.2 ! noro 272: u = (long)x[2]; if (lgefint(x) > 3 || u < 0) err(affer2);
! 273: return (s>0) ? u : -u;
1.1 noro 274: }
275:
276: INLINE void
277: affii(GEN x, GEN y)
278: {
279: long lx;
280:
281: if (x==y) return;
282: lx=lgefint(x); if (lg(y)<lx) err(affer3);
283: while (--lx) y[lx]=x[lx];
284: }
285:
286: INLINE void
287: affsi(long s, GEN x)
288: {
1.2 ! noro 289: if (!s) x[1] = evalsigne(0) | evallgefint(2);
! 290: else
! 291: {
! 292: if (lg(x) < 3) err(affer1);
! 293: if (s > 0) { x[1] = evalsigne( 1) | evallgefint(3); x[2] = s; }
! 294: else { x[1] = evalsigne(-1) | evallgefint(3); x[2] = -s; }
! 295: }
1.1 noro 296: }
297:
298: INLINE void
299: affsr(long s, GEN x)
300: {
301: long l;
302:
303: if (!s)
304: {
1.2 ! noro 305: x[1] = evalexpo(-bit_accuracy(lg(x)));
! 306: return;
1.1 noro 307: }
308: if (s<0) { x[1] = evalsigne(-1); s = -s; }
309: else x[1] = evalsigne(1);
310: l=bfffo(s); x[1] |= evalexpo((BITS_IN_LONG-1)-l);
311: x[2] = s<<l; for (l=3; l<lg(x); l++) x[l]=0;
312: }
313:
314: INLINE void
315: mpaff(GEN x, GEN y)
316: {
317: if (typ(x)==t_INT)
318: { if (typ(y)==t_INT) affii(x,y); else affir(x,y); }
319: else
320: { if (typ(y)==t_INT) affri(x,y); else affrr(x,y); }
321: }
322:
323: INLINE GEN
324: shiftr(GEN x, long n)
325: {
326: const long e = evalexpo(expo(x)+n);
327: const GEN y = rcopy(x);
328:
329: if (e & ~EXPOBITS) err(shier2);
330: y[1] = (y[1]&~EXPOBITS) | e; return y;
331: }
332:
333: INLINE int
334: cmpir(GEN x, GEN y)
335: {
1.2 ! noro 336: gpmem_t av;
1.1 noro 337: GEN z;
338:
339: if (!signe(x)) return -signe(y);
1.2 ! noro 340: if (!signe(y)) return signe(x);
1.1 noro 341: av=avma; z=cgetr(lg(y)); affir(x,z); avma=av;
342: return cmprr(z,y); /* cmprr does no memory adjustment */
343: }
344:
345: INLINE int
346: cmpsr(long x, GEN y)
347: {
1.2 ! noro 348: gpmem_t av;
1.1 noro 349: GEN z;
350:
351: if (!x) return -signe(y);
352: av=avma; z=cgetr(3); affsr(x,z); avma=av;
353: return cmprr(z,y);
354: }
355:
356: INLINE void
357: addssz(long x, long y, GEN z)
358: {
359: if (typ(z)==t_INT) gops2ssz(addss,x,y,z);
360: else
361: {
1.2 ! noro 362: const gpmem_t av=avma;
1.1 noro 363: const GEN p1=cgetr(lg(z));
364:
365: affsr(x,p1); affrr(addrs(p1,y),z); avma=av;
366: }
367: }
368:
369: INLINE GEN
370: subii(GEN x, GEN y)
371: {
372: const long s=signe(y);
373: GEN z;
374:
375: if (x==y) return gzero;
376: setsigne(y,-s); z=addii(x,y);
377: setsigne(y, s); return z;
378: }
379:
380: INLINE GEN
381: subrr(GEN x, GEN y)
382: {
383: const long s=signe(y);
384: GEN z;
385:
386: if (x==y) return realzero(lg(x)+2);
387: setsigne(y,-s); z=addrr(x,y);
388: setsigne(y, s); return z;
389: }
390:
391: INLINE GEN
392: subir(GEN x, GEN y)
393: {
394: const long s=signe(y);
395: GEN z;
396:
397: setsigne(y,-s); z=addir(x,y);
398: setsigne(y, s); return z;
399: }
400:
401: INLINE GEN
402: subri(GEN x, GEN y)
403: {
404: const long s=signe(y);
405: GEN z;
406:
407: setsigne(y,-s); z=addir(y,x);
408: setsigne(y, s); return z;
409: }
410:
411: INLINE GEN
412: subsi(long x, GEN y)
413: {
414: const long s=signe(y);
415: GEN z;
416:
417: setsigne(y,-s); z=addsi(x,y);
418: setsigne(y, s); return z;
419: }
420:
421: INLINE GEN
422: subsr(long x, GEN y)
423: {
424: const long s=signe(y);
425: GEN z;
426:
427: setsigne(y,-s); z=addsr(x,y);
428: setsigne(y, s); return z;
429: }
430:
431: INLINE void
432: mulssz(long x, long y, GEN z)
433: {
434: if (typ(z)==t_INT) gops2ssz(mulss,x,y,z);
435: else
436: {
1.2 ! noro 437: const gpmem_t av=avma;
1.1 noro 438: const GEN p1=cgetr(lg(z));
439:
440: affsr(x,p1); mpaff(mulsr(y,p1),z); avma=av;
441: }
442: }
443:
444: INLINE void
445: mulsii(long x, GEN y, GEN z)
446: {
1.2 ! noro 447: const gpmem_t av=avma;
1.1 noro 448: affii(mulsi(x,y),z); avma=av;
449: }
450:
451: INLINE void
452: addsii(long x, GEN y, GEN z)
453: {
1.2 ! noro 454: const gpmem_t av=avma;
1.1 noro 455: affii(addsi(x,y),z); avma=av;
456: }
457:
458: INLINE long
459: divisii(GEN x, long y, GEN z)
460: {
1.2 ! noro 461: const gpmem_t av=avma;
1.1 noro 462: affii(divis(x,y),z); avma=av; return hiremainder;
463: }
464:
465: INLINE long
466: vali(GEN x)
467: {
468: long lx,i;
469:
470: if (!signe(x)) return -1;
471: i = lx = lgefint(x)-1; while (!x[i]) i--;
472: return ((lx-i)<<TWOPOTBITS_IN_LONG) + vals(x[i]);
473: }
474:
475: INLINE GEN
476: divss(long x, long y)
477: {
478: long p1;
479: LOCAL_HIREMAINDER;
480:
481: if (!y) err(diver1);
482: hiremainder=0; p1 = divll((ulong)labs(x),(ulong)labs(y));
483: if (x<0) { hiremainder = -((long)hiremainder); p1 = -p1; }
484: if (y<0) p1 = -p1;
485: SAVE_HIREMAINDER; return stoi(p1);
486: }
487:
488: INLINE GEN
489: dvmdss(long x, long y, GEN *z)
490: {
491: const GEN p1=divss(x,y);
492: *z = stoi(hiremainder); return p1;
493: }
494:
495: INLINE GEN
496: dvmdsi(long x, GEN y, GEN *z)
497: {
498: const GEN p1=divsi(x,y);
499: *z = stoi(hiremainder); return p1;
500: }
501:
502: INLINE GEN
503: dvmdis(GEN x, long y, GEN *z)
504: {
505: const GEN p1=divis(x,y);
506: *z=stoi(hiremainder); return p1;
507: }
508:
509: INLINE void
510: dvmdssz(long x, long y, GEN z, GEN t)
511: {
1.2 ! noro 512: const gpmem_t av=avma;
1.1 noro 513: const GEN p1=divss(x,y);
514:
515: affsi(hiremainder,t); mpaff(p1,z); avma=av;
516: }
517:
518: INLINE void
519: dvmdsiz(long x, GEN y, GEN z, GEN t)
520: {
1.2 ! noro 521: const gpmem_t av=avma;
1.1 noro 522: const GEN p1=divsi(x,y);
523:
524: affsi(hiremainder,t); mpaff(p1,z); avma=av;
525: }
526:
527: INLINE void
528: dvmdisz(GEN x, long y, GEN z, GEN t)
529: {
1.2 ! noro 530: const gpmem_t av=avma;
1.1 noro 531: const GEN p1=divis(x,y);
532:
533: affsi(hiremainder,t); mpaff(p1,z); avma=av;
534: }
535:
536: INLINE void
537: dvmdiiz(GEN x, GEN y, GEN z, GEN t)
538: {
1.2 ! noro 539: const gpmem_t av=avma;
1.1 noro 540: GEN p;
541:
542: mpaff(dvmdii(x,y,&p),z); mpaff(p,t); avma=av;
543: }
544:
545: INLINE GEN
546: modis(GEN x, long y)
547: {
548: return stoi(smodis(x,y));
549: }
550:
551: INLINE GEN
552: ressi(long x, GEN y)
553: {
1.2 ! noro 554: const gpmem_t av=avma;
1.1 noro 555: divsi(x,y); avma=av; return stoi(hiremainder);
556: }
557:
558: INLINE GEN
559: resis(GEN x, long y)
560: {
1.2 ! noro 561: const gpmem_t av=avma;
1.1 noro 562: divis(x,y); avma=av; return stoi(hiremainder);
563: }
564:
565: INLINE void
566: divisz(GEN x, long y, GEN z)
567: {
568: if (typ(z)==t_INT) gops2gsz(divis,x,y,z);
569: else
570: {
1.2 ! noro 571: const gpmem_t av=avma;
1.1 noro 572: const GEN p1=cgetr(lg(z));
573:
574: affir(x,p1); affrr(divrs(p1,y),z); avma=av;
575: }
576: }
577:
578: INLINE void
579: divsiz(long x, GEN y, GEN z)
580: {
1.2 ! noro 581: const gpmem_t av=avma;
1.1 noro 582:
583: if (typ(z)==t_INT) gaffect(divsi(x,y),z);
584: else
585: {
586: const long lz=lg(z);
587: const GEN p1=cgetr(lz), p2=cgetr(lz);
588:
589: affsr(x,p1); affir(y,p2);
590: affrr(divrr(p1,p2),z);
591: }
592: avma=av;
593: }
594:
595: INLINE void
596: divssz(long x, long y, GEN z)
597: {
1.2 ! noro 598: const gpmem_t av=avma;
1.1 noro 599:
600: if (typ(z)==t_INT) gaffect(divss(x,y),z);
601: else
602: {
603: const GEN p1=cgetr(lg(z));
604:
605: affsr(x,p1); affrr(divrs(p1,y),z);
606: }
607: avma=av;
608: }
609:
610: INLINE void
611: divrrz(GEN x, GEN y, GEN z)
612: {
1.2 ! noro 613: const gpmem_t av=avma;
1.1 noro 614: mpaff(divrr(x,y),z); avma=av;
615: }
616:
617: INLINE void
618: resiiz(GEN x, GEN y, GEN z)
619: {
1.2 ! noro 620: const gpmem_t av=avma;
1.1 noro 621: affii(resii(x,y),z); avma=av;
622: }
623:
624: INLINE int
625: divise(GEN x, GEN y)
626: {
1.2 ! noro 627: const gpmem_t av=avma;
1.1 noro 628: const GEN p1=resii(x,y);
629: avma=av; return p1 == gzero;
630: }
631:
632: INLINE int
633: mpcmp(GEN x, GEN y)
634: {
635: if (typ(x)==t_INT)
636: return (typ(y)==t_INT) ? cmpii(x,y) : cmpir(x,y);
637: return (typ(y)==t_INT) ? -cmpir(y,x) : cmprr(x,y);
638: }
639:
640: INLINE GEN
641: mpadd(GEN x, GEN y)
642: {
643: if (typ(x)==t_INT)
644: return (typ(y)==t_INT) ? addii(x,y) : addir(x,y);
645: return (typ(y)==t_INT) ? addir(y,x) : addrr(x,y);
646: }
647:
648: INLINE GEN
649: mpsub(GEN x, GEN y)
650: {
651: if (typ(x)==t_INT)
652: return (typ(y)==t_INT) ? subii(x,y) : subir(x,y);
653: return (typ(y)==t_INT) ? subri(x,y) : subrr(x,y);
654: }
655:
656: INLINE GEN
657: mpmul(GEN x, GEN y)
658: {
659: if (typ(x)==t_INT)
660: return (typ(y)==t_INT) ? mulii(x,y) : mulir(x,y);
661: return (typ(y)==t_INT) ? mulir(y,x) : mulrr(x,y);
662: }
663:
664: INLINE GEN
665: mpdiv(GEN x, GEN y)
666: {
667: if (typ(x)==t_INT)
668: return (typ(y)==t_INT) ? divii(x,y) : divir(x,y);
669: return (typ(y)==t_INT) ? divri(x,y) : divrr(x,y);
670: }
671:
672: INLINE int
673: mpdivis(GEN x, GEN y, GEN z)
674: {
1.2 ! noro 675: const gpmem_t av=avma;
1.1 noro 676: GEN p2;
677: const GEN p1=dvmdii(x,y,&p2);
678:
679: if (signe(p2)) { avma=av; return 0; }
680: affii(p1,z); avma=av; return 1;
681: }
682:
683: /* THE FOLLOWING ONES ARE NOT IN mp.s */
684: # endif /* !defined(__M68K__) */
685:
1.2 ! noro 686: INLINE ulong
! 687: itou(GEN x)
! 688: {
! 689: const long s = signe(x);
! 690:
! 691: if (!s) return 0;
! 692: if (lgefint(x) > 3) err(affer2);
! 693: return x[2];
! 694: }
! 695:
! 696: INLINE void
! 697: affui(ulong u, GEN x)
! 698: {
! 699: if (!u) x[1] = evalsigne(0) | evallgefint(2);
! 700: else
! 701: {
! 702: if (lg(x) < 3) err(affer1);
! 703: x[1] = evalsigne(1) | evallgefint(3); x[2] = u;
! 704: }
! 705: }
! 706:
1.1 noro 707: INLINE int
708: mpdivisis(GEN x, long y, GEN z)
709: {
1.2 ! noro 710: const gpmem_t av = avma;
1.1 noro 711: GEN p1 = divis(x,y);
712: if (hiremainder) { avma = av; return 0; }
713: affii(p1,z); avma = av; return 1;
714: }
715:
716: INLINE double
717: gtodouble(GEN x)
718: {
1.2 ! noro 719: static long reel4[4]={ evaltyp(t_REAL) | _evallg(4),0,0,0 };
1.1 noro 720:
721: if (typ(x)==t_REAL) return rtodbl(x);
722: gaffect(x,(GEN)reel4); return rtodbl((GEN)reel4);
723: }
724:
725: INLINE GEN
1.2 ! noro 726: realzero_bit(long bitprec) { GEN x=cgetr(2); x[1]=evalexpo(bitprec); return x; }
! 727:
! 728: INLINE GEN
! 729: realzero(long prec) { return realzero_bit(-bit_accuracy(prec)); }
! 730:
! 731: INLINE GEN
! 732: realun(long prec) { GEN x=cgetr(prec); affsr(1,x); return x; }
! 733:
! 734: INLINE GEN
! 735: stor(long s, long prec) { GEN z = cgetr(prec); affsr(s,z); return z; }
1.1 noro 736:
737: INLINE GEN
1.2 ! noro 738: itor(GEN x, long prec) { GEN z = cgetr(prec); affir(x,z); return z; }
1.1 noro 739:
740: INLINE long
741: addssmod(long a, long b, long p)
742: {
743: ulong res = a + b;
744: return (res >= (ulong)p) ? res - p : res;
745: }
746:
747: INLINE long
748: subssmod(long a, long b, long p)
749: {
750: long res = a - b;
751: return (res >= 0) ? res : res + p;
752: }
753:
754: INLINE long
755: mulssmod(ulong a, ulong b, ulong c)
756: {
757: LOCAL_HIREMAINDER;
758: {
759: register ulong x = mulll(a,b);
760:
761: /* alter the doubleword by a multiple of c: */
762: if (hiremainder>=c) hiremainder %= c;
763: (void)divll(x,c);
764: }
765: return hiremainder;
766: }
767:
768: INLINE long
769: divssmod(long a, long b, long p)
770: {
771: long v1 = 0, v2 = 1, v3, r, oldp = p;
772:
773: while (b > 1)
774: {
775: v3 = v1 - (p / b) * v2; v1 = v2; v2 = v3;
776: r = p % b; p = b; b = r;
777: }
778:
779: if (v2 < 0) v2 += oldp;
780: return mulssmod(a, v2, oldp);
781: }
782:
783: INLINE long
784: expi(GEN x)
785: {
786: const long lx=lgefint(x);
787: return lx==2? -HIGHEXPOBIT: bit_accuracy(lx)-bfffo(x[2])-1;
788: }
789:
790: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>