void NR::mpdiv(Vec_O_UCHR &q, Vec_O_UCHR &r, Vec_I_UCHR &u, Vec_I_UCHR &v) { const int MACC=1; int i,is,mm; int n=u.size(); int m=v.size(); int p=r.size(); int n_min=MIN(m,p); if (m > n) nrerror("Divisor longer than dividend in mpdiv"); mm=m+MACC; Vec_UCHR s(mm),rr(mm),ss(mm+1),qq(n-m+1),t(n); mpinv(s,v); mpmul(rr,s,u); mpsad(ss,rr,1); mplsh(ss); mplsh(ss); mpmov(qq,ss); mpmov(q,qq); mpmul(t,qq,v); mplsh(t); mpsub(is,t,u,t); if (is != 0) nrerror("MACC too small in mpdiv"); for (i=0;i<n_min;i++) r[i]=t[i+n-m]; if (p>m) for (i=m;i<p;i++) r[i]=0; }
void mpsqrt(unsigned char w[], unsigned char u[], unsigned char v[], int n, int m) { void mplsh(unsigned char u[], int n); void mpmov(unsigned char u[], unsigned char v[], int n); void mpmul(unsigned char w[], unsigned char u[], unsigned char v[], int n, int m); void mpneg(unsigned char u[], int n); void mpsdv(unsigned char w[], unsigned char u[], int n, int iv, int *ir); int i,ir,j,mm; float fu,fv; unsigned char *r,*s; r=cvector(1,n<<1); s=cvector(1,n<<1); mm=IMIN(m,MF); fv=(float) v[mm]; for (j=mm-1;j>=1;j--) { fv *= BI; fv += v[j]; } fu=1.0/sqrt(fv); for (j=1;j<=n;j++) { i=(int) fu; u[j]=(unsigned char) i; fu=256.0*(fu-i); } for (;;) { mpmul(r,u,u,n,n); mplsh(r,n); mpmul(s,r,v,n,IMIN(m,n)); mplsh(s,n); mpneg(s,n); s[1] -= 253; mpsdv(s,s,n,2,&ir); for (j=2;j<n;j++) { if (s[j]) { mpmul(r,s,u,n,n); mpmov(u,&r[1],n); break; } } if (j<n) continue; mpmul(r,u,v,n,IMIN(m,n)); mpmov(w,&r[1],n); free_cvector(s,1,n<<1); free_cvector(r,1,n<<1); return; } }
void mpinv(unsigned char u[], unsigned char v[], int n, int m) { void mpmov(unsigned char u[], unsigned char v[], int n); void mpmul(unsigned char w[], unsigned char u[], unsigned char v[], int n, int m); void mpneg(unsigned char u[], int n); unsigned char *rr,*s; int i,j,maxmn,mm; float fu,fv; maxmn=IMAX(n,m); rr=cvector(1,1+(maxmn<<1)); s=cvector(1,maxmn); mm=IMIN(MF,m); fv=(float) v[mm]; for (j=mm-1;j>=1;j--) { fv *= BI; fv += v[j]; } fu=1.0/fv; for (j=1;j<=n;j++) { i=(int) fu; u[j]=(unsigned char) i; fu=256.0*(fu-i); } for (;;) { mpmul(rr,u,v,n,m); mpmov(s,&rr[1],n); mpneg(s,n); s[1] -= 254; mpmul(rr,s,u,n,n); mpmov(u,&rr[1],n); for (j=2;j<n;j++) if (s[j]) break; if (j==n) { free_cvector(s,1,maxmn); free_cvector(rr,1,1+(maxmn<<1)); return; } } }