home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-12-14 | 31.3 KB | 1,189 lines |
- /*********************************************************************/
- /*********************************************************************/
- /** **/
- /** FONCTIONS ARITHMETIQUES **/
- /** **/
- /** (deuxieme partie) **/
- /** **/
- /** copyright Babe Cool **/
- /** **/
- /** **/
- /*********************************************************************/
- /*********************************************************************/
-
- #include "genpari.h"
-
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
- /*~ ~*/
- /*~ NOMBRES PREMIERS ~*/
- /*~ ~*/
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-
- GEN prime (n)
- long n;
-
- {
- byteptr p=diffptr;
- long c,prime=0;
- while (n--) if (c= *p++) prime += c; else err(primer1);
- return stoi(prime);
- }
-
- GEN primes (n)
- long n;
-
- {
- GEN y,z;
- byteptr p=diffptr;
- long c,prime=0;
- z=y=cgetg(n+1,17);
- while (n--)
- {
- if (c= *p++) prime+=c; else err(primer1);
- *++z=(long)stoi(prime);
- }
- return y;
- }
-
- byteptr initprimes(maxnum)
- long maxnum;
- {
- register long k,size=(maxnum+257)>>1;
- byteptr p=(byteptr)calloc(size,1);
- register byteptr q,r,s,fin=p+size;
- for(r=q=p,k=1;r<fin;)
- {
- do {r+=k; k+=2; r+=k;} while (*++q);
- for(s=r;s<fin;s+=k) *s=1;
- }
- r=p; *r++=2; *r++=1;
- for(s=q=r-1;;)
- {
- while (*++q);
- if (q>=fin) break;
- *r++=(q-s)<<1;
- s=q;
- }
- *r++=0;
- return (byteptr)realloc(p,r-p);
- }
-
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
- /*~ ~*/
- /*~ FONCTIONS ARITHMETIQUES DE BASE ~*/
- /*~ ~*/
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
- /* Attention, le parametre doit etre une variable. */
- #define pseudoprime(p) millerrabin(p,5*lgef(p))
-
- long mu(n)
- GEN n;
-
- {
- byteptr d=diffptr;
- unsigned char c;
- GEN p, f;
- long av=avma,s=1;
- if (typ(n)!=1) err(arither1);
- if (!signe(n)) err(arither2);
- if ((n[2]==1)&&(lgef(n)==3)) return 1;
- n=absi(n);
- p=cgeti(3);p[1]=0x1000003;p[2]=0;
- while (c= *d++)
- {
- p[2]+=c;
- if (!mpdivis(n,p,n)) continue;
- if (divise(n,p)) {avma=av;return 0;}
- s= -s;
- if ((n[2]==1)&&(lgef(n)==3)) break;
- }
- while ((n[2]!=1)||(lgef(n)!=3))
- {
- f=gcopy(n);
- while (!((cmpii(mulii(p,p),f)>0)||pseudoprime(f))) f=ellfacteur(f);
- diviiz(n,f,n);
- if (divise(n,f)) {avma=av;return 0;}
- s= -s;
- }
- avma=av;
- return s;
- }
-
- GEN phi(n)
- GEN n;
-
- {
- byteptr d=diffptr;
- unsigned char c;
- GEN f,p,m;
- long av1,av2;
-
- if (typ(n)!=1) err(arither1);
- if (!signe(n)) err(arither2);
- if ((n[2]==1)&&(lgef(n)==3)) return stoi(1);
- m=cgeti(lgef(n));affsi(1,m);
- av1=avma;
- n=absi(n);
- p=cgeti(3);p[1]=0x1000003;p[2]=0;
- av2=avma;
- while (c= *d++)
- {
- p[2]+=c;
- if (!mpdivis(n,p,n)) continue;
- muliiz(m,subis(p,1),m);
- while (mpdivis(n,p,n)) muliiz(m,p,m);
- if ((n[2]==1)&&(lgef(n)==3)) break;
- avma=av2;
- }
- while ((n[2]!=1) || (lgef(n)!=3))
- {
- f=gcopy(n);
- while (!((cmpii(mulii(p,p),f)>0) || pseudoprime(f))) f = ellfacteur(f);
- mpdivis(n,f,n);
- muliiz(m,subis(f,1),m);
- while (mpdivis(n,f,n)) muliiz(m,f,m);
- avma=av2;
- }
- avma=av1;
- return m;
- }
-
- GEN auxdecomp(n,all)
- GEN n; long all;
-
- {
- byteptr d=diffptr;
- unsigned char c;
- GEN p,z,p1,p2,f;
- long nb=0,j,k,lim,av1,av2,av3,av4,sn;
-
- if (typ(n)!=1) err(arither1);
- if (!(sn=signe(n))) err(arither2);
- if(sn<0) {stoi(-1);stoi(1);nb++;}
- if ((n[2]!=1) || (lgef(n)!=3))
- {
- av1=avma;
- n=absi(n);
- p=cgeti(3);p[1]=0x1000003;p[2]=0;
- av2=avma;lim=(all<=1)?VERYBIGINT:all;
- while ((c= *d++)&&(p[2]<=lim))
- {
- p[2]+=c;
- if (!mpdivis(n,p,n)) continue;
- nb++;
- for (k=1;mpdivis(n,p,n);k++);
- gcopy(p);
- stoi(k);
- if ((n[2]==1)&&(lgef(n)==3)) break;
- }
- while ((n[2]!=1)||(lgef(n)!=3))
- {
- av3=avma;
- f=n;
- if(all==1)
- while (!((cmpii(mulii(p,p),f)>0)||pseudoprime(f))) f=ellfacteur(f);
- av4=avma;
- f=gerepile(av3,av4,gcopy(f));
- nb++;
- for (k=0;mpdivis(n,f,n);k++);
- stoi(k);
- }
- gerepile(av1,av2,0);
- }
- p=(GEN)avma;
- z=cgetg(3,19);
- p1=cgetg(nb+1,18);z[1]=(long)p1;
- p2=cgetg(nb+1,18);z[2]=(long)p2;
- for (j=nb;j;j--)
- {
- p2[j]=(long)p;
- p+=lg(p);
- p1[j]=(long)p;
- p+=lg(p);
- }
- return z;
- }
-
- GEN decomp(n)
- GEN n;
- {
- return auxdecomp(n,1);
- }
-
- GEN smallfact(n)
- GEN n;
- {
- GEN p1,p2,p3,p4,p5,y;
- long av,tetpil;
-
- switch(typ(n))
- {
- case 1:return auxdecomp(n,0);
- case 5:av=avma;n=gred(n);
- case 4:if(typ(n)==4) av=avma;p1=auxdecomp(n[1],0);
- p2=auxdecomp(n[2],0);p4=concat(p1[1],p2[1]);
- p5=concat(p1[2],gneg(p2[2]));p3=indexsort(p4);
- tetpil=avma;y=cgetg(3,19);y[1]=(long)extract(p4,p3);
- y[2]=(long)extract(p5,p3);return gerepile(av,tetpil,y);
- default: err(arither1);
- }
- }
-
- GEN boundfact(n,lim)
- GEN n;
- long lim;
- {
- GEN p1,p2,p3,p4,p5,y;
- long av,tetpil;
-
- if(lim<=1) lim=0;
- switch(typ(n))
- {
- case 1:return auxdecomp(n,lim);
- case 5:av=avma;n=gred(n);
- case 4:if(typ(n)==4) av=avma;p1=auxdecomp(n[1],lim);
- p2=auxdecomp(n[2],lim);p4=concat(p1[1],p2[1]);
- p5=concat(p1[2],gneg(p2[2]));p3=indexsort(p4);
- tetpil=avma;y=cgetg(3,19);y[1]=(long)extract(p4,p3);
- y[2]=(long)extract(p5,p3);return gerepile(av,tetpil,y);
- default: err(arither1);
- }
- }
-
- GEN divisors(n)
- GEN n;
- {
- long tetpil,av=avma,i,j,l,start;
- GEN p,t=decomp(n),p1=(GEN)t[1],p2=(GEN)t[2],t1,t2,t3,nbdiv=gun;
- l=lg(p1);
- start=1+((l>1)&&(signe(p1[1])<0));
- for(i=start;i<l;i++)nbdiv=mulis(nbdiv,1+itos(p2[i]));
- p=t=cgetg(itos(nbdiv)+1,17);
- *++p=lstoi(1);
- for(i=start;i<l;i++)
- for(t1=t,j=itos(p2[i]);j;j--)
- {
- t2=p;
- for(t3=t1;t3<t2;)
- *++p=lmulii(*++t3,p1[i]);
- t1=t2;
- }
- tetpil=avma;
- return gerepile(av,tetpil,sort(t));
- }
-
- long omega(n)
- GEN n;
-
- {
- byteptr d=diffptr;
- unsigned char c;
- GEN p,f;
- long nb=0,av=avma,av2;
- if (typ(n)!=1) err(arither1);
- if (!signe(n)) err(arither2);
- if ((n[2]==1)&&(lgef(n)==3)) return 0;
- n=absi(n);
- p=cgeti(3);p[1]=0x1000003;p[2]=0;
- av2=avma;
- while (c= *d++)
- {
- p[2]+=c;
- if (!mpdivis(n,p,n)) continue;
- nb++;
- while (mpdivis(n,p,n));
- if ((n[2]==1)&&(lgef(n)==3)) break;
- }
- while ((n[2]!=1) || (lgef(n)!=3))
- {
- f=gcopy(n);
- while (!((cmpii(mulii(p,p),f)>0)||pseudoprime(f))) f=ellfacteur(f);
- nb++;
- while (mpdivis(n,f,n));
- avma=av2;
- }
- avma=av;
- return nb;
- }
-
- long bigomega(n)
- GEN n;
-
- {
- byteptr d=diffptr;
- unsigned char c;
- GEN p,f;
- long nb=0,av=avma,av2;
- if (typ(n)!=1) err(arither1);
- if (!signe(n)) err(arither2);
- if ((n[2]==1)&&(lgef(n)==3)) return 0;
- n=absi(n);
- p=cgeti(3);p[1]=0x1000003;p[2]=0;
- av2=avma;
- while (c= *d++)
- {
- p[2]+=c;
- if (!mpdivis(n,p,n)) continue;
- do nb++;while (mpdivis(n,p,n));
- if ((n[2]==1)&&(lgef(n)==3)) break;
- }
- while ((n[2]!=1) || (lgef(n)!=3))
- {
- f=gcopy(n);
- while (!((cmpii(mulii(p,p),f)>0) || pseudoprime(f))) f = ellfacteur(f);
- while (mpdivis(n,f,n)) nb++;
- avma=av2;
- }
- avma=av;
- return nb;
- }
-
- GEN numbdiv(n)
- GEN n;
-
- {
- byteptr d=diffptr;
- unsigned char c;
- GEN p,f,m,m1;
- long l,av=avma,av2,av3;
- if (typ(n)!=1) err(arither1);
- if (!signe(n)) err(arither2);
- if ((n[2]==1)&&(lgef(n)==3)) return stoi(1);
- n=absi(n);
- p=cgeti(3);p[1]=0x1000003;p[2]=0;
- av2=avma;
- m=stoi(1);
- while (c= *d++)
- {
- p[2]+=c;
- if (!mpdivis(n,p,n)) continue;
- for (l=2;mpdivis(n,p,n);l++);
- av3=avma;
- m1=mulsi(l,m);
- if (lgef (m1) ==lgef(m)) affii(m1,m);
- else m=gerepile(av2,av3,m1);
- if ((n[2]==1)&&(lgef(n)==3)) break;
- }
- while ((n[2]!=1) || (lgef(n)!=3))
- {
- f=gcopy(n);
- while (!((cmpii(mulii(p,p),f)>0) || pseudoprime(f))) f = ellfacteur(f);
- for (l=2;mpdivis(n,f,n);l++);
- av3=avma;
- m=gerepile(av2,av3,mulsi(l,m));
- }
- return gerepile(av,av2,m);
- }
-
- GEN sumdiv(n)
- GEN n;
-
- {
- byteptr d=diffptr;
- unsigned char c;
- GEN p,f,m,m1;
- long av1=avma,av2,av3;
- if (typ(n)!=1) err(arither1);
- if (!signe(n)) err(arither2);
- if ((n[2]==1)&&(lgef(n)==3)) return stoi(1);
- n=absi(n);
- p=cgeti(3);p[1]=0x1000003;p[2]=0;
- av2=avma;
- m=gun;
- while (c= *d++)
- {
- p[2]+=c;
- if (!mpdivis(n,p,n)) continue;
- m1=addsi(1,p);
- while (mpdivis(n,p,n)) m1=addsi(1,mulii(p,m1));
- av3=avma;m=gerepile(av2,av3,mulii(m1,m));
- if ((n[2]==1)&&(lgef(n)==3)) break;
- }
- while ((n[2]!=1)||(lgef(n)!=3))
- {
- f=gcopy(n);
- while (!((cmpii(mulii(p,p),f)>0)||pseudoprime(f))) f=ellfacteur(f);
- m1=gun;
- while (mpdivis(n,f,n)) m1=addsi(1,mulii(f,m1));
- av3=avma;m=gerepile(av2,av3,mulii(m1,m));
- }
- return gerepile(av1,av2,m);
- }
-
- GEN sumdivk(k,n)
- long k;
- GEN n;
-
- {
- byteptr d=diffptr;
- unsigned char c;
- GEN p,p1,f,m,m1,pk;
- long av1=avma,av2,av3,k1;
- if (typ(n)!=1) err(arither1);
- if (!signe(n)) err(arither2);
- if ((n[2]==1)&&(lgef(n)==3)) return stoi(1);
- n=absi(n);k1=k;if(k<0) {k= -k;p1=gpuigs(n,k1);}
- p=cgeti(3);p[1]=0x1000003;p[2]=0;
- av2=avma;
- m=gun;
- while (c= *d++)
- {
- p[2]+=c;
- if (!mpdivis(n,p,n)) continue;
- pk=gpuigs(p,k);
- m1=addsi(1,pk);
- while (mpdivis(n,p,n)) m1=addsi(1,mulii(pk,m1));
- av3=avma;m=gerepile(av2,av3,mulii(m1,m));
- if ((n[2]==1)&&(lgef(n)==3)) break;
- }
- while ((n[2]!=1)||(lgef(n)!=3))
- {
- f=gcopy(n);
- while (!((cmpii(mulii(p,p),f)>0)||pseudoprime(f))) f=ellfacteur(f);
- pk=gpuigs(f,k);
- m1=gun;
- while (mpdivis(n,f,n)) m1=addsi(1,mulii(pk,m1));
- av3=avma;m=gerepile(av2,av3,mulii(m1,m));
- }
- av3=avma;return (k1>=0) ? gerepile(av1,av2,m) : gerepile(av1,av3,gmul(p1,m));
- }
-
- /* decomposition de nombres par la methode des courbes elliptiques.
- La seule fonction exportee est ellfacteur.
- Cette fonction renvoie un facteur non trivial de n.
- On suppose en entree que n n'est pas premier, et n'est divisible par
- aucun petit nombre premier (pas de facteur<65536,en tout cas.) */
-
- static GEN x1,y11,x2,y2,aux,w,n,global;
- static long nombre,taillef;
-
- static GEN cree(nb)
- long nb;
- {
- GEN z=cgetg(nb+1,17);
- long i;
- for(i=1;i<=nb;i++) z[i]=lgeti(taillef);
- return z;
- }
-
- static long pur(x,p)
- long x,*p;
- {
- byteptr d=diffptr;
- long m=0;
- do m+= *d++;while (x % m);
- do x /=m;while (!(x % m));
- *p=m;
- return x==1;
- }
-
- static GEN elladd()
- {
- GEN v1,glob,lambda;
- long i,av=avma;
- for(i=1;i<=nombre;i++)
- {subiiz(x1[i],x2[i],aux[i]); if (signe(aux[i])<0) addiiz(aux[i],n,aux[i]);}
- for(i=1;i<=nombre;i++)
- {modiiz(mulii(aux[i],w[i]),n,w[i+1]);avma=av;}
- if (!inversemodulo(w[nombre+1],n,&glob)) return glob;
- affii(glob,global);
- for(i=nombre;i;i--)
- {
- v1=modii(mulii(global,w[i]),n);
- modiiz(mulii(global,aux[i]),n,global);
- lambda=modii(mulii(subii(y11[i],y2[i]),v1),n);
- modiiz(subii(mulii(lambda,lambda),addii(x2[i],x1[i])),n,x2[i]);
- modiiz(subii(mulii(lambda,subii(x1[i],x2[i])),y11[i]),n,y2[i]);
- avma=av;
- }
- return (GEN)0;
- }
-
- static GEN elldouble()
- {
- GEN v1,v2,glob,lambda;
- long i,av=avma;
- for(i=1;i<=nombre;i++) {modiiz(shifti(y2[i],1),n,aux[i]);avma=av;}
- for(i=1;i<=nombre;i++) {modiiz(mulii(aux[i],w[i]),n,w[i+1]);avma=av;}
- if (!inversemodulo(w[nombre+1],n,&glob)) return glob;
- affii(glob,global);
- for(i=nombre;i;i--)
- {
- v1=modii(mulii(global,w[i]),n);
- modiiz(mulii(global,aux[i]),n,global);
- lambda=modii(mulii(addsi(1,mulsi(3,mulii(x2[i],x2[i]))),v1),n);
- v2=modii(subii(mulii(lambda,lambda),shifti(x2[i],1)),n);
- modiiz(subii(mulii(lambda,subii(x2[i],v2)),y2[i]),n,y2[i]);
- affii(v2,x2[i]);
- avma=av;
- }
- return (GEN)0;
- }
-
- static GEN ellmult(k)
- long k;
- {
- GEN result = (GEN)0;
- if (k>1)
- {
- if (result = ellmult(k/2)) return result;
- if (result = elldouble()) return result;
- if (k&1) result = elladd();
- }
- return result;
- }
-
- GEN ellfacteur(n1)
- GEN n1;
- {
- static long i,k,m,av;
- static GEN glob;
- taillef=lgef(n1);
- nombre=10*lgef(n1);
- global=cgeti(taillef);
- av=avma;
- n=absi(n1);
- x1=cree(nombre);
- x2=cree(nombre);
- y11=cree(nombre);
- y2=cree(nombre);
- aux=cree(nombre);
- w=cree(nombre+1);
- w[1]=un;
- for(i=nombre;i;i--) {affsi(rand(),x2[i]);affsi(rand(),y2[i]);}
- for (m=2;;m++)
- if (pur(m,&k))
- {
- for(i=nombre;i;i--) {affii(x2[i],x1[i]);affii(y2[i],y11[i]);}
- if(glob = ellmult(k))
- {
- if (cmpii(mulii(glob,glob),n)>0) diviiz(n,glob,global);
- else affii(glob,global);
- avma=av;
- return global;
- }
- }
- }
-
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
- /*~ ~*/
- /*~ COMPOSITION DES FORMES QUADRATIQUES ~*/
- /*~ ~*/
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
- GEN qfi(x, y, z)
- GEN x, y, z;
-
- {
- GEN t;
-
- if((typ(x)!=1)||(typ(y)!=1)||(typ(z)!=1)) err(qfer1);
- t=cgetg(4,16);
- t[1] = lcopy(x); t[2] = lcopy(y); t[3] = lcopy(z);
- return t;
- }
-
-
- GEN qfr(x, y, z, d)
- GEN x, y, z, d;
-
- {
- GEN t;
-
- if((typ(x)!=1)||(typ(y)!=1)||(typ(z)!=1)||(typ(d)!=2)) err(qfer1);
- t=cgetg(5,15);
- t[1]=lcopy(x);t[2]=lcopy(y);t[3]=lcopy(z);t[4]=lcopy(d);
- return t;
- }
-
- GEN compose(x,y)
- GEN x,y;
-
- {
- long av,tetpil;
- GEN s,n,d,d1,d2,x1,x2,y1,y2,v1,v2,v3,b3,c3,m,z,p1,r;
-
- if(cmpii(x[1],y[1])>0) {s=x;x=y;y=s;}
- av=avma;s=shifti(addii(x[2],y[2]),-1);n=subii(y[2],s);
- d=bezout(y[1],x[1],&y1,&x1);d1=bezout(s,d,&x2,&y2);
- v1=divii(x[1],d1);v2=divii(y[1],d1);
- d2=(gcmp1(d1))?gun:mppgcd(d1,mppgcd(x[3],mppgcd(y[3],n)));
- v3=mulii(d2,v1);
- m=addii(mulii(mulii(y1,y2),n),mulii(y[3],x2));setsigne(m,-signe(m));
- r=modii(m,v3);b3=shifti((p1=mulii(v2,r)),1);
- c3=addii(mulii(y[3],d1),mulii(r,addii(y[2],p1)));
- z=cgetg(4,16);z[1]=lmulii(v3,v2);z[2]=laddii(y[2],b3);z[3]=ldivii(c3,v3);
- tetpil=avma;return gerepile(av,tetpil,redcomp(z));
- }
-
- GEN compreal(x,y)
- GEN x,y;
-
- {
- long av,tetpil;
- GEN s,n,d,d1,d2,x1,x2,y1,y2,v1,v2,v3,b3,c3,m,z,p1,r;
-
- av=avma;s=shifti(addii(x[2],y[2]),-1);n=subii(y[2],s);
- d=bezout(y[1],x[1],&y1,&x1);d1=bezout(s,d,&x2,&y2);
- v1=divii(x[1],d1);v2=divii(y[1],d1);
- d2=(gcmp1(d1))?gun:mppgcd(d1,mppgcd(x[3],mppgcd(y[3],n)));
- v3=mulii(d2,v1);
- m=addii(mulii(mulii(y1,y2),n),mulii(y[3],x2));setsigne(m,-signe(m));
- r=modii(m,v3);b3=shifti((p1=mulii(v2,r)),1);
- c3=addii(mulii(y[3],d1),mulii(r,addii(y[2],p1)));
- z=cgetg(5,15);z[1]=lmulii(v3,v2);z[2]=laddii(y[2],b3);z[3]=ldivii(c3,v3);
- z[4]=laddrr(x[4],y[4]);tetpil=avma;return gerepile(av,tetpil,redreal(z));
- }
-
- GEN comprealraw(x,y)
- GEN x,y;
-
- {
- long av,tetpil;
- GEN s,n,d,d1,d2,x1,x2,y1,y2,v1,v2,v3,b3,c3,m,z,p1,r;
-
- av=avma;s=shifti(addii(x[2],y[2]),-1);n=subii(y[2],s);
- d=bezout(y[1],x[1],&y1,&x1);d1=bezout(s,d,&x2,&y2);
- v1=divii(x[1],d1);v2=divii(y[1],d1);
- d2=(gcmp1(d1))?gun:mppgcd(d1,mppgcd(x[3],mppgcd(y[3],n)));
- v3=mulii(d2,v1);
- m=addii(mulii(mulii(y1,y2),n),mulii(y[3],x2));setsigne(m,-signe(m));
- r=modii(m,v3);b3=shifti((p1=mulii(v2,r)),1);
- c3=addii(mulii(y[3],d1),mulii(r,addii(y[2],p1)));
- z=cgetg(5,15);z[1]=lmulii(v3,v2);z[2]=laddii(y[2],b3);z[3]=ldivii(c3,v3);
- z[4]=laddrr(x[4],y[4]);tetpil=avma;return gerepile(av,tetpil,gcopy(z));
- }
-
- GEN nucomp(x,y,l)
- GEN x,y,l;
-
- /* l=floor((|d|/4)^(1/4)) */
-
- {
- long av=avma,tetpil,cz;
- GEN s,n,d,d1,v,u1,u,v1,v2,z,p1,p2,p3;
- GEN a,b,e,f,g,a1,a2,a3,b3,v3,q,t2,t3,c3,q1,q2,q3,q4;
-
- if((typ(x)!=16)||(typ(y)!=16)) err(nucomper1);
- if(x==y) return nudupl(x,l);
- if(cmpii(x[1],y[1])<0) {s=x;x=y;y=s;}
- s=shifti(addii(x[2],y[2]),-1);n=subii(y[2],s);
- a1=(GEN)x[1];a2=(GEN)y[1];d=bezout(a2,a1,&u,&v);
- if(gcmp1(d)) {a=negi(gmul(u,n));d1=d;}
- else
- if(divise(s,d))
- {
- a=negi(gmul(u,n));d1=d;a1=divii(a1,d1);a2=divii(a2,d1);s=divii(s,d1);
- }
- else
- {
- d1=bezout(s,d,&u1,&v1);
- if(!gcmp1(d1))
- {
- a1=divii(a1,d1);a2=divii(a2,d1);s=divii(s,d1);d=divii(d,d1);
- }
- p1=resii(x[3],d);p2=resii(y[3],d);
- p3=modii(negi(mulii(u1,addii(mulii(u,p1),mulii(v,p2)))),d);
- a=subii(mulii(p3,divii(a1,d)),mulii(u,divii(n,d)));
- }
- a=modii(a,a1);p1=subii(a1,a);if(cmpii(a,p1)>0) a=negi(p1);
- v=gzero;d=a1;v2=gun;v3=a;cz=0;
- while(cmpii(v3,l)>=0)
- {
- q=dvmdii(d,v3,&t3);t2=subii(v,mulii(q,v2));
- v=v2;d=v3;v2=t2;v3=t3;cz++;
- }
- if(!cz)
- {
- q1=mulii(a2,v3);q2=addii(q1,n);f=divii(q2,d);
- g=divii(addii(mulii(v3,s),y[3]),d);
- a3=mulii(d,a2);c3=addii(mulii(v3,f),mulii(g,d1));
- b3=addii(shifti(q1,1),y[2]);
- }
- else
- {
- if(cz&1) {v3=negi(v3);v2=negi(v2);}
- b=divii(addii(mulii(a2,d),mulii(n,v)),a1);q1=mulii(b,v3);
- q2=addii(q1,n);f=divii(q2,d);
- e=divii(addii(mulii(s,d),mulii(y[3],v)),a1);
- q3=mulii(e,v2);q4=subii(q3,s);g=divii(q4,v);
- if(!gcmp1(d1)) {v2=mulii(d1,v2);v=mulii(d1,v);}
- a3=addii(mulii(d,b),mulii(e,v));c3=addii(mulii(v3,f),mulii(g,v2));
- b3=addii(addii(q1,q2),mulii(d1,addii(q3,q4)));
- }
- z=cgetg(4,16);z[1]=(long)a3;z[2]=(long)b3;z[3]=(long)c3;
- tetpil=avma;return gerepile(av,tetpil,redcomp(z));
- }
-
- GEN nudupl(x,l)
- GEN x,l;
-
- /* l=floor((|d|/4)^(1/4)) */
-
- {
- long av=avma,tetpil,cz;
- GEN u,v,d,d1,p1,a,b,c,b2,z,v2,v3,q,t2,t3,e,g;
-
- d1=bezout(x[2],x[1],&u,&v);a=divii(x[1],d1);b=divii(x[2],d1);
- c=modii(negi(mulii(u,x[3])),a);p1=subii(a,c);if(cmpii(c,p1)>0) c=negi(p1);
- v=gzero;d=a;v2=gun;v3=c;cz=0;
- while(cmpii(v3,l)>=0)
- {
- q=dvmdii(d,v3,&t3);t2=subii(v,mulii(q,v2));
- v=v2;d=v3;v2=t2;v3=t3;cz++;
- }
- if(!cz)
- {
- g=divii(addii(mulii(b,v3),x[3]),d);
- z=cgetg(4,16);z[1]=lmulii(d,d);
- z[2]=laddii(x[2],shifti(mulii(d,v3),1));
- z[3]=laddii(mulii(v3,v3),mulii(g,d1));
- }
- else
- {
- if(cz&1) {v=negi(v);d=negi(d);}
- e=divii(addii(mulii(x[3],v),mulii(b,d)),a);
- g=divii(subii(mulii(e,v2),b),v);b2=addii(mulii(e,v2),mulii(v,g));
- if(!gcmp1(d1)) {b2=mulii(d1,b2);v=mulii(d1,v);v2=mulii(d1,v2);}
- z=cgetg(4,16);z[1]=laddii(mulii(d,d),mulii(e,v));
- z[2]=laddii(b2,shifti(mulii(d,v3),1));
- z[3]=laddii(mulii(v3,v3),mulii(g,v2));
- }
- tetpil=avma;return gerepile(av,tetpil,redcomp(z));
- }
-
- GEN sqcomp(x)
- GEN x;
-
- {
- long av,tetpil;
- GEN d1,d2,x2,y2,v1,v3,b3,c3,m,z,p1,r;
-
- av=avma;
- d1=bezout(x[2],x[1],&x2,&y2);v1=divii(x[1],d1);
- d2=(gcmp1(d1))?gun:mppgcd(d1,x[3]);v3=mulii(d2,v1);
- m=mulii(x[3],x2);setsigne(m,-signe(m));
- r=modii(m,v3);b3=shifti((p1=mulii(v1,r)),1);
- c3=addii(mulii(x[3],d1),mulii(r,addii(x[2],p1)));
- z=cgetg(4,16);z[1]=lmulii(v3,v1);
- z[2]=laddii(x[2],b3);z[3]=ldivii(c3,v3);
- tetpil=avma;return gerepile(av,tetpil,redcomp(z));
- }
-
- GEN sqcompreal(x)
- GEN x;
-
- {
- long av,tetpil;
- GEN d1,d2,x2,y2,v1,v3,b3,c3,m,z,p1,r;
-
- av=avma;
- d1=bezout(x[2],x[1],&x2,&y2);v1=divii(x[1],d1);
- d2=(gcmp1(d1))?gun:mppgcd(d1,x[3]);v3=mulii(d2,v1);
- m=mulii(x[3],x2);setsigne(m,-signe(m));
- r=modii(m,v3);b3=shifti((p1=mulii(v1,r)),1);
- c3=addii(mulii(x[3],d1),mulii(r,addii(x[2],p1)));
- z=cgetg(5,15);z[1]=lmulii(v3,v1);z[2]=laddii(x[2],b3);z[3]=ldivii(c3,v3);
- z[4]=lshiftr(x[4],1);tetpil=avma;return gerepile(av,tetpil,redreal(z));
- }
-
- GEN sqcomprealraw(x)
- GEN x;
-
- {
- long av,tetpil;
- GEN d1,d2,x2,y2,v1,v3,b3,c3,m,z,p1,r;
-
- av=avma;
- d1=bezout(x[2],x[1],&x2,&y2);v1=divii(x[1],d1);
- d2=(gcmp1(d1))?gun:mppgcd(d1,x[3]);v3=mulii(d2,v1);
- m=mulii(x[3],x2);setsigne(m,-signe(m));
- r=modii(m,v3);b3=shifti((p1=mulii(v1,r)),1);
- c3=addii(mulii(x[3],d1),mulii(r,addii(x[2],p1)));
- z=cgetg(5,15);z[1]=lmulii(v3,v1);z[2]=laddii(x[2],b3);z[3]=ldivii(c3,v3);
- z[4]=lshiftr(x[4],1);tetpil=avma;return gerepile(av,tetpil,gcopy(z));
- }
-
- GEN powrealraw(x,n,prec)
- GEN x;
- long n,prec;
- {
- long av,tetpil;
- GEN p1,p2,y,z;
-
- if(n<0) err(impl,"powrealraw for negative exponents");
- if(n==1) return gcopy(x);
- z=x;av=avma;y=cgetg(5,15);y[1]=un;
- p1=subii(mulii(x[2],x[2]),shifti(mulii(x[1],x[3]),2));
- p2=racine(p1);if(mpodd(subii(p2,x[2]))) p2=addsi(-1,p2);
- y[2]=(long)p2;y[3]=lshifti(subii(mulii(p2,p2),p1),-2);
- p1=cgetr(prec);y[4]=(long)p1;p1[1]=0x800000-((prec-2)<<5);
- p1[2]=0;tetpil=avma;y=gerepile(av,tetpil,gcopy(y));
- if(!n) return y;
- else
- {
- for(;n>1;n>>=1)
- {
- if (n&1) y=comprealraw(y,z);
- z=sqcomprealraw(z);
- }
- tetpil=avma;return gerepile(av,tetpil,comprealraw(y,z));
- }
- }
-
- GEN nupow(x,n)
- GEN x,n;
- {
- long av,tetpil,i,j;
- unsigned long m;
- GEN p1,p2,y,z,l;
-
- if(typ(n)!=1) err(nupower1);
- if(gcmp1(n)) return gcopy(x);
- z=x;av=avma;y=cgetg(4,16);y[1]=un;y[2]=mpodd(x[2]) ? un : zero;
- p1=mulii(x[1],x[3]);p2=shifti(mulii(x[2],x[2]),-2);y[3]=lsubii(p1,p2);
- if(!signe(n)) {tetpil=avma;return gerepile(av,tetpil,gcopy(y));}
- else
- {
- l=racine(shifti(racine(y[3]),1));
- for (i=lgef(n)-1;i>2;i--)
- {
- for (m=n[i],j=0;j<32;j++,m>>=1)
- {
- if (m&1) y=nucomp(y,z,l);
- z=nudupl(z,l);
- }
- }
- for (m=n[2];m>1;m>>=1)
- {
- if (m&1) y=nucomp(y,z,l);
- z=nudupl(z,l);
- }
- tetpil=avma;y=nucomp(y,z,l);
- if ((signe(n)<0)&&cmpii(y[1],y[2])&&cmpii(y[1],y[3]))
- setsigne(y[2],-signe(y[2]));
- y=gerepile(av,tetpil,y);
- }
- }
-
- GEN redcomp(x)
- GEN x;
-
- {
- long av,tetpil,s,fl,fg;
- GEN b1,c1,p1,a,b,c,d,z;
-
- av=avma;a=(GEN)x[1];b=(GEN)x[2];c=(GEN)x[3];
- fl=cmpii(a,c);s=signe(b);setsigne(b,abs(s));fg=cmpii(a,b);
- while((fl>0)||(fg<0))
- {
- p1=shifti(c,1);d=dvmdii(b,p1,&b1);
- setsigne(b,s);
- if(s>=0)
- {
- if(cmpii(b1,c)<=0) {setsigne(d,-signe(d));setsigne(b1,-signe(b1));}
- else {d=subsi(-1,d);b1=subii(p1,b1);}
- }
- else
- {
- if(cmpii(b1,c)>=0) {d=addsi(1,d);b1=subii(b1,p1);}
- }
- c1=addii(a,mulii(d,shifti(subii(b,b1),-1)));a=c;
- b=b1;c=c1;
- fl=cmpii(a,c);s=signe(b);setsigne(b,abs(s));fg=cmpii(a,b);
- }
- if(fl&&fg&&(s<0)) setsigne(b,s);tetpil=avma;
- z=cgetg(4,16);z[1]=lcopy(a);z[2]=lcopy(b);z[3]=lcopy(c);
- return gerepile(av,tetpil,z);
- }
-
- GEN rhoreal(x)
- GEN x;
- {
- long av,tetpil,s,l;
- GEN y,p1,nn,sqrtD,isqrtD,D;
-
- if(typ(x)!=15) err(rhoer1);
- av=avma;y=cgetg(5,15);
- l=max(lg(x[4]),((-expo(x[4]))>>5)+2);if(l<=2) l=3;
- y[1]=lcopy(x[3]);sqrtD=gsqrt(D=subii(mulii(x[2],x[2]),shifti(mulii(x[1],x[3]),2)),l);
- isqrtD=mptrunc(sqrtD);
- s=signe(y[1]);setsigne(y[1],1);
- if(cmpii(isqrtD,y[1])>=0) nn=divii(addii(isqrtD,x[2]),p1=shifti(y[1],1));
- else nn=divii(addii(y[1],x[2]),p1=shifti(y[1],1));
- p1=mulii(nn,p1);y[2]=lsubii(p1,x[2]);
- setsigne(y[1],s);p1=shifti(subii(mulii(y[2],y[2]),D),-2);y[3]=ldivii(p1,y[1]);
- y[4]=laddrr(shiftr(mplog(absr(divrr(addir(x[2],sqrtD),subir(x[2],sqrtD)))),-1),x[4]);
- tetpil=avma;return gerepile(av,tetpil,gcopy(y));
- }
-
- GEN redreal(x)
- GEN x;
- {
- long fl,av=avma,tetpil,l,s;
- GEN y,p1,sqrtD,isqrtD,D,z,nn;
-
- if(typ(x)!=15) err(rhoer1);
- if(signe(x[4])) l=lg(x[4]);
- else {l=((-expo(x[4]))>>5)+2;if(l<=2) l=3;}
- sqrtD=gsqrt(D=subii(mulii(x[2],x[2]),shifti(mulii(x[1],x[3]),2)),l);
- isqrtD=mptrunc(sqrtD);
- y=cgetg(5,15);y[1]=x[1];y[2]=x[2];y[3]=x[3];y[4]=x[4];
- if((signe(x[2])<=0)||(cmpii(x[2],isqrtD)>0)) fl=1;
- else
- {
- p1=subii(isqrtD,shifti(absi(x[1]),1));
- if(signe(p1)<0) fl=(cmpii(x[2],absi(p1))<0);else fl=(cmpii(x[2],p1)<=0);
- }
- while(fl)
- {
- z=cgetg(5,15);
- z[1]=y[3];s=signe(z[1]);setsigne(z[1],1);
- if(cmpii(isqrtD,z[1])>=0) nn=divii(addii(isqrtD,y[2]),p1=shifti(z[1],1));
- else nn=divii(addii(z[1],y[2]),p1=shifti(z[1],1));
- p1=mulii(nn,p1);z[2]=lsubii(p1,y[2]);
- setsigne(z[1],s);p1=shifti(subii(mulii(z[2],z[2]),D),-2);z[3]=ldivii(p1,z[1]);
- z[4]=laddrr(shiftr(mplog(absr(divrr(addir(y[2],sqrtD),subir(y[2],sqrtD)))),-1),y[4]);
- y=z;
- if((signe(y[2])<=0)||(cmpii(y[2],isqrtD)>0)) fl=1;
- else
- {
- p1=subii(isqrtD,shifti(absi(y[1]),1));
- if(signe(p1)<0) fl=(cmpii(y[2],absi(p1))<0);else fl=(cmpii(y[2],p1)<=0);
- }
- }
- tetpil=avma;return gerepile(av,tetpil,gcopy(y));
- }
-
- GEN rhorealnod(x,isqrtD)
- GEN x,isqrtD;
- {
- long av,tetpil,s;
- GEN y,p1,nn,D;
-
- if(typ(x)!=15) err(rhoer1);
- if(typ(isqrtD)!=1) err(arither1);
- av=avma;y=cgetg(5,15);
- y[1]=lcopy(x[3]);D=subii(mulii(x[2],x[2]),shifti(mulii(x[1],x[3]),2));
- s=signe(y[1]);setsigne(y[1],1);
- if(cmpii(isqrtD,y[1])>=0) nn=divii(addii(isqrtD,x[2]),p1=shifti(y[1],1));
- else nn=divii(addii(y[1],x[2]),p1=shifti(y[1],1));
- p1=mulii(nn,p1);y[2]=lsubii(p1,x[2]);
- setsigne(y[1],s);p1=shifti(subii(mulii(y[2],y[2]),D),-2);y[3]=ldivii(p1,y[1]);
- affsr(0,y[4]=lgetr(3));
- tetpil=avma;return gerepile(av,tetpil,gcopy(y));
- }
-
- GEN redrealnod(x,isqrtD)
- GEN x,isqrtD;
- {
- long fl,av=avma,tetpil,s;
- GEN y,p1,D,z,nn;
-
- if(typ(x)!=15) err(rhoer1);
- if(typ(isqrtD)!=1) err(arither1);
- D=subii(mulii(x[2],x[2]),shifti(mulii(x[1],x[3]),2));
- y=cgetg(5,15);y[1]=x[1];y[2]=x[2];y[3]=x[3];
- if((signe(x[2])<=0)||(cmpii(x[2],isqrtD)>0)) fl=1;
- else
- {
- p1=subii(isqrtD,shifti(absi(x[1]),1));
- if(signe(p1)<0) fl=(cmpii(x[2],absi(p1))<0);else fl=(cmpii(x[2],p1)<=0);
- }
- while(fl)
- {
- z=cgetg(5,15);
- z[1]=y[3];s=signe(z[1]);setsigne(z[1],1);
- if(cmpii(isqrtD,z[1])>=0) nn=divii(addii(isqrtD,y[2]),p1=shifti(z[1],1));
- else nn=divii(addii(z[1],y[2]),p1=shifti(z[1],1));
- p1=mulii(nn,p1);z[2]=lsubii(p1,y[2]);
- setsigne(z[1],s);p1=shifti(subii(mulii(z[2],z[2]),D),-2);z[3]=ldivii(p1,z[1]);
- y=z;
- if((signe(y[2])<=0)||(cmpii(y[2],isqrtD)>0)) fl=1;
- else
- {
- p1=subii(isqrtD,shifti(absi(y[1]),1));
- if(signe(p1)<0) fl=(cmpii(y[2],absi(p1))<0);else fl=(cmpii(y[2],p1)<=0);
- }
- }
- affsr(0,y[4]=lgetr(3));
- tetpil=avma;return gerepile(av,tetpil,gcopy(y));
- }
-
- GEN primeform(x,p,prec)
- GEN x,p;
- long prec;
- {
- long av,tetpil,s,t,sb,sx=signe(x);
- GEN y,b,c;
-
- if((typ(x)!=1)||(!sx)) err(arither1);
- if(gcmpgs(p,2))
- {
- y=(sx<0) ? cgetg(4,16) : cgetg(5,15);y[1]=lcopy(p);y[2]=lgeti(lgef(p));
- av=avma;
- if(!mpsqrtmod(x,p,&b)) err(sqrter5);
- s=b[lgef(b)-1]&1;t=x[lgef(x)-1]&1;
- if(odd(s+t)) subiiz(p,b,y[2]);else affii(b,y[2]);
- c=shifti(subii(mulii(y[2],y[2]),x),-2);tetpil=avma;
- y[3]=lpile(av,tetpil,divii(c,p));
- }
- else
- {
- s=x[lgef(x)-1]&7;if(signe(x)<0) s=8-s;
- switch(s)
- {
- case 0:
- case 8: sb=0;break;
- case 1: sb=1;break;
- case 4: sb=2;break;
- default: err(sqrter5);
- }
- y=(sx<0) ? cgetg(4,16) : cgetg(5,15);y[1]=lcopy(deux);y[2]=lstoi(sb);
- av=avma;c=gsubsg(sb*sb,x);tetpil=avma;
- y[3]=lpile(av,tetpil,shifti(c,-3));
- }
- if(sx>0) affsr(0,y[4]=lgetr(prec));
- return y;
- }
-
- GEN classno(x)
- GEN x;
-
- /* calcul de h(x) pour x<0 par la methode de Shanks */
-
- {
- static long prem,ptforme;
- long av,av1,av2,av3,tetpil,k,k2,i,j,j1,lim,limite,succes,com,j2,s;
- GEN tabla, tablb, count, index, hash;
- static long court[3]={0x1000003,0x1010003,0};
- GEN p1,p2,p3,hin,q,formes[100],l,h,hp,f,fh,fg,ftest,pm2;
- static byteptr p;
-
- if (typ(x)!=1) err(arither1);
- if (!(s=signe(x))) err(arither2);
- if(s>0) return classno2(x);
- k=x[lgef(x)-1]&3;
- if((k==1)||(k==2)) err(classer2);
- if(gcmpgs(x,-12)>=0) return gun;
- tabla = newbloc(10000);
- tablb = newbloc(10000);
- count = newbloc(256);
- index = newbloc(257);
- hash = newbloc(10000);
- prem=ptforme=0;p=diffptr;av=avma;limite=(av+bot)>>1;
- p1=divrr(gsqrt(absi(x),4),mppi(4));
- l=gtrunc(shiftr(gsqrt(gsqrt(absi(x),4),4),1));
- if(gcmpgs(l,1000)<0) affsi(1000,l);
- while((gcmpgs(l,prem)>=0)&&(*p))
- {
- prem+= *p++;
- k=krogs(x,prem);
- if(k)
- {
- av2=avma;
- if(k>0)
- {
- divrsz(mulsr(prem,p1),prem-1,p1);avma=av2;
- if((ptforme<100)&&(prem>2))
- {
- court[2]=prem;
- formes[ptforme++]=redcomp(primeform(x,court,3));
- }
- }
- else {divrsz(mulsr(prem,p1),prem+1,p1);avma=av2;}
- }
- }
- hin=ground(p1);h=gcopy(hin);f=formes[0];fh=gpui(f,h);
- s=2*itos(gceil(gpui(p1,gdivgs(gun,4),4)));
- if(s>=10000) s=10000;
- p1=fh;av2=avma;
- for(i=0;i<=255;i++) count[i]=0;
- for(i=0;i<=s-1;i++)
- {
- p2=(GEN)p1[1];tabla[i]=p2[lgef(p2)-1];j=tabla[i]&255;count[j]++;
- p2=(GEN)p1[2];tablb[i]=p2[lgef(p2)-1];
- p1=compose(p1,f);
- }
- fg=gpuigs(f,s);ftest=gpuigs(p1,0);
- index[0]=0;for(i=0;i<=254;i++) index[i+1]=index[i]+count[i];
- for(i=0;i<=s-1;i++) hash[index[tabla[i]&255]++]=i;
- index[0]=0;for(i=0;i<=255;i++) index[i+1]=index[i]+count[i];
- succes=0;com=0;av3=avma;
- while(!succes)
- {
- p1=(GEN)ftest[1];k=p1[lgef(p1)-1];j=k&255;
- pm2=negi(ftest[2]);
- for(j1=index[j];(j1<index[j+1])&&(!succes);j1++)
- {
- j2=hash[j1];
- if(tabla[j2]==k)
- {
- p2=(GEN)ftest[2];k2=p2[lgef(p2)-1];
- if((tablb[j2]==k2)||(tablb[j2]== -k2))
- {
- p1=gmul(gpuigs(f,j2),fh);
- succes=(!cmpii(p1[1],ftest[1]))&&((!cmpii(p1[2],ftest[2]))||(!cmpii(p1[2],pm2)));
- }
- }
- }
- if(!succes)
- {
- com++;
- if(avma>=limite) ftest=gmul(ftest,fg);
- else {tetpil=avma;ftest=gerepile(av3,tetpil,gmul(ftest,fg));}
- if (gcmp1(ftest[1]))
- {
- err(impl, "classno with too small order");
- }
- }
- }
- h=addis(h,j2);p2=mulsi(s,stoi(com));tetpil=avma;
- h=(!cmpii(p1[2],ftest[2]))?subii(h,p2):addii(h,p2);
- p2=factor(h);
- p1=(GEN)p2[1];
- p2=(GEN)p2[2];
- for(i=1;i<lg(p1);i++)
- {
- p3=divii(h,p1[i]);fh=gpui(f,p3);lim=itos(p2[i]);
- for(j=1;(j<=lim)&&(!cmpii(fh[1],un));j++)
- {
- h=p3;
- if(j<lim) {p3=divii(h,p1[i]);fh=gpui(f,p3);}
- }
- }
- q=ground(gdiv(hin,h));tetpil=avma;
- hp=mulii(q,h);av1=avma;
- for(i=1;(i<=10)&&(i<ptforme);i++)
- {
- f=formes[i];com=0;
- fg=gpui(f,h);
- fh=gpui(fg,q);
- ftest=fg;
- if(cmpis(fh[1],1))
- {
- for(;;)
- {
- com++;
- if ((!cmpii(fh[1],ftest[1]))&&((!cmpii(fh[2],ftest[2]))||(!cmpii(fh[2],negi(ftest[2]))))) break;
- ftest=gmul(ftest,fg);
- }
- if(!cmpii(fh[2],ftest[2])) com= -com;
- p2=mulsi(com,h);q=addsi(com,q);tetpil=avma;
- hp=addii(hp,p2);av1=avma;
- }
- }
- avma=av1;
- killbloc(tabla); killbloc(tablb); killbloc(count);
- killbloc(index); killbloc(hash);
- return gerepile(av,tetpil,hp);
- }
-