/* bc program padic */ * mult(a[],b[],m,n,p) forms the product of a=a[0]+a[1]p+...+a[m]p^m * and b=b[0]+b[1]p+...+b[n]p^n * where a[m] and b[n] are nonzero. * The product is given by the global variable prod[] * prod[0]+prod[1]p+...+prod[l]p^l, where prod[l] is nonzero. * If a or b is zero, we return 0 at the start, otherwise return l.. * The program is an adaption of one in i1.c * from http://www.numbertheory.org/calc/ */ define mult(a[],b[],m,n,p){ auto c,i,t,j,bk,k,l if((m==0 && a[0]==0) || (n==0 && b[0]==0)){ prod[0]=0 print prod[0] l=0 print "\n" return(l) } c=0 l=m+n+1 for(k=0;k<=m;k++){ prod[k]=0 } for(k=0;k<=n;k++){ bk=b[k] if(bk){ c=0 for(j=0;j<=m;j++){ t=a[j]*bk+prod[j+k]+c prod[j+k]=t%p c=t/p } prod[m+k+1]=c }else{ prod[m+k+1]=0 } } if(c==0){ l=m+n } return(l) } /* * rsv(a[],b[],m,n) is an adaption of one in i1.c * from http://www.numbertheory.org/calc/ * it returns 1,0,-1 according as a[] >,=,< b[]. */ define rsv(a[],b[],m,n){ auto j if(m>n){ return(1) } if(m0){ j=j-1 } if(a[j]>b[j]){ return(1) } if(a[j]= b[] and returns the l and the global array * diff[]=a[]-b[]=diff[0]+diff[1]*p+...+diff[l]*p^l. */ define sub(a[],b[],m,n,p){ auto c,d,f,k,j,l,t if(n==0 && b[0]==0){ for(j=0;j<=m;j++){ diff[j]=a[j] } l=m return(l) } c=1 l=m for(j=0;j<=n;j++){ t=a[j]-b[j]+p+c-1 diff[j]=t%p c=t/p } if(m>n){ for(j=n+1;j<=m;j++){ t=a[j]+p+c-1 diff[j]=t%p c=t/p } } d=0 k=m while (k >= 0) { if (diff[k] != 0) { d = k k = -1 }else{ k=k-1 } } f = m - d; if(f){ l=d } return(l) } /* base(b,n) gives the base b expansion of n: * base[]=baseb[0]+baseb[1]*b+ ...+baseb[i]*b^i. * The integer i is returned, along with the global * variable baseb[]. */ define base(b,n){ auto i,q,t,x i=0 if(n<0){"Try again, n<";return(0)} if(b<=1){"Try again, b<=";return(1)} x=n while(n>=b){ q=n/b t=n-q*b baseb[i]=t n=q i=i+1 } baseb[i]=n return(i) } /* * twoadicsqrt(a,n) n>=3, returns the first n binary digits of a * 2adic sqroot x of a positive integer a=8k+1. Here x=1 or 5 (mod 8). * See http://www.numbertheory.org/courses/MP313/lectures/lecture23/page3.html * and http://www.numbertheory.org/courses/MP313/solns/soln3/page1.html. */ define twoadicsqrt(a,n){ auto i,j,k,l,x,y,z,b[] if(n<1){ print "n<1\n" return } if(a%8!=1){ print "a is not of the form 8k+1\n" return } if(a<1){ print "a<1\n" return } b[0]=1; if(n==1){ print "1 is the first digit of the 2adic square root of " return(a) } b[1]=0; if(n==2){ print "10 are the first digits of the 2adic square root of " return(a) } x=base(2,a) l=0 for(k=3;k<=n;k++){ y=mult(b[],b[],l,l,2) z=rsv(prod[],baseb[],y,x) if(z<0){ j=sub(baseb[],prod[],x,y,2) }else{ j=sub(prod[],baseb[],y,x,2) } if(diff[k]){ b[k-1]=1 if(k==3){ l=2 }else{ l=k-1 } } } for(i=0;i= 1; k--){ ratiop[k]=t/b t = ratiop[k-1] + ((t%b)*p) } if (ratiop[n]==0){ l=n-1 } } ratiop[0] = t / b return(l) } define parity(a[],n,p){ auto i,s if(p==2){ t=a[0]%2 return(t) } s=0 for(i=0;i<=n;i++){ t=a[i]%2 s=s+t } return(s%2) } /* a[]~a[0]+a[1]p+...+a[k-1]p^(k-1) (mod p^k), 0<=a[i]0 || (m=0 && y[0]>0)){ t=parity(y[],m,p) while(t==0){ m=divp(y[],m,2,p) for(i=0;i<=m;i++){ y[i]=ratiop[i] } t=parity(y[],m,p) u=multp(x[],x[],k,p) for(i=0;i