home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The C Users' Group Library 1994 August
/
wc-cdrom-cusersgrouplibrary-1994-08.iso
/
vol_200
/
247_01
/
bnbuild.c
< prev
next >
Wrap
Text File
|
1989-04-19
|
3KB
|
130 lines
/*
* MIRACL flash number builder: uses generator of
* regular continued fraction expansion to create
* a flash number, rounded if necessary.
* bnbuild.c
*/
#include <stdio.h>
#include "miracl.h"
#define abs(x) ((x)<0? (-(x)) : (x))
/* Access global variables */
extern int depth; /* error tracing .. */
extern int trace[]; /* .. mechanism */
extern int check; /* error checking */
extern small base; /* number base */
extern int nib; /* no. ints in big */
extern int workprec;
extern big w0;
extern big w1; /* workspace variables */
extern big w2;
extern big w3;
extern big w4;
extern big w7;
void build(x,gen)
flash x;
int (*gen)();
{ /* Build x from its regular c.f. *
* generated by gen() */
small a,b,c,d,rm,ex1,ex2,ex;
int q,n,prc,lw2,lw4,lz;
bool finoff,last;
big t;
if (ERNUM) return;
depth++;
trace[depth]=48;
if (TRACER) track();
zero(w1);
convert((small)1,w2);
convert((small)1,w3);
zero(w4);
finoff=FALSE;
last=FALSE;
n=0;
q=(*gen)(x,n); /* Note - first quotient may be zero */
ex=base;
if (nib==workprec) prc=nib;
else prc=workprec+1;
while (!ERNUM && q>=0)
{
if (q==TOOBIG || n==0 || finoff)
{
if (q!=TOOBIG) convert((small)q,x);
else last=FALSE;
check=OFF;
multiply(w2,x,w0);
subtract(w1,w0,w7);
check=ON;
if (abs(w7[0])>nib) break;
copy(w7,w1);
t=w1,w1=w2,w2=t; /* swap(w1,w2) */
check=OFF;
multiply(w4,x,w0);
subtract(w3,w0,w7);
check=ON;
if (abs(w7[0])>nib) break;
copy(w7,w3);
t=w3,w3=w4,w4=t; /* swap(w3,w4) */
n++;
}
lw2=abs(w2[0]);
lw4=abs(w4[0]);
lz=lw2+lw4;
if (lz > prc) break; /* too big - exit */
if (last)
{
if (finoff) break;
finoff=TRUE;
q=(*gen)(x,n);
continue;
}
if (lz>=prc-1)
{ /* nearly finished - so be careful not to overshoot */
ex1=base/(w2[lw2]+1);
ex2=base/(w4[lw4]+1);
if (ex2>ex1) ex=ex1,ex1=ex2,ex2=ex;
if (lz==prc) ex=ex2;
else ex=ex1;
last=TRUE;
}
a=1;
b=0;
c=0;
d=1;
forever
{
q=(*gen)(x,n);
if (q<0 || q==TOOBIG || q>=MAXBASE/abs(d)) break;
rm=b-q*d;
b=d;
d=rm;
rm=a-q*c;
a=c;
c=rm;
n++;
if (abs(c-d)>ex) break;
}
premult(w1,c,w7);
premult(w1,a,w1);
premult(w2,b,w0);
premult(w2,d,w2);
add(w1,w0,w1);
add(w2,w7,w2);
premult(w3,c,w7);
premult(w3,a,w3);
premult(w4,b,w0);
premult(w4,d,w4);
add(w3,w0,w3);
add(w4,w7,w4);
}
if (abs(w2[0]-w4[0]) <= nib) fpack(w2,w4,x);
else fpack(w1,w3,x);
negate (x,x);
if (q!=(-1)) EXACT=FALSE;
depth--;
}