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;

}