# Approximating Pi with Polygons

I wrote a program that approximates Pi by using polygons. I used the formulars in the picture beyond. In my code they are called innerPoly ($c_{2n}$) and outerPoly ($C_{2n}$).

And since you can calculate the circumference of a 2n-polygon with knowing the circumference of a n-polygon you will get the circumferences $C_8$, $C_{16}$, $C_{32}$ etc., knowing $C_4$.

$$\begin{array}{l} c_{2n} =& 2 \sqrt{2n^2-n\sqrt{(2n)^2-c_n^2}} \qquad&\textrm{for the inner polygon, with}\ c_4=4\sqrt{2} \\ C_{2n} =& \frac{4 n C_n}{2n + \sqrt{(2n)^2 + C_n^2}} &\textrm{for the outer polygon, with}\ C_4=8 \end{array}$$

My thoughts are:

1. Would it make it anyhow better when I have a function called void PiApproximation() that writes my values to stdout already? I mean technically you can always put your full code into the main()-function, but when you have to use the same code-parts over and over again you should make a own function of it and call it, when u need it. So I guess in this case it will make no difference if I use an own function or calculate the circumferences and print it in the main-function.

2. What else can I improve?

pi_approx.c

#include <stdio.h>
#include <math.h>

#define INNER_FOUR 4*sqrt(2); //circumference c_4 of the inner tetragon(square)
#define OUTER_FOUR 8 //circumference C_4 of the outer tetragon

int power(int n, int p);

int main(void)
{
int n = 4;
double innerPoly = INNER_FOUR;
double outerPoly = OUTER_FOUR;

printf("PI-APPROXIMATION USING POLYGONS\n");
printf("===============================\n\n");
printf("    n    I      c_n/2      I       C_n/2     I\n");
printf("---------I-----------------I-----------------I\n");

for (int i=3; n<=8192; n=power(i,2), i++)
{
printf("   %4d  I   %1.8lf    I    %1.8lf   I\n", n, innerPoly / 2, outerPoly / 2);

innerPoly = 2 * sqrt(2 * n*n - n*sqrt(4 * n*n - innerPoly*innerPoly)); //formular c_2n
outerPoly = (4 * n * outerPoly) / (2 * n + sqrt(4 * n*n + outerPoly*outerPoly)); //formular C_2n
}

return 0;
}

int power(int n, int p)
{

int pBuffer = 1;

for (int i=1; i <= n; i++)
{
pBuffer *= p;
}

return pBuffer;
}


Would it make it better if I had a function called PiApproximation?

The code in main does just one thing so it would not be an improvement to introduce a new function like this — the question would then be, what's the point of main?

2. There is a dependency between the initial value of n and the initial values of innerPoly and outerPoly. It would make sense to put all the initialization code together.

3. Because n can never be negative it could be unsigned.

4. The loop:

for (int i=3; n<=8192; n=power(i,2), i++)


is quite hard to follow because the loop variable is i but the termination condition is on a different variable n. Because the loop variable i is not used, it would be easier to follow the logic if you wrote:

for (; n <= 8192; n *= 2)


(This also avoids the need for the power function.)

5. The l modifier has no effect on the printf format specifier %f, and so should be omitted.

• I see, thank you for the helpful and fast answer! Apr 15, 2017 at 14:45
• I don't know the C preprocessor very well, but those #define scare me: iirc doing something like double sum = INNER_FOUR + OUTER_FOUR or anything with code after the macro could break in interesting ways. What's the correct way to deal with that? Apr 15, 2017 at 16:35
• @CAD97: Parenthesize the macro expansion (see the comp.lang.c FAQ). Apr 15, 2017 at 16:42
• In my case I only use this constant circumferences of a 4-polygon as a start-value of my calculation, i.e. I do not really use them in a formular, where I can immediately see what this constant would mean in a determined context. Apr 16, 2017 at 20:30
• So in my case I could directly write on the variables innerPoly, outerPoly my start-values at the begin of the main()-program. What do you think about that? Apr 16, 2017 at 20:37