5
\$\begingroup\$

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;
}
\$\endgroup\$
4
\$\begingroup\$
  1. You asked,

    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.

\$\endgroup\$
  • \$\begingroup\$ I see, thank you for the helpful and fast answer! \$\endgroup\$ – physics Apr 15 '17 at 14:45
  • \$\begingroup\$ 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? \$\endgroup\$ – CAD97 Apr 15 '17 at 16:35
  • 1
    \$\begingroup\$ @CAD97: Parenthesize the macro expansion (see the comp.lang.c FAQ). \$\endgroup\$ – Gareth Rees Apr 15 '17 at 16:42
  • \$\begingroup\$ 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. \$\endgroup\$ – physics Apr 16 '17 at 20:30
  • \$\begingroup\$ 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? \$\endgroup\$ – physics Apr 16 '17 at 20:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.