summaryrefslogtreecommitdiff
path: root/fpcsrc/tests/bench/pi.c
blob: 5d6235640f07f9ee33b1f21ec6b07e611edcf0e6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include <stdlib.h>
#include <stdio.h>

void ComputePi(int numdigits, char* pi)
{
    int alength = 10 * numdigits / 3;
    int* a = (int*) malloc(alength * sizeof(int));
    int piLength = 0;
    int nines = 0;
    int predigit = 0;
    int i, j;
    for(i = 0; i < alength; ++i)
        a[i] = 2;

    for (j = 0; j < numdigits; ++j)
    {
        int q = 0;
        int p = 2 * alength - 1;
        for (i = alength; --i >= 0; )
        {
            int x = 10*a[i] + q*(i+1);
            a[i] = x % p;
            q = x / p;
            p -= 2;
        }

        a[0] = q % 10;
        q /= 10;
        if (q == 9)
            ++nines;
        else if (q == 10)
        {
            int k;
            pi[piLength] = (char) (predigit + 1 + '0');
            for (k = 1; k <= nines; ++k)
                pi[piLength+k] = '0';
            piLength += nines + 1;
            predigit = 0;
            nines = 0;
        }
        else
        {
            int k;
            pi[piLength] = (char)(predigit + '0');
            predigit = q;
            for (k = 1; k <= nines; ++k)
                pi[piLength + k] = '9';
            piLength += nines + 1;
            nines = 0;
        }
    }
    pi[piLength] = (char)(predigit + '0');
    pi[piLength+1] = '\0';

    free(a);
}

int main(int argc, char** argv)
{
    int numdigits;
    char* pi;

    if (argc <= 1)
    {
        fprintf(stderr, "usage: pi #DIGITS [FILE]");
        return 1;
    }

    numdigits = atoi(argv[1]);
    pi = (char*) malloc(numdigits+1);
    ComputePi(numdigits, pi);

    if (argc > 2)
    {
        FILE* fp = fopen(argv[2], "w");
        if (fp == NULL)
        {
           fprintf(stderr, "Cannot open %s\n", argv[2]);
           return 2;
        }
        fputs(pi, fp);
        fputc('\n', fp);
        fclose(fp);
    }
    else
        puts(pi);

    free(pi);

    return 0;
}