code:
Can't Copy and Paste this?
Click here for a copy-and-paste friendly version of this code!
Terms of Agreement:
By using this code, you agree to the following terms...
1) You may use this code in your own programs (and may compile it into a program and distribute it in compiled format for langauges that allow it) freely and with no charge.
2) You MAY NOT redistribute this code (for example to a web site) without written permission from the original author. Failure to do so is a violation of copyright laws.
3) You may link to this code from another website, but ONLY if it is not wrapped in a frame.
4) You will abide by any additional copyright restrictions which the author may have placed in the code or code's description.
/* +++Date last modified: 05-Jul-1997 */
/*
pi8.c Sept 9, 1996.
*/
#include
#include
#include
#define SHOWTIME
#define USEFPU
#if defined USEFPU
#define BASE1000000000L
#define BASEDIGITS 9
typedef long int SHORT;
typedef doubleLONG;
#else
#define BASE100
#define BASEDIGITS 2
typedef unsigned char SHORT;
typedef long int LONG;
#endif
typedef long int INDEXER;
short *pi, *powers, *term;
INDEXER size;
void OutDig(int dig)
{
static int printed = 0;
putchar(dig + '0');
printed++;
if ((printed%1000) == 0)
{
printed = 0;
printf("\n\n\n");
}
if ((printed%50) == 0)
printf("\n");
else if ((printed%10) == 0)
putchar(' ');
}
void PrintShort(SHORT num)
{
int x;
int digits[BASEDIGITS + 1];
for (x = 0; x < BASEDIGITS; x++)
{
digits[x] = num % 10;
num /= 10;
}
for (x = BASEDIGITS - 1; x >= 0; x--)
OutDig(digits[x]);
}
void Print(SHORT *num)
{
INDEXER x;
printf("\nPI = 3.\n");
for (x = 1; x < size; x++)
PrintShort(num[x]);
printf("\n");
}
void arctan(int multiplier, int denom, int sign)
{
INDEXER x;
long remain, temp, divisor, denom2;
short NotZero = 1;
INDEXER adv;
for (x = 0; x < size; x++)
powers[x] = 0;
divisor = 1;
denom2 = (LONG)denom;denom2 *= denom2;
adv = 0;
remain = (LONG)multiplier * denom;
while (NotZero)
{
for (x = adv; x < size; x++)
{
temp = (LONG)powers[x] + remain;
powers[x] = (SHORT)(temp / denom2);
remain = (temp - (denom2 * (LONG)powers[
// x])) * BASE;
}
remain = 0;
for (x = adv; x < size; x++)
{
temp = (LONG)powers[x] + remain;
term[x] = (SHORT)(temp / divisor);
remain = (temp - (divisor * (LONG)term[x
// ])) * BASE;
}
remain = 0;
if (sign > 0)
{
long carry, sum;
carry = 0;
for (x = size - 1; x >=0; x--)
{
sum = (LONG)pi[x] + (LONG)term[x] + carry;
carry = 0;
if (sum >= BASE)
{
carry = 1;
sum -= BASE;
}
pi[x] = (SHORT)sum;
}
}
else
{
long borrow, sum;
borrow = 0;
for (x = size - 1; x >= 0; x--)
{
sum = (LONG)pi[x] - (LONG)term[x] - borrow;
borrow = 0;
if (sum < 0)
{
borrow = 1;
sum += BASE;
}
pi[x] = (SHORT)sum;
}
}
sign = -sign;
divisor += 2;
NotZero = 0;
for (x = adv; x < size; x++)
{
if (powers[x])
{
NotZero = 1;
break;
}
}
if (NotZero)
{
while (powers[adv] == 0)
adv++;
}
/* We can skip ones that are already 0 */
}
}
int main(int argc, char *argv[])
{
INDEXER x;
time_t T1, T2;
if (argc != 2)
{
printf("I need to know how many digits to compute.\n");
exit(EXIT_FAILURE);
}
size = atol(argv[1]);
if (size <= 0L)
{
printf("Invalid argument.\n");
exit(EXIT_FAILURE);
}
size = ((size + BASEDIGITS - 1) / BASEDIGITS) + 1;
pi = malloc(sizeof(SHORT) * size);
powers = malloc(sizeof(SHORT) * size);
term = malloc(sizeof(SHORT) * size);
if ((pi == NULL) || (powers == NULL) || (term == NULL))
{
printf("Unable to allocate enough memory.\n");
exit(EXIT_FAILURE);
}
for (x = 0; x < size; x++)
pi[x] = 0;
T1 = time(NULL);
#if defined ARC3
arctan(8, 3, 1);
arctan(4, 7, 1);
#elif defined ARC5
arctan(16, 5, 1);
arctan(4, 70, -1);
arctan(4, 99, 1);
#elif defined ARC4
arctan(12, 4, 1);
arctan(4, 20, 1);
arctan(4, 1985, 1);
#elif defined ARC10
arctan(32, 10, 1);
arctan(4, 239, -1);
arctan(16, 515, -1);
#else
/* Machin formula */
arctan(16, 5, 1);
arctan(4, 239, -1);
#endif
T2 = time(NULL);
Print(pi);
#ifdef SHOWTIME
printf("\nCalculation time %0.0lf\n", difftime(T2, T1));
#endif
return EXIT_SUCCESS;
}