home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: Science
/
Science.zip
/
picalcu.zip
/
ESCOTT.C
next >
Wrap
Text File
|
2002-09-20
|
7KB
|
330 lines
/* 16 bit version of the Escott algorithm for Pi */
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <ctype.h>
#define DECMAX 94835L
typedef struct
{ unsigned int *fraction;
unsigned int valid;
} LONGFRACT;
LONGFRACT pi;
unsigned int digits;
void divlongf (LONGFRACT *dividend, unsigned int divisor, unsigned int rest)
{
_asm
{
les bx,dividend
mov si,es:[bx].valid
les bx,es:[bx].fraction
mov cx,divisor
mov dx,rest
dec si
shl si,1
mov ax,es:[bx+si]
div cx
and ax,ax
jnz div_2
les bx,dividend
dec word ptr es:[bx].valid
les bx,es:[bx].fraction
jmp div_2
div_1:
mov ax,es:[bx+si]
div cx
div_2:
mov es:[bx+si],ax
sub si,2
jnc div_1
}
}
void addlongf (LONGFRACT *bezug, LONGFRACT *zahl)
{
_asm
{
push ds
push bp
les bx,zahl
mov cx,es:[bx].valid
les bx,es:[bx].fraction
lds bp,bezug
mov di,ds:[bp].valid
lds bp,ds:[bp].fraction
xor si,si
shl di,1
clc
add_1:
mov ax,es:[bx+si]
adc ds:[bp+si],ax
inc si
inc si
dec cx
jnz add_1
jnc add_4
add_2:
cmp si,di
jc add_3
lds bp,bezug
inc word ptr ds:[bp].valid
lds bp,ds:[bp].fraction
inc di
inc di
add_3:
inc word ptr ds:[bp+si]
jnz add_4
inc si
inc si
jmp add_2
add_4:
pop bp
pop ds
}
}
void sublongf (LONGFRACT *bezug, LONGFRACT *zahl)
{
_asm
{
push ds
push bp
les bx,zahl
mov cx,es:[bx].valid
les bx,es:[bx].fraction
lds bp,bezug
lds bp,ds:[bp].fraction
xor si,si
clc
sub_1:
mov ax,es:[bx+si]
sbb ds:[bp+si],ax
inc si
inc si
dec cx
jnz sub_1
jnc sub_3
sub_2:
sub word ptr ds:[bp+si],1
jnc sub_3
inc si
inc si
jmp sub_2
sub_3:
pop bp
pop ds
}
}
unsigned int pimalzt (void)
{
_asm
{
mov ax,SEG digits
mov es,ax
mov di,es:[digits]
mov bx,SEG pi
mov es,bx
mov bx,OFFSET pi
mov si,es:[bx].valid
les bx,es:[bx].fraction
shl si,1
shl di,1
mov ax,10000
mul word ptr es:[bx+si]
and ax,ax
jnz mul_2
mov bx,SEG pi
mov es,bx
mov bx,OFFSET pi
inc word ptr es:[bx].valid
les bx,es:[bx].fraction
jmp mul_2
mul_1:
mov ax,10000
mul word ptr es:[bx+si]
add ax,cx
jnc mul_2
inc dx
mul_2:
mov cx,dx
mov es:[bx+si],ax
inc si
inc si
cmp si,di
jc mul_1
mov ax,cx
}
}
void cpylongf (LONGFRACT *ziel, LONGFRACT *quelle)
{
register unsigned int *z, *q, i;
ziel->valid = i = quelle->valid;
z = ziel->fraction;
q = quelle->fraction;
while (i--) *z++ = *q++;
}
int main (int argc, char *argv[])
{
LONGFRACT a,b,c,d,s;
int minus = 0;
unsigned int denomin = 1, a_high;
long decimals = 0;
char ch, last[5], *next = last;
if (argc > 2)
{
fprintf (stderr, "too many arguments (only one number allowed)!\n");
exit (1);
}
if (argc == 2)
{
while (ch = *argv[1]++)
{
if (isdigit (ch))
{
ch -= '0';
decimals = decimals * 10 + ch;
if (decimals > DECMAX)
{
fprintf (stderr, "number of decimals may not exceed %ld!\n",
DECMAX);
exit (2);
}
}
else
{
fprintf (stderr, "parameter must be the number of decimals!\n");
exit (3);
}
}
}
else decimals = DECMAX;
digits = (decimals * 49 + 354) / 236;
if (a.fraction = calloc (digits, sizeof (unsigned int)))
{
if (b.fraction = calloc (digits, sizeof (unsigned int)))
{
if (c.fraction = calloc (digits, sizeof (unsigned int)))
{
if (d.fraction = calloc (digits, sizeof (unsigned int)))
{
if (s.fraction = calloc (digits, sizeof (unsigned int)))
{
if (pi.fraction = calloc (digits, sizeof (unsigned int)))
{
a.valid = b.valid = c.valid = d.valid = digits;
a_high = 3;
divlongf (&a, 28, 4);
divlongf (&b, 443, 8);
divlongf (&c, 1393, 20);
divlongf (&d, 11018, 40);
cpylongf (&pi, &a);
addlongf (&pi, &b);
sublongf (&pi, &c);
sublongf (&pi, &d);
while (a.valid)
{
divlongf (&a, 784, a_high);
a_high = 0;
fprintf (stderr, " 1: %5d", a.valid);
if (a.valid)
{
cpylongf (&s, &a);
if (b.valid)
{
divlongf (&b, 443, 0);
if (b.valid)
divlongf (&b, 443, 0);
fprintf (stderr, " 2: %5d", b.valid);
if (b.valid)
{
addlongf (&s, &b);
if (c.valid)
{
divlongf (&c, 1393, 0);
if (c.valid)
divlongf (&c, 1393, 0);
fprintf (stderr, " 3: %5d", c.valid);
if (c.valid)
{
sublongf (&s, &c);
if (d.valid)
{
divlongf (&d, 11018, 0);
if (d.valid)
divlongf (&d, 11018, 0);
fprintf (stderr, " 4: %5d", d.valid);
if (d.valid)
sublongf (&s, &d);
} /* d.valid */
} /* c.valid 2 */
} /* c.valid 1 */
} /* b.valid 2 */
} /* b.valid 1 */
divlongf (&s, denomin += 2, 0);
if (s.valid)
{ if (minus = ! minus)
sublongf (&pi, &s);
else
addlongf (&pi, &s);
}
else a.valid = 0;
} /* a.valid 2 */
fprintf (stderr, "\r");
} /* a.valid 1 */
printf ("3.");
pi.valid = 0;
while (decimals > 4)
{
printf ("%04d", pimalzt ());
decimals -= 4;
}
sprintf (last, "%04d", pimalzt ());
while (decimals--)
fputchar (*next++);
free (pi.fraction);
}
free (s.fraction);
}
free (d.fraction);
}
free (c.fraction);
}
free (b.fraction);
}
free (a.fraction);
}
exit (0);
}